This commit is contained in:
newtbot 2024-01-26 04:07:13 +08:00
commit d3b031a50d
43 changed files with 10677 additions and 2862 deletions

42
Sean/modules/otpUtils.js Normal file
View File

@ -0,0 +1,42 @@
const nodemailer = require("nodemailer");
const otpGenerator = require('otp-generator');
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
const generateOTP = () => {
const otp = otpGenerator.generate(6, { upperCase: false, specialChars: false });
const expirationTime = Date.now() + 5 * 60 * 1000; // 5 minutes expiration
return { otp, expirationTime };
};
const sendOTPByEmail = async (email, otp) => {
try {
const transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
port: 587, // use the appropriate port for your SMTP server
secure: false, // true for 465, false for other ports
auth: {
user: process.env.euser, // replace with your email
pass: process.env.epass // replace with your email password
}
});
const mailOptions = {
from: process.env.euser,
to: email,
subject: 'Login OTP',
text: `Your OTP for login is: ${otp}`
};
await transporter.sendMail(mailOptions);
console.log('OTP sent successfully to', email);
} catch (error) {
console.error('Error sending OTP:', error);
throw error;
}
};
module.exports = {
generateOTP,
sendOTPByEmail
};

View File

@ -0,0 +1,9 @@
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each IP to 5 requests per windowMs
message: 'Too many login attempts from this IP, please try again later.',
});
module.exports = limiter;

View File

@ -0,0 +1,77 @@
const { body } = require('express-validator');
const locationValidation = [
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('description').trim().escape(),
];
const locationValidationUpdate = [
body('id').trim().escape(),
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('description').trim().escape(),
];
const locationdeleteValidation = [
body('id').trim().escape()
];
const sensorValidation = [
body('sensorname').trim().isLength({ min: 1 }).withMessage('Sensor Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('macAddress').custom(value => {
const macAddressRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
if (!macAddressRegex.test(value)) {
throw new Error('Invalid MAC address format');
}
return true;
}).withMessage('Invalid MAC address format').escape(),
body('description').trim().escape(),
body('location').trim().escape()
];
const sensorupdateValidation = [
body('id').trim().escape(),
body('sensorname').trim().isLength({ min: 1 }).withMessage('Sensor Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('macAddress').custom(value => {
const macAddressRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
if (!macAddressRegex.test(value)) {
throw new Error('Invalid MAC address format');
}
return true;
}).withMessage('Invalid MAC address format').escape(),
body('description').trim().escape(),
body('location').trim().escape()
];
const sensordeleteValidation = [
body('id').trim().escape()
];
const loginValidation = [
body('username').escape().trim().isLength({ min: 1 }).withMessage('Username must not be empty'),
body('password').escape().trim().isLength({ min: 1 }).withMessage('Password must not be empty'),
];
const otpValidation = [
body('otp').escape().trim().isLength({ min: 1 }).withMessage('OTP must not be empty'),
];
const createValidation = [
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('username').trim().isLength({ min: 1 }).withMessage('Username must not be empty').escape(),
body('email').isEmail().withMessage('Invalid email address').normalizeEmail(),
body('password').custom((value) => {
if (!isStrongPassword(value)) { throw new Error('Password does not meet complexity requirements'); } return true;
}),
body('jobTitle').trim().isLength({ min: 1 }).withMessage('Job title must not be empty').escape(),
];
module.exports = {
locationValidation,locationValidationUpdate,locationdeleteValidation
,sensorValidation,sensorupdateValidation,sensordeleteValidation,loginValidation,otpValidation
,createValidation
};

View File

@ -1,26 +1,25 @@
const express = require("express");
const session = require("express-session");
const rateLimit = require('express-rate-limit');
const cookieParser = require('cookie-parser');
const bodyParser = require("body-parser");
const bcrypt = require("bcrypt");
const crypto = require("crypto");
const nodemailer = require("nodemailer");
const otpGenerator = require('otp-generator');
const { body, validationResult } = require('express-validator');
const validator = require('validator');
const axios = require('axios');
const {validationResult } = require('express-validator');
const {locationValidation, locationValidationUpdate, locationdeleteValidation
,sensorValidation, sensorupdateValidation, sensordeleteValidation, loginValidation
,otpValidation, createValidation} = require('./modules/validationMiddleware');
const rateLimit = require('./modules/rateLimitMiddleware');
const { generateOTP, sendOTPByEmail } = require('./modules/otpUtils');
const { format } = require('date-fns');
const helmet = require('helmet');
const { Sequelize } = require('sequelize');
const { transporter } = require("./modules/nodeMailer");
const { sequelize, User } = require("./modules/mysql");
const userLogs= require('./models/userLogs')(sequelize); // Adjust the path based on your project structure
const userLogs= require('./models/userLogs')(sequelize);
const app = express();
const nonce = crypto.randomBytes(16).toString('base64');
console.log('Nonce:', nonce);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
@ -30,17 +29,6 @@ require("dotenv").config();
app.use(bodyParser.urlencoded({ extended: true }));
app.set("view engine", "ejs");
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'",`'nonce-${nonce}'`],
scriptSrc: ["'self'",`'nonce-${nonce}'`,"'strict-dynamic'", 'cdn.jsdelivr.net', 'fonts.googleapis.com', 'stackpath.bootstrapcdn.com', 'code.jquery.com', 'cdnjs.cloudflare.com'],
styleSrc: ["'self'",`'nonce-${nonce}'`, 'cdn.jsdelivr.net', 'fonts.googleapis.com'],
imgSrc: ["'self'"],
fontSrc: ["'self'", 'fonts.gstatic.com'],
},
})
);
app.use(session({
secret: process.env.key,
@ -56,79 +44,33 @@ function isAuthenticated(req, res, next) {
if (req.session && req.session.authenticated) {
return next();
} else {
res.redirect("/login");
res.redirect("/index");
}
}
const generateOTP = () => {
const otp = otpGenerator.generate(6, { upperCase: false, specialChars: false });
const expirationTime = Date.now() + 5 * 60 * 1000; // 5 minutes expiration
return { otp, expirationTime };
};
const sendOTPByEmail = async (email, otp) => {
try {
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.euser, // replace with your email
pass: process.env.epass // replace with your email password
}
});
const mailOptions = {
from: process.env.euser,
to: email,
subject: 'Login OTP',
text: `Your OTP for login is: ${otp}`
};
await transporter.sendMail(mailOptions);
console.log('OTP sent successfully to', email);
} catch (error) {
console.error('Error sending OTP:', error);
throw error;
}
};
app.get('/index', (req, res) => {
res.render('index');
});
app.get("/login", (req, res) => {
res.render("login", { error: null });
});
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each IP to 3 requests per windowMs
message: 'Too many login attempts from this IP, please try again later.',
});
app.use('/login', limiter);
app.use('/login', rateLimit);
app.post('/login', [
body('username').escape().trim().isLength({ min: 1 }).withMessage('Username must not be empty'),
body('password').escape().trim().isLength({ min: 1 }).withMessage('Password must not be empty'),
],
async (req, res) => {
try {
const errors = validationResult(req);
app.post('/login', loginValidation, async (req, res) => {
try {const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.render('login', { error: 'Invalid input. Please check your credentials.', csrfToken: req.session.csrfToken });
}
let { username, password } = req.body;
username = username.trim();
const user = await User.findOne({ where: { username } });
if (user) {
const isLoginSuccessful = await bcrypt.compare(password, user.password);
if (isLoginSuccessful) {
await userLogs.create({ username, success: true, activity: "Credentials entered correctly" });
const { otp, expirationTime } = generateOTP();
req.session.otp = otp;
@ -174,17 +116,12 @@ async (req, res) => {
// OTP verification route
app.post("/verify-otp", [
body('otp').escape().trim().isLength({ min: 1 }).withMessage('OTP must not be empty'),
],
async (req, res) => {
app.post("/verify-otp", otpValidation ,async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.render('otp', { error: 'Invalid OTP. Please try again.'});
}
const enteredOTP = req.body.otp;
if (!req.session) {
@ -222,17 +159,10 @@ app.post("/verify-otp", [
req.session.authenticated = true;
req.session.username = req.body.username;
req.session.sessionToken = sessionToken;
csrfTokenSession = crypto.randomBytes(32).toString('hex');
// Log anti-CSRF token
console.log(`Generated Anti-CSRF Token: ${csrfTokenSession}`);
res.cookie('sessionToken', sessionToken, { secure: true, httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000) }); // Expires in 1 day
console.log(`Generated Session Token: ${sessionToken}`);
res.redirect("/home");
} else {
if (req.body.username) {
@ -275,17 +205,11 @@ app.post("/verify-otp", [
}
});
app.get("/home", isAuthenticated, (req, res) => {
// Render the home page with sensor data
res.render("home", {
username: req.session.username,
});
app.get("/home", isAuthenticated, async (req, res) => {
res.render("home", { username: req.session.username});
});
app.get("/inusers", isAuthenticated, async (req, res) => {
try {
// Fetch all user data from the database using Sequelize
@ -294,9 +218,8 @@ app.post("/verify-otp", [
});
const currentUsername = req.session.username;
// Render the inusers page with JSON data
res.render("inusers", { nonce: nonce, allUsers, csrfToken: csrfTokenSession, currentUsername });
res.render("inusers", {allUsers, csrfToken: csrfTokenSession, currentUsername });
} catch (error) {
console.error("Error fetching all users:", error);
res.status(500).send("Internal Server Error");
@ -332,20 +255,8 @@ function isStrongPassword(password) {
return true;
}
app.post(
'/createUser',
[
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('username').trim().isLength({ min: 1 }).withMessage('Username must not be empty').escape(),
body('email').isEmail().withMessage('Invalid email address').normalizeEmail(),
body('password').custom((value) => {
if (!isStrongPassword(value)) { throw new Error('Password does not meet complexity requirements'); } return true;
}),
body('jobTitle').trim().isLength({ min: 1 }).withMessage('Job title must not be empty').escape(),
],
async (req, res) => {
'/createUser', createValidation, async (req, res) => {
try {
const errors = validationResult(req);
@ -477,24 +388,13 @@ app.post("/forgot-password", async (req, res) => {
const error = "Username or email not found.";
return res.render("forgot-password", { error, success: null });
}
// Generate reset token and update the user
const reset_token = crypto.randomBytes(20).toString("hex");
const reset_token_expiry = new Date(Date.now() + 3600000); // Token expires in 1 hour
// Update the user with the reset token and expiry
await User.update(
{
reset_token,
reset_token_expiry,
},
{
where: {
id: user.id, // Replace 'id' with the actual primary key field of your User model
},
}
await User.update({reset_token,reset_token_expiry,},
{where: {id: user.id},}
);
// Send email with reset link
const resetLink = `http://localhost:3000/reset-password/${reset_token}`;
const mailOptions = {
@ -502,12 +402,9 @@ app.post("/forgot-password", async (req, res) => {
subject: "Password Reset",
text: `Click on the following link to reset your password: ${resetLink}`,
};
await transporter.sendMail(mailOptions);
const success = "Password reset email sent successfully. Check your inbox.";
res.render("forgot-password", { error: null, success });
// Log the successful sending of the reset link in the database
await userLogs.create({
username: user.username,
@ -523,29 +420,22 @@ app.post("/forgot-password", async (req, res) => {
console.error("Error during password reset:", error);
const errorMessage = "An error occurred during the password reset process.";
res.render("forgot-password", { error: errorMessage, success: null });
}
});
}});
app.post("/reset-password/:token", async (req, res) => {
try {
const { token } = req.params;
const { password, confirmPassword } = req.body;
// Sanitize the inputs
const sanitizedToken = validator.escape(token);
const sanitizedPassword = validator.escape(password);
const sanitizedConfirmPassword = validator.escape(confirmPassword);
// Find user with matching reset token and not expired
const user = await User.findOne({
where: {
reset_token: sanitizedToken,
reset_token_expiry: { [Sequelize.Op.gt]: new Date() },
where: {reset_token: sanitizedToken,
reset_token_expiry: { [Sequelize.Op.gt]: new Date() },
},
});
if (!user) {
// Pass the error to the template when rendering the reset-password page
return res.render("reset-password", {
@ -553,7 +443,6 @@ app.post("/forgot-password", async (req, res) => {
resetError: "Invalid or expired reset token",
});
}
// Check if passwords match
if (sanitizedPassword !== sanitizedConfirmPassword) {
// Pass the error to the template when rendering the reset-password page
@ -562,31 +451,24 @@ app.post("/forgot-password", async (req, res) => {
resetError: "Passwords do not match",
});
}
// Check if the new password meets complexity requirements
if (!isStrongPassword(sanitizedPassword)) {
// Pass the error to the template when rendering the reset-password page
return res.render("reset-password", {
token,
resetError:
token, resetError:
"Password does not meet complexity requirements. It must be at least 10 characters long and include at least one uppercase letter, one lowercase letter, one digit, and one symbol.",
});
}
// Hash the new password
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(sanitizedPassword, saltRounds);
// Update user's password and clear reset token
const updateQuery = {
password: hashedPassword,
reset_token: null,
reset_token_expiry: null,
};
const whereCondition = {
reset_token: sanitizedToken,
};
const whereCondition = {reset_token: sanitizedToken,};
await User.update(updateQuery, {
where: whereCondition,
});
@ -633,10 +515,8 @@ app.post("/reset-password", async (req, res) => {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const sessionTokencookie = req.cookies['sessionToken'];
// Verify sessionToken with the one stored in the database
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
@ -644,12 +524,10 @@ app.post("/reset-password", async (req, res) => {
const sanitizedUsername = validator.escape(username);
const sanitizedPassword = validator.escape(password);
const sanitizedConfirmPassword = validator.escape(confirmPassword);
// Check if passwords match
if (sanitizedPassword !== sanitizedConfirmPassword) {
return res.status(400).json({ error: "Passwords do not match" });
}
// Check if the new password meets complexity requirements
if (!isStrongPassword(sanitizedPassword)) {
return res.status(400).json({
@ -657,31 +535,25 @@ app.post("/reset-password", async (req, res) => {
"Password does not meet complexity requirements. It must be at least 10 characters long and include at least one uppercase letter, one lowercase letter, one digit, and one symbol.",
});
}
try {
// Find the user in the database
const user = await User.findOne({ where: { username: sanitizedUsername } });
if (!user) {
return res.status(404).json({ error: "User does not exist" });
}
// Generate a random salt and hash the new password
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(sanitizedPassword, saltRounds);
// Update user's password
await User.update(
{ password: hashedPassword },
{ where: { username: sanitizedUsername } }
);
// Log password reset activity
await userLogs.create({
username: creatorUsername,
activity: `Password has been reset for ${sanitizedUsername}`,
});
// Password update successful
return res.status(200).json({ success: "Password updated successfully" });
} catch (error) {
@ -693,10 +565,8 @@ app.post("/reset-password", async (req, res) => {
app.get('/searchUser', async (req, res) => {
const { username } = req.query;
// Sanitize the input
const sanitizedUsername = validator.escape(username);
try {
// Find the user in the database
const user = await User.findOne({ where: { username: sanitizedUsername } });
@ -704,11 +574,7 @@ app.get('/searchUser', async (req, res) => {
if (!user) {
// No user found with the given username
res.status(404).json({ success: false, error: 'User not found' });
} else {
// User found, return user data
res.json(user);
}
} else {res.json(user)}
} catch (error) {
console.error('Sequelize query error:', error);
res.status(500).json({ success: false, error: 'Internal Server Error' });
@ -719,7 +585,6 @@ app.get('/api/users', async (req, res) => {
try {
// Find all users in the database
const users = await User.findAll();
// Return the users in the response
res.json(users);
} catch (error) {
@ -787,9 +652,6 @@ app.delete('/api/deleteUser/:username', async (req, res) => {
res.status(500).json({ success: false, error: 'Internal Server Error', details: error.message });
}
});
app.get('/api/getLogs', async (req, res) => {
try {
@ -814,6 +676,197 @@ app.get('/api/getLogs', async (req, res) => {
}
});
app.get("/locations", isAuthenticated, async (req, res) => {
try {
// Fetch data using Axios
const response = await axios.get(process.env.API_ALLLOCATION);
const locationsData = response.data;
// Render the "locations" page with the fetched JSON data
res.render("locations", { locationsData, csrfToken: csrfTokenSession});
} catch (error) {
console.error("Error fetching locations:", error);
res.status(500).send("Internal Server Error");
}
});
app.post('/location/new', locationValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { name, added_by, description } = req.body;
const preparedData = {name, added_by, description};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_NEWLOCATION, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new location submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.post('/location/update', locationValidationUpdate, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { id, name, added_by, description } = req.body;
const preparedData = {id, name, added_by, description};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_UPDATELOCATION, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new location submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.post('location/delete',locationdeleteValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const {id} = req.body;
const preparedData = {id};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_DELLOCATION, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new sensor submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.get("/sensors", isAuthenticated, async (req, res) => {
try {
// Render the inusers page with JSON data
const response = await axios.get(process.env.API_ALLLOCATION);
const locationsData = response.data;
const response2 = await axios.get(process.env.API_ALLSENSOR);
const sensorData = response2.data;
res.render("sensors",{locationsData, sensorData, csrfToken: csrfTokenSession});
} catch (error) {
console.error("Error:", error);
res.status(500).send("Internal Server Error");
}
});
app.post('sensor/new',sensorValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { sensorname, added_by, macAddress, description, location} = req.body;
const preparedData = {sensorname, added_by, macAddress, description, location};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_NEWSENSOR, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new sensor submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.post('sensor/update',sensorupdateValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { id, sensorname, added_by, macAddress, description, location} = req.body;
const preparedData = {id, sensorname, added_by, macAddress, description, location};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_NEWSENSOR, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new sensor submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.post('sensor/delete',sensordeleteValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const {id} = req.body;
const preparedData = {id};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_DELSENSOR, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new sensor submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.use(express.static("views"));
app.listen(PORT, () => {

4074
Sean/views/assets/animatecss/animate.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
/*!
* Bootstrap Reboot v5.0.1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,265 @@
.navbar-dropdown {
left: 0;
padding: 0;
position: absolute;
right: 0;
top: 0;
transition: all 0.45s ease;
z-index: 1030;
background: #282828; }
.navbar-dropdown .navbar-logo {
margin-right: 0.8rem;
transition: margin 0.3s ease-in-out;
vertical-align: middle; }
.navbar-dropdown .navbar-logo img {
height: 3.125rem;
transition: all 0.3s ease-in-out; }
.navbar-dropdown .navbar-logo.mbr-iconfont {
font-size: 3.125rem;
line-height: 3.125rem; }
.navbar-dropdown .navbar-caption {
font-weight: 700;
white-space: normal;
vertical-align: -4px;
line-height: 3.125rem !important; }
.navbar-dropdown .navbar-caption, .navbar-dropdown .navbar-caption:hover {
color: inherit;
text-decoration: none; }
.navbar-dropdown .mbr-iconfont + .navbar-caption {
vertical-align: -1px; }
.navbar-dropdown.navbar-fixed-top {
position: fixed; }
.navbar-dropdown .navbar-brand span {
vertical-align: -4px; }
.navbar-dropdown.bg-color.transparent {
background: none; }
.navbar-dropdown.navbar-short .navbar-brand {
padding: 0.625rem 0; }
.navbar-dropdown.navbar-short .navbar-brand span {
vertical-align: -1px; }
.navbar-dropdown.navbar-short .navbar-caption {
line-height: 2.375rem !important;
vertical-align: -2px; }
.navbar-dropdown.navbar-short .navbar-logo {
margin-right: 0.5rem; }
.navbar-dropdown.navbar-short .navbar-logo img {
height: 2.375rem; }
.navbar-dropdown.navbar-short .navbar-logo.mbr-iconfont {
font-size: 2.375rem;
line-height: 2.375rem; }
.navbar-dropdown.navbar-short .mbr-table-cell {
height: 3.625rem; }
.navbar-dropdown .navbar-close {
left: 0.6875rem;
position: fixed;
top: 0.75rem;
z-index: 1000; }
.navbar-dropdown .hamburger-icon {
content: "";
display: inline-block;
vertical-align: middle;
width: 16px;
-webkit-box-shadow: 0 -6px 0 1px #282828,0 0 0 1px #282828,0 6px 0 1px #282828;
-moz-box-shadow: 0 -6px 0 1px #282828,0 0 0 1px #282828,0 6px 0 1px #282828;
box-shadow: 0 -6px 0 1px #282828,0 0 0 1px #282828,0 6px 0 1px #282828; }
.dropdown-menu .dropdown-toggle[data-toggle="dropdown-submenu"]::after {
border-bottom: 0.35em solid transparent;
border-left: 0.35em solid;
border-right: 0;
border-top: 0.35em solid transparent;
margin-left: 0.3rem; }
.dropdown-menu .dropdown-item:focus {
outline: 0; }
.nav-dropdown {
font-size: 0.75rem;
font-weight: 500;
height: auto !important; }
.nav-dropdown .nav-btn {
padding-left: 1rem; }
.nav-dropdown .link {
margin: .667em 1.667em;
font-weight: 500;
padding: 0;
transition: color .2s ease-in-out; }
.nav-dropdown .link.dropdown-toggle {
margin-right: 2.583em; }
.nav-dropdown .link.dropdown-toggle::after {
margin-left: .25rem;
border-top: 0.35em solid;
border-right: 0.35em solid transparent;
border-left: 0.35em solid transparent;
border-bottom: 0; }
.nav-dropdown .link.dropdown-toggle[aria-expanded="true"] {
margin: 0;
padding: 0.667em 3.263em 0.667em 1.667em; }
.nav-dropdown .link::after,
.nav-dropdown .dropdown-item::after {
color: inherit; }
.nav-dropdown .btn {
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0;
margin-bottom: 0;
padding-left: 1.25rem;
padding-right: 1.25rem; }
.nav-dropdown .dropdown-menu {
border-radius: 0;
border: 0;
left: 0;
margin: 0;
padding-bottom: 1.25rem;
padding-top: 1.25rem;
position: relative; }
.nav-dropdown .dropdown-submenu {
margin-left: 0.125rem;
top: 0; }
.nav-dropdown .dropdown-item {
font-weight: 500;
line-height: 2;
padding: 0.3846em 4.615em 0.3846em 1.5385em;
position: relative;
transition: color .2s ease-in-out, background-color .2s ease-in-out; }
.nav-dropdown .dropdown-item::after {
margin-top: -0.3077em;
position: absolute;
right: 1.1538em;
top: 50%; }
.nav-dropdown .dropdown-item:focus, .nav-dropdown .dropdown-item:hover {
background: none; }
@media (max-width: 767px) {
.nav-dropdown.navbar-toggleable-sm {
bottom: 0;
display: none;
left: 0;
overflow-x: hidden;
position: fixed;
top: 0;
transform: translateX(-100%);
-ms-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
width: 18.75rem;
z-index: 999; } }
.nav-dropdown.navbar-toggleable-xl {
bottom: 0;
display: none;
left: 0;
overflow-x: hidden;
position: fixed;
top: 0;
transform: translateX(-100%);
-ms-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
width: 18.75rem;
z-index: 999; }
.nav-dropdown-sm {
display: block !important;
overflow-x: hidden;
overflow: auto;
padding-top: 3.875rem; }
.nav-dropdown-sm::after {
content: "";
display: block;
height: 3rem;
width: 100%; }
.nav-dropdown-sm.collapse.in ~ .navbar-close {
display: block !important; }
.nav-dropdown-sm.collapsing, .nav-dropdown-sm.collapse.in {
transform: translateX(0);
-ms-transform: translateX(0);
-webkit-transform: translateX(0);
transition: all 0.25s ease-out;
-webkit-transition: all 0.25s ease-out;
background: #282828; }
.nav-dropdown-sm.collapsing[aria-expanded="false"] {
transform: translateX(-100%);
-ms-transform: translateX(-100%);
-webkit-transform: translateX(-100%); }
.nav-dropdown-sm .nav-item {
display: block;
margin-left: 0 !important;
padding-left: 0; }
.nav-dropdown-sm .link,
.nav-dropdown-sm .dropdown-item {
border-top: 1px dotted rgba(255, 255, 255, 0.1);
font-size: 0.8125rem;
line-height: 1.6;
margin: 0 !important;
padding: 0.875rem 2.4rem 0.875rem 1.5625rem !important;
position: relative;
white-space: normal; }
.nav-dropdown-sm .link:focus, .nav-dropdown-sm .link:hover,
.nav-dropdown-sm .dropdown-item:focus,
.nav-dropdown-sm .dropdown-item:hover {
background: rgba(0, 0, 0, 0.2) !important;
color: #c0a375; }
.nav-dropdown-sm .nav-btn {
position: relative;
padding: 1.5625rem 1.5625rem 0 1.5625rem; }
.nav-dropdown-sm .nav-btn::before {
border-top: 1px dotted rgba(255, 255, 255, 0.1);
content: "";
left: 0;
position: absolute;
top: 0;
width: 100%; }
.nav-dropdown-sm .nav-btn + .nav-btn {
padding-top: 0.625rem; }
.nav-dropdown-sm .nav-btn + .nav-btn::before {
display: none; }
.nav-dropdown-sm .btn {
padding: 0.625rem 0; }
.nav-dropdown-sm .dropdown-toggle[data-toggle="dropdown-submenu"]::after {
margin-left: .25rem;
border-top: 0.35em solid;
border-right: 0.35em solid transparent;
border-left: 0.35em solid transparent;
border-bottom: 0; }
.nav-dropdown-sm .dropdown-toggle[data-toggle="dropdown-submenu"][aria-expanded="true"]::after {
border-top: 0;
border-right: 0.35em solid transparent;
border-left: 0.35em solid transparent;
border-bottom: 0.35em solid; }
.nav-dropdown-sm .dropdown-menu {
margin: 0;
padding: 0;
position: relative;
top: 0;
left: 0;
width: 100%;
border: 0;
float: none;
border-radius: 0;
background: none; }
.nav-dropdown-sm .dropdown-submenu {
left: 100%;
margin-left: 0.125rem;
margin-top: -1.25rem;
top: 0; }
.navbar-toggleable-sm .nav-dropdown .dropdown-menu {
position: absolute; }
.navbar-toggleable-sm .nav-dropdown .dropdown-submenu {
left: 100%;
margin-left: 0.125rem;
margin-top: -1.25rem;
top: 0; }
.navbar-toggleable-sm.opened .nav-dropdown .dropdown-menu {
position: relative; }
.navbar-toggleable-sm.opened .nav-dropdown .dropdown-submenu {
left: 0;
margin-left: 00rem;
margin-top: 0rem;
top: 0; }
.is-builder .nav-dropdown.collapsing {
transition: none !important; }

View File

@ -0,0 +1,8 @@
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(b,c,a){b!=Array.prototype&&b!=Object.prototype&&(b[c]=a.value)};$jscomp.getGlobal=function(b){return"undefined"!=typeof window&&window===b?b:"undefined"!=typeof global&&null!=global?global:b};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(b,c,a,d){if(c){a=$jscomp.global;b=b.split(".");for(d=0;d<b.length-1;d++){var f=b[d];f in a||(a[f]={});a=a[f]}b=b[b.length-1];d=a[b];c=c(d);c!=d&&null!=c&&$jscomp.defineProperty(a,b,{configurable:!0,writable:!0,value:c})}};
$jscomp.polyfill("Array.from",function(b){return b?b:function(b,a,d){a=null!=a?a:function(a){return a};var f=[],e="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];if("function"==typeof e){b=e.call(b);for(var c=0;!(e=b.next()).done;)f.push(a.call(d,e.value,c++))}else for(e=b.length,c=0;c<e;c++)f.push(a.call(d,b[c],c));return f}},"es6","es3");
(function(){function b(a){"resize"===a.type&&(document.body.classList.remove("navbar-dropdown-open"),document.querySelector(".navbar-dropdown").querySelector(".navbar-collapse").classList.remove("show"),document.querySelector(".navbar-dropdown").classList.remove("opened"),Array.from(document.querySelector(".navbar-dropdown").querySelectorAll('.navbar-toggler[aria-expanded="true"]')).forEach(function(a){var b=a.querySelector(a.getAttribute("data-target"));b&&(b.classList.remove("in"),b.setAttribute("aria-expanded",
"false"),a.setAttribute("aria-expanded","false"))}));var b=document.documentElement.scrollTop;Array.from(document.querySelectorAll(".navbar-dropdown")).forEach(function(a){a.matches(".navbar-fixed-top")&&(a.matches(".transparent")&&!a.classList.contains("opened")&&(0<b?a.classList.remove("bg-color"):a.classList.add("bg-color")),0<b?a.classList.add("navbar-short"):a.classList.remove("navbar-short"))})}var c;["scroll","resize"].forEach(function(a){document.addEventListener(a,function(a){clearTimeout(c);
c=setTimeout(function(){b(a)},10)})});["show.bs.collapse","hide.bs.collapse"].forEach(function(a){document.addEventListener(a,function(b){if(b=b.target.closest(".navbar-dropdown"))"show.bs.collapse"===a?(document.body.classList.add("navbar-dropdown-open"),b.classList.add("opened")):(document.body.classList.remove("navbar-dropdown-open"),b.classList.remove("opened"),window.dispatchEvent(new Event("scroll.bs.navbar-dropdown.data-api")),b.dispatchEvent(new Event("collapse.bs.navbar-dropdown")))})});
document.querySelector("html").classList.contains("is-builder")||document.addEventListener("click",function(a){a=a.target;if(!a.classList.contains("nav-link")&&!a.parentNode.classList.contains("nav-link")){var b=document.querySelector("#navbarSupportedContent"),c=document.querySelector(".navbar-dropdown"),e=b.classList.contains("show"),g=a.closest(".nav-item a:not(.dropdown-toggle)");c=c.classList.contains("collapsed");(window.matchMedia("(max-width: 991px)").matches||c)&&(e&&!a.closest(".navbar-collapse")||
g)&&new bootstrap.Collapse(b)}});document.addEventListener("collapse.bs.nav-dropdown",function(a){(a=a.relatedTarget.closest(".navbar-dropdown"))&&(a=a.querySelector('.navbar-toggler[aria-expanded="true"]'))&&a.dispatchEvent(new Event("click"))});document.querySelectorAll(".nav-link.dropdown-toggle").forEach(function(a){a.addEventListener("click",function(a){a.preventDefault();a.target.parentNode.classList.toggle("open")})})})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

View File

@ -0,0 +1 @@
{"+GQdJ/FkTHHhtIo5SJpbjw==":"logo-96x43.png","sNnwj6dliedFMQPUjtqZKA==":"logo-1-96x43.png","FshdhnAXWIc3Sivjcd0w7w==":"logo-2-96x43.png","o6j4Z3r46yoaBgNIONzS4A==":"logo-3-96x43.png","gakqOFXqLTkOgBY/bPwdWw==":"logo-4-96x43.png","erPZweO4Ec5GB5uI98xycQ==":"ecosostenibilita-1000x500.jpeg","XL8v257g6FjjbOw+0BL9KA==":"air-pollution-1679x944.jpg","BOA7b8UnSidGomEe8QOuuQ==":"the%20expansion%20of%20cloud%20applications%20has%20added%20to...-766x476.png"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
.jarallax {
position: relative;
z-index: 0;
}
.jarallax > .jarallax-img {
position: absolute;
object-fit: cover;
/* support for plugin https://github.com/bfred-it/object-fit-images */
font-family: 'object-fit: cover;';
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}

View File

@ -0,0 +1,45 @@
/*
Name : Just Another Parallax [Jarallax]
Version : 1.12.7
Author : nK <https://nkdev.info>
GitHub : https://github.com/nk-o/jarallax
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,d,b){a!=Array.prototype&&a!=Object.prototype&&(a[d]=b.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(a,d,b,e){if(d){b=$jscomp.global;a=a.split(".");for(e=0;e<a.length-1;e++){var g=a[e];g in b||(b[g]={});b=b[g]}a=a[a.length-1];e=b[a];d=d(e);d!=e&&null!=d&&$jscomp.defineProperty(b,a,{configurable:!0,writable:!0,value:d})}};
$jscomp.polyfill("Array.from",function(a){return a?a:function(a,b,e){b=null!=b?b:function(a){return a};var d=[],l="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];if("function"==typeof l){a=l.call(a);for(var q=0;!(l=a.next()).done;)d.push(b.call(e,l.value,q++))}else for(l=a.length,q=0;q<l;q++)d.push(b.call(e,a[q],q));return d}},"es6","es3");$jscomp.arrayIteratorImpl=function(a){var d=0;return function(){return d<a.length?{done:!1,value:a[d++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};
$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.SymbolClass=function(a,d){this.$jscomp$symbol$id_=a;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:d})};$jscomp.SymbolClass.prototype.toString=function(){return this.$jscomp$symbol$id_};
$jscomp.Symbol=function(){function a(b){if(this instanceof a)throw new TypeError("Symbol is not a constructor");return new $jscomp.SymbolClass($jscomp.SYMBOL_PREFIX+(b||"")+"_"+d++,b)}var d=0;return a}();
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("Symbol.iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}});$jscomp.initSymbolIterator=function(){}};
$jscomp.initSymbolAsyncIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.asyncIterator;a||(a=$jscomp.global.Symbol.asyncIterator=$jscomp.global.Symbol("Symbol.asyncIterator"));$jscomp.initSymbolAsyncIterator=function(){}};$jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[$jscomp.global.Symbol.iterator]=function(){return this};return a};
$jscomp.iteratorFromArray=function(a,d){$jscomp.initSymbolIterator();a instanceof String&&(a+="");var b=0,e={next:function(){if(b<a.length){var g=b++;return{value:d(g,a[g]),done:!1}}e.next=function(){return{done:!0,value:void 0}};return e.next()}};e[Symbol.iterator]=function(){return e};return e};$jscomp.polyfill("Array.prototype.keys",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a){return a})}},"es6","es3");
(function(a){function d(e){if(b[e])return b[e].exports;var g=b[e]={i:e,l:!1,exports:{}};a[e].call(g.exports,g,g.exports,d);g.l=!0;return g.exports}var b={};d.m=a;d.c=b;d.d=function(a,b,l){d.o(a,b)||Object.defineProperty(a,b,{enumerable:!0,get:l})};d.r=function(a){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"});Object.defineProperty(a,"__esModule",{value:!0})};d.t=function(a,b){b&1&&(a=d(a));if(b&8||b&4&&"object"===typeof a&&a&&a.__esModule)return a;
var g=Object.create(null);d.r(g);Object.defineProperty(g,"default",{enumerable:!0,value:a});if(b&2&&"string"!=typeof a)for(var e in a)d.d(g,e,function(b){return a[b]}.bind(null,e));return g};d.n=function(a){var b=a&&a.__esModule?function(){return a["default"]}:function(){return a};d.d(b,"a",b);return b};d.o=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};d.p="";return d(d.s=10)})([,,function(a,d){a.exports=function(a){"complete"===document.readyState||"interactive"===document.readyState?
a.call():document.attachEvent?document.attachEvent("onreadystatechange",function(){"interactive"===document.readyState&&a.call()}):document.addEventListener&&document.addEventListener("DOMContentLoaded",a)}},function(a,d,b){d=b(4);a.exports="undefined"!==typeof window?window:"undefined"!==typeof d?d:"undefined"!==typeof self?self:{}},function(a,d){function b(a){"@babel/helpers - typeof";b="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&
"function"===typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};return b(a)}d=function(){return this}();try{d=d||(new Function("return this"))()}catch(e){"object"===("undefined"===typeof window?"undefined":b(window))&&(d=window)}a.exports=d},,,,,,function(a,d,b){a.exports=b(11)},function(a,d,b){function e(a){"@babel/helpers - typeof";e="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"===typeof Symbol&&
a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};return e(a)}b.r(d);a=b(2);a=b.n(a);var g=b(3);b.n(g);var l=b(12),q=g.window.jarallax;g.window.jarallax=l["default"];g.window.jarallax.noConflict=function(){g.window.jarallax=q;return this};if("undefined"!==typeof g.jQuery){b=function(){for(var a=arguments.length,b=Array(a),d=0;d<a;d++)b[d]=arguments[d];Array.prototype.unshift.call(b,this);a=l["default"].apply(g.window,b);return"object"!==e(a)?a:this};b.constructor=l["default"].constructor;
var v=g.jQuery.fn.jarallax;g.jQuery.fn.jarallax=b;g.jQuery.fn.jarallax.noConflict=function(){g.jQuery.fn.jarallax=v;return this}}a()(function(){Object(l["default"])(document.querySelectorAll("[data-jarallax]"))})},function(a,d,b){function e(a,f){var h=Array.isArray(a)?a:void 0;if(!h)if(h=a&&("undefined"!==typeof Symbol&&a[Symbol.iterator]||a["@@iterator"]),null==h)h=void 0;else{var c=[],b=!0,d=!1,m;try{for(h=h.call(a);!(b=(m=h.next()).done)&&(c.push(m.value),!f||c.length!==f);b=!0);}catch(B){d=!0;
var e=B}finally{try{if(!b&&null!=h["return"])h["return"]()}finally{if(d)throw e;}}h=c}if(!(m=h))a:{if(a){if("string"===typeof a){m=g(a,f);break a}m=Object.prototype.toString.call(a).slice(8,-1);"Object"===m&&a.constructor&&(m=a.constructor.name);if("Map"===m||"Set"===m){m=Array.from(a);break a}if("Arguments"===m||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(m)){m=g(a,f);break a}}m=void 0}if(!(a=m))throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
return a}function g(a,f){if(null==f||f>a.length)f=a.length;for(var h=0,c=Array(f);h<f;h++)c[h]=a[h];return c}function l(a){"@babel/helpers - typeof";l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"===typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};return l(a)}function q(a,f){for(var h=0;h<f.length;h++){var c=f[h];c.enumerable=c.enumerable||!1;c.configurable=!0;"value"in c&&(c.writable=!0);Object.defineProperty(a,
c.key,c)}}function v(a,f,h){f&&q(a.prototype,f);h&&q(a,h);return a}function u(){C?(!t&&document.body&&(t=document.createElement("div"),t.style.cssText="position: fixed; top: -9999px; left: 0; height: 100vh; width: 0;",document.body.appendChild(t)),k=(t?t.clientHeight:0)||p.window.innerHeight||document.documentElement.clientHeight):k=p.window.innerHeight||document.documentElement.clientHeight}function A(a){for(var f=[];null!==a.parentElement;)a=a.parentElement,1===a.nodeType&&f.push(a);return f}function x(){r.length&&
(r.forEach(function(a,f){var h=a.instance;a=a.oldData;var c=h.$item.getBoundingClientRect();c={width:c.width,height:c.height,top:c.top,bottom:c.bottom,wndW:p.window.innerWidth,wndH:k};var b=!a||a.wndW!==c.wndW||a.wndH!==c.wndH||a.width!==c.width||a.height!==c.height;a=b||!a||a.top!==c.top||a.bottom!==c.bottom;r[f].oldData=c;if(b)h.onResize();if(a)h.onScroll()}),p.window.requestAnimationFrame(x))}b.r(d);a=b(2);a=b.n(a);var p=b(3);b.n(p);var n=p.window.navigator,D=-1<n.userAgent.indexOf("MSIE ")||-1<
n.userAgent.indexOf("Trident/")||-1<n.userAgent.indexOf("Edge/"),C=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(n.userAgent),w=function(){for(var a=["transform","WebkitTransform","MozTransform"],f=document.createElement("div"),h=0;h<a.length;h+=1)if(f&&void 0!==f.style[a[h]])return a[h];return!1}(),t,k;u();p.window.addEventListener("resize",u);p.window.addEventListener("orientationchange",u);p.window.addEventListener("load",u);a()(function(){u({type:"dom-loaded"})});var r=
[],y=0,z=function(){function a(f,h){if(!(this instanceof a))throw new TypeError("Cannot call a class as a function");var c=this;c.instanceID=y;y+=1;c.$item=f;c.defaults={type:"scroll",speed:.5,imgSrc:null,imgElement:".jarallax-img",imgSize:"cover",imgPosition:"50% 50%",imgRepeat:"no-repeat",keepImg:!1,elementInViewport:null,zIndex:-100,disableParallax:!1,disableVideo:!1,videoSrc:null,videoStartTime:0,videoEndTime:0,videoVolume:0,videoLoop:!0,videoPlayOnlyVisible:!0,videoLazyLoading:!0,onScroll:null,
onInit:null,onDestroy:null,onCoverImage:null};var b=c.$item.dataset||{},d={};Object.keys(b).forEach(function(a){var f=a.substr(0,1).toLowerCase()+a.substr(1);f&&"undefined"!==typeof c.defaults[f]&&(d[f]=b[a])});c.options=c.extend({},c.defaults,d,h);c.pureOptions=c.extend({},c.options);Object.keys(c.options).forEach(function(a){"true"===c.options[a]?c.options[a]=!0:"false"===c.options[a]&&(c.options[a]=!1)});c.options.speed=Math.min(2,Math.max(-1,parseFloat(c.options.speed)));"string"===typeof c.options.disableParallax&&
(c.options.disableParallax=new RegExp(c.options.disableParallax));if(c.options.disableParallax instanceof RegExp){var g=c.options.disableParallax;c.options.disableParallax=function(){return g.test(n.userAgent)}}"function"!==typeof c.options.disableParallax&&(c.options.disableParallax=function(){return!1});"string"===typeof c.options.disableVideo&&(c.options.disableVideo=new RegExp(c.options.disableVideo));if(c.options.disableVideo instanceof RegExp){var m=c.options.disableVideo;c.options.disableVideo=
function(){return m.test(n.userAgent)}}"function"!==typeof c.options.disableVideo&&(c.options.disableVideo=function(){return!1});(f=c.options.elementInViewport)&&"object"===l(f)&&"undefined"!==typeof f.length&&(f=e(f,1)[0]);f instanceof Element||(f=null);c.options.elementInViewport=f;c.image={src:c.options.imgSrc||null,$container:null,useImgTag:!1,position:/iPad|iPhone|iPod|Android/.test(n.userAgent)?"absolute":"fixed"};c.initImg()&&c.canInitParallax()&&c.init()}v(a,[{key:"css",value:function(a,b){if("string"===
typeof b)return p.window.getComputedStyle(a).getPropertyValue(b);b.transform&&w&&(b[w]=b.transform);Object.keys(b).forEach(function(c){a.style[c]=b[c]});return a}},{key:"extend",value:function(a){for(var b=arguments.length,c=Array(1<b?b-1:0),f=1;f<b;f++)c[f-1]=arguments[f];a=a||{};Object.keys(c).forEach(function(b){c[b]&&Object.keys(c[b]).forEach(function(f){a[f]=c[b][f]})});return a}},{key:"getWindowData",value:function(){return{width:p.window.innerWidth||document.documentElement.clientWidth,height:k,
y:document.documentElement.scrollTop}}},{key:"initImg",value:function(){var a=this.options.imgElement;a&&"string"===typeof a&&(a=this.$item.querySelector(a));a instanceof Element||(this.options.imgSrc?(a=new Image,a.src=this.options.imgSrc):a=null);a&&(this.options.keepImg?this.image.$item=a.cloneNode(!0):(this.image.$item=a,this.image.$itemParent=a.parentNode),this.image.useImgTag=!0);if(this.image.$item)return!0;null===this.image.src&&(this.image.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
this.image.bgImage=this.css(this.$item,"background-image"));return!(!this.image.bgImage||"none"===this.image.bgImage)}},{key:"canInitParallax",value:function(){return w&&!this.options.disableParallax()}},{key:"init",value:function(){var a={position:"absolute",top:0,left:0,width:"100%",height:"100%",overflow:"hidden"},b={pointerEvents:"none",transformStyle:"preserve-3d",backfaceVisibility:"hidden",willChange:"transform,opacity"};if(!this.options.keepImg){var c=this.$item.getAttribute("style");c&&this.$item.setAttribute("data-jarallax-original-styles",
c);this.image.useImgTag&&(c=this.image.$item.getAttribute("style"))&&this.image.$item.setAttribute("data-jarallax-original-styles",c)}"static"===this.css(this.$item,"position")&&this.css(this.$item,{position:"relative"});"auto"===this.css(this.$item,"z-index")&&this.css(this.$item,{zIndex:0});this.image.$container=document.createElement("div");this.css(this.image.$container,a);this.css(this.image.$container,{"z-index":this.options.zIndex});D&&this.css(this.image.$container,{opacity:.9999});this.image.$container.setAttribute("id",
"jarallax-container-".concat(this.instanceID));this.$item.appendChild(this.image.$container);this.image.useImgTag?b=this.extend({"object-fit":this.options.imgSize,"object-position":this.options.imgPosition,"font-family":"object-fit: ".concat(this.options.imgSize,"; object-position: ").concat(this.options.imgPosition,";"),"max-width":"none"},a,b):(this.image.$item=document.createElement("div"),this.image.src&&(b=this.extend({"background-position":this.options.imgPosition,"background-size":this.options.imgSize,
"background-repeat":this.options.imgRepeat,"background-image":this.image.bgImage||'url("'.concat(this.image.src,'")')},a,b)));if("opacity"===this.options.type||"scale"===this.options.type||"scale-opacity"===this.options.type||1===this.options.speed)this.image.position="absolute";"fixed"===this.image.position&&(a=A(this.$item).filter(function(a){a=p.window.getComputedStyle(a);var c=a["-webkit-transform"]||a["-moz-transform"]||a.transform,b=/(auto|scroll)/;return c&&"none"!==c||b.test(a.overflow+a["overflow-y"]+
a["overflow-x"])}),this.image.position=a.length?"absolute":"fixed");b.position=this.image.position;this.css(this.image.$item,b);this.image.$container.appendChild(this.image.$item);this.onResize();this.onScroll(!0);this.options.onInit&&this.options.onInit.call(this);"none"!==this.css(this.$item,"background-image")&&this.css(this.$item,{"background-image":"none"});this.addToParallaxList()}},{key:"addToParallaxList",value:function(){r.push({instance:this});1===r.length&&p.window.requestAnimationFrame(x)}},
{key:"removeFromParallaxList",value:function(){var a=this;r.forEach(function(b,c){b.instance.instanceID===a.instanceID&&r.splice(c,1)})}},{key:"destroy",value:function(){this.removeFromParallaxList();var a=this.$item.getAttribute("data-jarallax-original-styles");this.$item.removeAttribute("data-jarallax-original-styles");a?this.$item.setAttribute("style",a):this.$item.removeAttribute("style");if(this.image.useImgTag){var b=this.image.$item.getAttribute("data-jarallax-original-styles");this.image.$item.removeAttribute("data-jarallax-original-styles");
b?this.image.$item.setAttribute("style",a):this.image.$item.removeAttribute("style");this.image.$itemParent&&this.image.$itemParent.appendChild(this.image.$item)}this.$clipStyles&&this.$clipStyles.parentNode.removeChild(this.$clipStyles);this.image.$container&&this.image.$container.parentNode.removeChild(this.image.$container);this.options.onDestroy&&this.options.onDestroy.call(this);delete this.$item.jarallax}},{key:"clipContainer",value:function(){if("fixed"===this.image.position){var a=this.image.$container.getBoundingClientRect(),
b=a.width;a=a.height;this.$clipStyles||(this.$clipStyles=document.createElement("style"),this.$clipStyles.setAttribute("type","text/css"),this.$clipStyles.setAttribute("id","jarallax-clip-".concat(this.instanceID)),(document.head||document.getElementsByTagName("head")[0]).appendChild(this.$clipStyles));b="#jarallax-container-".concat(this.instanceID," {\n clip: rect(0 ").concat(b,"px ").concat(a,"px 0);\n clip: rect(0, ").concat(b,"px, ").concat(a,"px, 0);\n -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);\n clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);\n }");
this.$clipStyles.styleSheet?this.$clipStyles.styleSheet.cssText=b:this.$clipStyles.innerHTML=b}}},{key:"coverImage",value:function(){var a=this.image.$container.getBoundingClientRect(),b=a.height,c=this.options.speed,d="scroll"===this.options.type||"scroll-opacity"===this.options.type,e=0,g=b;d&&(0>c?(e=c*Math.max(b,k),k<b&&(e-=c*(b-k))):e=c*(b+k),g=1<c?Math.abs(e-k):0>c?e/c+Math.abs(e):g+(k-b)*(1-c),e/=2);this.parallaxScrollDistance=e;b=d?(k-g)/2:(b-g)/2;this.css(this.image.$item,{height:"".concat(g,
"px"),marginTop:"".concat(b,"px"),left:"fixed"===this.image.position?"".concat(a.left,"px"):"0",width:"".concat(a.width,"px")});this.options.onCoverImage&&this.options.onCoverImage.call(this);return{image:{height:g,marginTop:b},container:a}}},{key:"isVisible",value:function(){return this.isElementInViewport||!1}},{key:"onScroll",value:function(a){var b=this.$item.getBoundingClientRect(),c=b.top,d=b.height,f={},e=b;this.options.elementInViewport&&(e=this.options.elementInViewport.getBoundingClientRect());
this.isElementInViewport=0<=e.bottom&&0<=e.right&&e.top<=k&&e.left<=p.window.innerWidth;if(a||this.isElementInViewport){a=Math.max(0,c);e=Math.max(0,d+c);var g=Math.max(0,-c),m=Math.max(0,c+d-k),l=Math.max(0,d-(c+d-k)),q=Math.max(0,-c+k-d),r=1-(k-c)/(k+d)*2,n=1;d<k?n=1-(g||m)/d:e<=k?n=e/k:l<=k&&(n=l/k);if("opacity"===this.options.type||"scale-opacity"===this.options.type||"scroll-opacity"===this.options.type)f.transform="translate3d(0,0,0)",f.opacity=n;if("scale"===this.options.type||"scale-opacity"===
this.options.type)d=1,d=0>this.options.speed?d-this.options.speed*n:d+this.options.speed*(1-n),f.transform="scale(".concat(d,") translate3d(0,0,0)");if("scroll"===this.options.type||"scroll-opacity"===this.options.type)d=this.parallaxScrollDistance*r,"absolute"===this.image.position&&(d-=c),f.transform="translate3d(0,".concat(d,"px,0)");this.css(this.image.$item,f);this.options.onScroll&&this.options.onScroll.call(this,{section:b,beforeTop:a,beforeTopEnd:e,afterTop:g,beforeBottom:m,beforeBottomEnd:l,
afterBottom:q,visiblePercent:n,fromViewportCenter:r})}}},{key:"onResize",value:function(){this.coverImage();this.clipContainer()}}]);return a}();b=function(a,b){if("object"===("undefined"===typeof HTMLElement?"undefined":l(HTMLElement))?a instanceof HTMLElement:a&&"object"===l(a)&&null!==a&&1===a.nodeType&&"string"===typeof a.nodeName)a=[a];for(var d=a.length,c=0,e,f=arguments.length,g=Array(2<f?f-2:0),k=2;k<f;k++)g[k-2]=arguments[k];for(c;c<d;c+=1)if("object"===l(b)||"undefined"===typeof b?a[c].jarallax||
(a[c].jarallax=new z(a[c],b)):a[c].jarallax&&(e=a[c].jarallax[b].apply(a[c].jarallax,g)),"undefined"!==typeof e)return e;return a};b.constructor=z;d["default"]=b}]);

View File

@ -0,0 +1,15 @@
(function(){function C(){if(!D&&document.body){D=!0;var a=document.body,b=document.documentElement,d=window.innerHeight,c=a.scrollHeight;l=0<=document.compatMode.indexOf("CSS")?b:a;m=a;f.keyboardSupport&&window.addEventListener("keydown",M,!1);if(top!=self)v=!0;else if(ca&&c>d&&(a.offsetHeight<=d||b.offsetHeight<=d)){var e=document.createElement("div");e.style.cssText="position:absolute; z-index:-10000; top:0; left:0; right:0; height:"+l.scrollHeight+"px";document.body.appendChild(e);var g;w=function(){g||
(g=setTimeout(function(){e.style.height="0";e.style.height=l.scrollHeight+"px";g=null},500))};setTimeout(w,10);window.addEventListener("resize",w,!1);z=new da(w);z.observe(a,{attributes:!0,childList:!0,characterData:!1});l.offsetHeight<=d&&(d=document.createElement("div"),d.style.clear="both",a.appendChild(d))}f.fixedBackground||(a.style.backgroundAttachment="scroll",b.style.backgroundAttachment="scroll")}}function N(a,b,d){ea(b,d);if(1!=f.accelerationMax){var c=Date.now()-E;c<f.accelerationDelta&&
(c=(1+50/c)/2,1<c&&(c=Math.min(c,f.accelerationMax),b*=c,d*=c));E=Date.now()}t.push({x:b,y:d,lastX:0>b?.99:-.99,lastY:0>d?.99:-.99,start:Date.now()});if(!F){c=O();var e=a===c||a===document.body;null==a.$scrollBehavior&&fa(a)&&(a.$scrollBehavior=a.style.scrollBehavior,a.style.scrollBehavior="auto");var g=function(c){c=Date.now();for(var k=0,l=0,h=0;h<t.length;h++){var n=t[h],p=c-n.start,m=p>=f.animationTime,q=m?1:p/f.animationTime;f.pulseAlgorithm&&(p=q,1<=p?q=1:0>=p?q=0:(1==f.pulseNormalize&&(f.pulseNormalize/=
P(1)),q=P(p)));p=n.x*q-n.lastX>>0;q=n.y*q-n.lastY>>0;k+=p;l+=q;n.lastX+=p;n.lastY+=q;m&&(t.splice(h,1),h--)}e?window.scrollBy(k,l):(k&&(a.scrollLeft+=k),l&&(a.scrollTop+=l));b||d||(t=[]);t.length?Q(g,a,1E3/f.frameRate+1):(F=!1,null!=a.$scrollBehavior&&(a.style.scrollBehavior=a.$scrollBehavior,a.$scrollBehavior=null))};Q(g,a,0);F=!0}}function R(a){D||C();var b=a.target;if(a.defaultPrevented||a.ctrlKey||r(m,"embed")||r(b,"embed")&&/\.pdf/i.test(b.src)||r(m,"object")||b.shadowRoot)return!0;var d=-a.wheelDeltaX||
a.deltaX||0,c=-a.wheelDeltaY||a.deltaY||0;ha&&(a.wheelDeltaX&&x(a.wheelDeltaX,120)&&(d=a.wheelDeltaX/Math.abs(a.wheelDeltaX)*-120),a.wheelDeltaY&&x(a.wheelDeltaY,120)&&(c=a.wheelDeltaY/Math.abs(a.wheelDeltaY)*-120));d||c||(c=-a.wheelDelta||0);1===a.deltaMode&&(d*=40,c*=40);b=S(b);if(!b)return v&&G?(Object.defineProperty(a,"target",{value:window.frameElement}),parent.wheel(a)):!0;if(ia(c))return!0;1.2<Math.abs(d)&&(d*=f.stepSize/120);1.2<Math.abs(c)&&(c*=f.stepSize/120);N(b,d,c);a.preventDefault();
T()}function M(a){var b=a.target,d=a.ctrlKey||a.altKey||a.metaKey||a.shiftKey&&a.keyCode!==g.spacebar;document.body.contains(m)||(m=document.activeElement);var c=/^(textarea|select|embed|object)$/i,e=/^(button|submit|radio|checkbox|file|color|image)$/i;if(!(c=a.defaultPrevented||c.test(b.nodeName)||r(b,"input")&&!e.test(b.type)||r(m,"video"))){c=a.target;var h=!1;if(-1!=document.URL.indexOf("www.youtube.com/watch")){do if(h=c.classList&&c.classList.contains("html5-video-controls"))break;while(c=c.parentNode)
}c=h}if(c||b.isContentEditable||d||(r(b,"button")||r(b,"input")&&e.test(b.type))&&a.keyCode===g.spacebar||r(b,"input")&&"radio"==b.type&&ja[a.keyCode])return!0;c=b=0;d=S(m);if(!d)return v&&G?parent.keydown(a):!0;e=d.clientHeight;d==document.body&&(e=window.innerHeight);switch(a.keyCode){case g.up:c=-f.arrowScroll;break;case g.down:c=f.arrowScroll;break;case g.spacebar:c=a.shiftKey?1:-1;c=-c*e*.9;break;case g.pageup:c=.9*-e;break;case g.pagedown:c=.9*e;break;case g.home:d==document.body&&document.scrollingElement&&
(d=document.scrollingElement);c=-d.scrollTop;break;case g.end:e=d.scrollHeight-d.scrollTop-e;c=0<e?e+10:0;break;case g.left:b=-f.arrowScroll;break;case g.right:b=f.arrowScroll;break;default:return!0}N(d,b,c);a.preventDefault();T()}function U(a){m=a.target}function T(){clearTimeout(V);V=setInterval(function(){W=H=A={}},1E3)}function I(a,b,d){d=d?W:H;for(var c=a.length;c--;)d[J(a[c])]=b;return b}function S(a){var b=[],d=document.body,c=l.scrollHeight;do{var e=H[J(a)];if(e)return I(b,e);b.push(a);if(c===
a.scrollHeight){if(e=X(l)&&X(d)||Y(l),v&&l.clientHeight+10<l.scrollHeight||!v&&e)return I(b,O())}else if(a.clientHeight+10<a.scrollHeight&&Y(a))return I(b,a)}while(a=a.parentElement)}function X(a){return"hidden"!==getComputedStyle(a,"").getPropertyValue("overflow-y")}function Y(a){a=getComputedStyle(a,"").getPropertyValue("overflow-y");return"scroll"===a||"auto"===a}function fa(a){var b=J(a);null==A[b]&&(a=getComputedStyle(a,"")["scroll-behavior"],A[b]="smooth"==a);return A[b]}function r(a,b){return a&&
(a.nodeName||"").toLowerCase()===b.toLowerCase()}function ea(a,b){a=0<a?1:-1;b=0<b?1:-1;if(B.x!==a||B.y!==b)B.x=a,B.y=b,t=[],E=0}function ia(a){if(a){h.length||(h=[a,a,a]);a=Math.abs(a);h.push(a);h.shift();clearTimeout(Z);Z=setTimeout(function(){try{localStorage.SS_deltaBuffer=h.join(",")}catch(d){}},1E3);var b=120<a&&K(a);b=!K(120)&&!K(100)&&!b;return 50>a?!0:b}}function x(a,b){return Math.floor(a/b)==a/b}function K(a){return x(h[0],a)&&x(h[1],a)&&x(h[2],a)}function P(a){a*=f.pulseScale;if(1>a)var b=
a-(1-Math.exp(-a));else b=Math.exp(-1),a=1-Math.exp(-(a-1)),b+=a*(1-b);return b*f.pulseNormalize}function y(a){for(var b in a)aa.hasOwnProperty(b)&&(f[b]=a[b])}var aa={frameRate:150,animationTime:400,stepSize:100,pulseAlgorithm:!0,pulseScale:4,pulseNormalize:1,accelerationDelta:50,accelerationMax:3,keyboardSupport:!0,arrowScroll:50,fixedBackground:!0,excluded:""},f=aa,v=!1,B={x:0,y:0},D=!1,l=document.documentElement,m,z,w,h=[],Z,ha=/^Mac/.test(navigator.platform),g={left:37,up:38,right:39,down:40,
spacebar:32,pageup:33,pagedown:34,end:35,home:36},ja={37:1,38:1,39:1,40:1},t=[],F=!1,E=Date.now(),J=function(){var a=0;return function(b){return b.uniqueID||(b.uniqueID=a++)}}(),W={},H={},V,A={};if(window.localStorage&&localStorage.SS_deltaBuffer)try{h=localStorage.SS_deltaBuffer.split(",")}catch(a){}var Q=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a,b,d){window.setTimeout(a,d||1E3/60)}}(),da=window.MutationObserver||
window.WebKitMutationObserver||window.MozMutationObserver,O=function(){var a=document.scrollingElement;return function(){if(!a){var b=document.createElement("div");b.style.cssText="height:10000px;width:1px;";document.body.appendChild(b);var d=document.body.scrollTop;window.scrollBy(0,3);a=document.body.scrollTop!=d?document.body:document.documentElement;window.scrollBy(0,-3);document.body.removeChild(b)}return a}}(),k=window.navigator.userAgent,u=/Edge/.test(k),G=/chrome/i.test(k)&&!u;u=/safari/i.test(k)&&
!u;var ka=/mobile/i.test(k),la=/Windows NT 6.1/i.test(k)&&/rv:11/i.test(k),ca=u&&(/Version\/8/i.test(k)||/Version\/9/i.test(k));k=(G||u||la)&&!ka;var ba=!1;try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:function(){ba=!0}}))}catch(a){}u=ba?{passive:!1}:!1;var L="onwheel"in document.createElement("div")?"wheel":"mousewheel";L&&k&&(window.addEventListener(L,R,u||!1),window.addEventListener("mousedown",U,!1),window.addEventListener("load",C,!1));y.destroy=function(){z&&
z.disconnect();window.removeEventListener(L,R,!1);window.removeEventListener("mousedown",U,!1);window.removeEventListener("keydown",M,!1);window.removeEventListener("resize",w,!1);window.removeEventListener("load",C,!1)};window.SmoothScrollOptions&&y(window.SmoothScrollOptions);"function"===typeof define&&define.amd?define(function(){return y}):"object"==typeof exports?module.exports=y:window.SmoothScroll=y})();

View File

@ -0,0 +1,934 @@
@charset "UTF-8";
@font-face {
font-family: 'Socicon';
src: url('../fonts/socicon.eot');
src: url('../fonts/socicon.eot?#iefix') format('embedded-opentype'),
url('../fonts/socicon.woff2') format('woff2'),
url('../fonts/socicon.ttf') format('truetype'),
url('../fonts/socicon.woff') format('woff'),
url('../fonts/socicon.svg#socicon') format('svg');
font-weight: normal;
font-style: normal;
font-display: swap;
}
[data-icon]:before {
font-family: "socicon" !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
[class^="socicon-"], [class*=" socicon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'Socicon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.socicon-eitaa:before {
content: "\e97c";
}
.socicon-soroush:before {
content: "\e97d";
}
.socicon-bale:before {
content: "\e97e";
}
.socicon-zazzle:before {
content: "\e97b";
}
.socicon-society6:before {
content: "\e97a";
}
.socicon-redbubble:before {
content: "\e979";
}
.socicon-avvo:before {
content: "\e978";
}
.socicon-stitcher:before {
content: "\e977";
}
.socicon-googlehangouts:before {
content: "\e974";
}
.socicon-dlive:before {
content: "\e975";
}
.socicon-vsco:before {
content: "\e976";
}
.socicon-flipboard:before {
content: "\e973";
}
.socicon-ubuntu:before {
content: "\e958";
}
.socicon-artstation:before {
content: "\e959";
}
.socicon-invision:before {
content: "\e95a";
}
.socicon-torial:before {
content: "\e95b";
}
.socicon-collectorz:before {
content: "\e95c";
}
.socicon-seenthis:before {
content: "\e95d";
}
.socicon-googleplaymusic:before {
content: "\e95e";
}
.socicon-debian:before {
content: "\e95f";
}
.socicon-filmfreeway:before {
content: "\e960";
}
.socicon-gnome:before {
content: "\e961";
}
.socicon-itchio:before {
content: "\e962";
}
.socicon-jamendo:before {
content: "\e963";
}
.socicon-mix:before {
content: "\e964";
}
.socicon-sharepoint:before {
content: "\e965";
}
.socicon-tinder:before {
content: "\e966";
}
.socicon-windguru:before {
content: "\e967";
}
.socicon-cdbaby:before {
content: "\e968";
}
.socicon-elementaryos:before {
content: "\e969";
}
.socicon-stage32:before {
content: "\e96a";
}
.socicon-tiktok:before {
content: "\e96b";
}
.socicon-gitter:before {
content: "\e96c";
}
.socicon-letterboxd:before {
content: "\e96d";
}
.socicon-threema:before {
content: "\e96e";
}
.socicon-splice:before {
content: "\e96f";
}
.socicon-metapop:before {
content: "\e970";
}
.socicon-naver:before {
content: "\e971";
}
.socicon-remote:before {
content: "\e972";
}
.socicon-internet:before {
content: "\e957";
}
.socicon-moddb:before {
content: "\e94b";
}
.socicon-indiedb:before {
content: "\e94c";
}
.socicon-traxsource:before {
content: "\e94d";
}
.socicon-gamefor:before {
content: "\e94e";
}
.socicon-pixiv:before {
content: "\e94f";
}
.socicon-myanimelist:before {
content: "\e950";
}
.socicon-blackberry:before {
content: "\e951";
}
.socicon-wickr:before {
content: "\e952";
}
.socicon-spip:before {
content: "\e953";
}
.socicon-napster:before {
content: "\e954";
}
.socicon-beatport:before {
content: "\e955";
}
.socicon-hackerone:before {
content: "\e956";
}
.socicon-hackernews:before {
content: "\e946";
}
.socicon-smashwords:before {
content: "\e947";
}
.socicon-kobo:before {
content: "\e948";
}
.socicon-bookbub:before {
content: "\e949";
}
.socicon-mailru:before {
content: "\e94a";
}
.socicon-gitlab:before {
content: "\e945";
}
.socicon-instructables:before {
content: "\e944";
}
.socicon-portfolio:before {
content: "\e943";
}
.socicon-codered:before {
content: "\e940";
}
.socicon-origin:before {
content: "\e941";
}
.socicon-nextdoor:before {
content: "\e942";
}
.socicon-udemy:before {
content: "\e93f";
}
.socicon-livemaster:before {
content: "\e93e";
}
.socicon-crunchbase:before {
content: "\e93b";
}
.socicon-homefy:before {
content: "\e93c";
}
.socicon-calendly:before {
content: "\e93d";
}
.socicon-realtor:before {
content: "\e90f";
}
.socicon-tidal:before {
content: "\e910";
}
.socicon-qobuz:before {
content: "\e911";
}
.socicon-natgeo:before {
content: "\e912";
}
.socicon-mastodon:before {
content: "\e913";
}
.socicon-unsplash:before {
content: "\e914";
}
.socicon-homeadvisor:before {
content: "\e915";
}
.socicon-angieslist:before {
content: "\e916";
}
.socicon-codepen:before {
content: "\e917";
}
.socicon-slack:before {
content: "\e918";
}
.socicon-openaigym:before {
content: "\e919";
}
.socicon-logmein:before {
content: "\e91a";
}
.socicon-fiverr:before {
content: "\e91b";
}
.socicon-gotomeeting:before {
content: "\e91c";
}
.socicon-aliexpress:before {
content: "\e91d";
}
.socicon-guru:before {
content: "\e91e";
}
.socicon-appstore:before {
content: "\e91f";
}
.socicon-homes:before {
content: "\e920";
}
.socicon-zoom:before {
content: "\e921";
}
.socicon-alibaba:before {
content: "\e922";
}
.socicon-craigslist:before {
content: "\e923";
}
.socicon-wix:before {
content: "\e924";
}
.socicon-redfin:before {
content: "\e925";
}
.socicon-googlecalendar:before {
content: "\e926";
}
.socicon-shopify:before {
content: "\e927";
}
.socicon-freelancer:before {
content: "\e928";
}
.socicon-seedrs:before {
content: "\e929";
}
.socicon-bing:before {
content: "\e92a";
}
.socicon-doodle:before {
content: "\e92b";
}
.socicon-bonanza:before {
content: "\e92c";
}
.socicon-squarespace:before {
content: "\e92d";
}
.socicon-toptal:before {
content: "\e92e";
}
.socicon-gust:before {
content: "\e92f";
}
.socicon-ask:before {
content: "\e930";
}
.socicon-trulia:before {
content: "\e931";
}
.socicon-loomly:before {
content: "\e932";
}
.socicon-ghost:before {
content: "\e933";
}
.socicon-upwork:before {
content: "\e934";
}
.socicon-fundable:before {
content: "\e935";
}
.socicon-booking:before {
content: "\e936";
}
.socicon-googlemaps:before {
content: "\e937";
}
.socicon-zillow:before {
content: "\e938";
}
.socicon-niconico:before {
content: "\e939";
}
.socicon-toneden:before {
content: "\e93a";
}
.socicon-augment:before {
content: "\e908";
}
.socicon-bitbucket:before {
content: "\e909";
}
.socicon-fyuse:before {
content: "\e90a";
}
.socicon-yt-gaming:before {
content: "\e90b";
}
.socicon-sketchfab:before {
content: "\e90c";
}
.socicon-mobcrush:before {
content: "\e90d";
}
.socicon-microsoft:before {
content: "\e90e";
}
.socicon-pandora:before {
content: "\e907";
}
.socicon-messenger:before {
content: "\e906";
}
.socicon-gamewisp:before {
content: "\e905";
}
.socicon-bloglovin:before {
content: "\e904";
}
.socicon-tunein:before {
content: "\e903";
}
.socicon-gamejolt:before {
content: "\e901";
}
.socicon-trello:before {
content: "\e902";
}
.socicon-spreadshirt:before {
content: "\e900";
}
.socicon-500px:before {
content: "\e000";
}
.socicon-8tracks:before {
content: "\e001";
}
.socicon-airbnb:before {
content: "\e002";
}
.socicon-alliance:before {
content: "\e003";
}
.socicon-amazon:before {
content: "\e004";
}
.socicon-amplement:before {
content: "\e005";
}
.socicon-android:before {
content: "\e006";
}
.socicon-angellist:before {
content: "\e007";
}
.socicon-apple:before {
content: "\e008";
}
.socicon-appnet:before {
content: "\e009";
}
.socicon-baidu:before {
content: "\e00a";
}
.socicon-bandcamp:before {
content: "\e00b";
}
.socicon-battlenet:before {
content: "\e00c";
}
.socicon-mixer:before {
content: "\e00d";
}
.socicon-bebee:before {
content: "\e00e";
}
.socicon-bebo:before {
content: "\e00f";
}
.socicon-behance:before {
content: "\e010";
}
.socicon-blizzard:before {
content: "\e011";
}
.socicon-blogger:before {
content: "\e012";
}
.socicon-buffer:before {
content: "\e013";
}
.socicon-chrome:before {
content: "\e014";
}
.socicon-coderwall:before {
content: "\e015";
}
.socicon-curse:before {
content: "\e016";
}
.socicon-dailymotion:before {
content: "\e017";
}
.socicon-deezer:before {
content: "\e018";
}
.socicon-delicious:before {
content: "\e019";
}
.socicon-deviantart:before {
content: "\e01a";
}
.socicon-diablo:before {
content: "\e01b";
}
.socicon-digg:before {
content: "\e01c";
}
.socicon-discord:before {
content: "\e01d";
}
.socicon-disqus:before {
content: "\e01e";
}
.socicon-douban:before {
content: "\e01f";
}
.socicon-draugiem:before {
content: "\e020";
}
.socicon-dribbble:before {
content: "\e021";
}
.socicon-drupal:before {
content: "\e022";
}
.socicon-ebay:before {
content: "\e023";
}
.socicon-ello:before {
content: "\e024";
}
.socicon-endomodo:before {
content: "\e025";
}
.socicon-envato:before {
content: "\e026";
}
.socicon-etsy:before {
content: "\e027";
}
.socicon-facebook:before {
content: "\e028";
}
.socicon-feedburner:before {
content: "\e029";
}
.socicon-filmweb:before {
content: "\e02a";
}
.socicon-firefox:before {
content: "\e02b";
}
.socicon-flattr:before {
content: "\e02c";
}
.socicon-flickr:before {
content: "\e02d";
}
.socicon-formulr:before {
content: "\e02e";
}
.socicon-forrst:before {
content: "\e02f";
}
.socicon-foursquare:before {
content: "\e030";
}
.socicon-friendfeed:before {
content: "\e031";
}
.socicon-github:before {
content: "\e032";
}
.socicon-goodreads:before {
content: "\e033";
}
.socicon-google:before {
content: "\e034";
}
.socicon-googlescholar:before {
content: "\e035";
}
.socicon-googlegroups:before {
content: "\e036";
}
.socicon-googlephotos:before {
content: "\e037";
}
.socicon-googleplus:before {
content: "\e038";
}
.socicon-grooveshark:before {
content: "\e039";
}
.socicon-hackerrank:before {
content: "\e03a";
}
.socicon-hearthstone:before {
content: "\e03b";
}
.socicon-hellocoton:before {
content: "\e03c";
}
.socicon-heroes:before {
content: "\e03d";
}
.socicon-smashcast:before {
content: "\e03e";
}
.socicon-horde:before {
content: "\e03f";
}
.socicon-houzz:before {
content: "\e040";
}
.socicon-icq:before {
content: "\e041";
}
.socicon-identica:before {
content: "\e042";
}
.socicon-imdb:before {
content: "\e043";
}
.socicon-instagram:before {
content: "\e044";
}
.socicon-issuu:before {
content: "\e045";
}
.socicon-istock:before {
content: "\e046";
}
.socicon-itunes:before {
content: "\e047";
}
.socicon-keybase:before {
content: "\e048";
}
.socicon-lanyrd:before {
content: "\e049";
}
.socicon-lastfm:before {
content: "\e04a";
}
.socicon-line:before {
content: "\e04b";
}
.socicon-linkedin:before {
content: "\e04c";
}
.socicon-livejournal:before {
content: "\e04d";
}
.socicon-lyft:before {
content: "\e04e";
}
.socicon-macos:before {
content: "\e04f";
}
.socicon-mail:before {
content: "\e050";
}
.socicon-medium:before {
content: "\e051";
}
.socicon-meetup:before {
content: "\e052";
}
.socicon-mixcloud:before {
content: "\e053";
}
.socicon-modelmayhem:before {
content: "\e054";
}
.socicon-mumble:before {
content: "\e055";
}
.socicon-myspace:before {
content: "\e056";
}
.socicon-newsvine:before {
content: "\e057";
}
.socicon-nintendo:before {
content: "\e058";
}
.socicon-npm:before {
content: "\e059";
}
.socicon-odnoklassniki:before {
content: "\e05a";
}
.socicon-openid:before {
content: "\e05b";
}
.socicon-opera:before {
content: "\e05c";
}
.socicon-outlook:before {
content: "\e05d";
}
.socicon-overwatch:before {
content: "\e05e";
}
.socicon-patreon:before {
content: "\e05f";
}
.socicon-paypal:before {
content: "\e060";
}
.socicon-periscope:before {
content: "\e061";
}
.socicon-persona:before {
content: "\e062";
}
.socicon-pinterest:before {
content: "\e063";
}
.socicon-play:before {
content: "\e064";
}
.socicon-player:before {
content: "\e065";
}
.socicon-playstation:before {
content: "\e066";
}
.socicon-pocket:before {
content: "\e067";
}
.socicon-qq:before {
content: "\e068";
}
.socicon-quora:before {
content: "\e069";
}
.socicon-raidcall:before {
content: "\e06a";
}
.socicon-ravelry:before {
content: "\e06b";
}
.socicon-reddit:before {
content: "\e06c";
}
.socicon-renren:before {
content: "\e06d";
}
.socicon-researchgate:before {
content: "\e06e";
}
.socicon-residentadvisor:before {
content: "\e06f";
}
.socicon-reverbnation:before {
content: "\e070";
}
.socicon-rss:before {
content: "\e071";
}
.socicon-sharethis:before {
content: "\e072";
}
.socicon-skype:before {
content: "\e073";
}
.socicon-slideshare:before {
content: "\e074";
}
.socicon-smugmug:before {
content: "\e075";
}
.socicon-snapchat:before {
content: "\e076";
}
.socicon-songkick:before {
content: "\e077";
}
.socicon-soundcloud:before {
content: "\e078";
}
.socicon-spotify:before {
content: "\e079";
}
.socicon-stackexchange:before {
content: "\e07a";
}
.socicon-stackoverflow:before {
content: "\e07b";
}
.socicon-starcraft:before {
content: "\e07c";
}
.socicon-stayfriends:before {
content: "\e07d";
}
.socicon-steam:before {
content: "\e07e";
}
.socicon-storehouse:before {
content: "\e07f";
}
.socicon-strava:before {
content: "\e080";
}
.socicon-streamjar:before {
content: "\e081";
}
.socicon-stumbleupon:before {
content: "\e082";
}
.socicon-swarm:before {
content: "\e083";
}
.socicon-teamspeak:before {
content: "\e084";
}
.socicon-teamviewer:before {
content: "\e085";
}
.socicon-technorati:before {
content: "\e086";
}
.socicon-telegram:before {
content: "\e087";
}
.socicon-tripadvisor:before {
content: "\e088";
}
.socicon-tripit:before {
content: "\e089";
}
.socicon-triplej:before {
content: "\e08a";
}
.socicon-tumblr:before {
content: "\e08b";
}
.socicon-twitch:before {
content: "\e08c";
}
.socicon-twitter:before {
content: "\e08d";
}
.socicon-uber:before {
content: "\e08e";
}
.socicon-ventrilo:before {
content: "\e08f";
}
.socicon-viadeo:before {
content: "\e090";
}
.socicon-viber:before {
content: "\e091";
}
.socicon-viewbug:before {
content: "\e092";
}
.socicon-vimeo:before {
content: "\e093";
}
.socicon-vine:before {
content: "\e094";
}
.socicon-vkontakte:before {
content: "\e095";
}
.socicon-warcraft:before {
content: "\e096";
}
.socicon-wechat:before {
content: "\e097";
}
.socicon-weibo:before {
content: "\e098";
}
.socicon-whatsapp:before {
content: "\e099";
}
.socicon-wikipedia:before {
content: "\e09a";
}
.socicon-windows:before {
content: "\e09b";
}
.socicon-wordpress:before {
content: "\e09c";
}
.socicon-wykop:before {
content: "\e09d";
}
.socicon-xbox:before {
content: "\e09e";
}
.socicon-xing:before {
content: "\e09f";
}
.socicon-yahoo:before {
content: "\e0a0";
}
.socicon-yammer:before {
content: "\e0a1";
}
.socicon-yandex:before {
content: "\e0a2";
}
.socicon-yelp:before {
content: "\e0a3";
}
.socicon-younow:before {
content: "\e0a4";
}
.socicon-youtube:before {
content: "\e0a5";
}
.socicon-zapier:before {
content: "\e0a6";
}
.socicon-zerply:before {
content: "\e0a7";
}
.socicon-zomato:before {
content: "\e0a8";
}
.socicon-zynga:before {
content: "\e0a9";
}

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,965 @@
@charset "UTF-8";
section {
background-color: #ffffff;
}
body {
font-style: normal;
line-height: 1.5;
font-weight: 400;
color: #232323;
position: relative;
}
button {
background-color: transparent;
border-color: transparent;
}
.embla__button,
.carousel-control {
background-color: #edefea !important;
opacity: 0.8 !important;
color: #464845 !important;
border-color: #edefea !important;
}
.carousel .close,
.modalWindow .close {
background-color: #edefea !important;
color: #464845 !important;
border-color: #edefea !important;
opacity: 0.8 !important;
}
.carousel .close:hover,
.modalWindow .close:hover {
opacity: 1 !important;
}
.carousel-indicators li {
background-color: #edefea !important;
border: 2px solid #464845 !important;
}
.carousel-indicators li:hover,
.carousel-indicators li:active {
opacity: 0.8 !important;
}
.embla__button:hover,
.carousel-control:hover {
background-color: #edefea !important;
opacity: 1 !important;
}
.modalWindow-video-container {
height: 80%;
}
section,
.container,
.container-fluid {
position: relative;
word-wrap: break-word;
}
a.mbr-iconfont:hover {
text-decoration: none;
}
.article .lead p,
.article .lead ul,
.article .lead ol,
.article .lead pre,
.article .lead blockquote {
margin-bottom: 0;
}
a {
font-style: normal;
font-weight: 400;
cursor: pointer;
}
a, a:hover {
text-decoration: none;
}
.mbr-section-title {
font-style: normal;
line-height: 1.3;
}
.mbr-section-subtitle {
line-height: 1.3;
}
.mbr-text {
font-style: normal;
line-height: 1.7;
}
h1,
h2,
h3,
h4,
h5,
h6,
.display-1,
.display-2,
.display-4,
.display-5,
.display-7,
span,
p,
a {
line-height: 1;
word-break: break-word;
word-wrap: break-word;
font-weight: 400;
}
b,
strong {
font-weight: bold;
}
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, input:-webkit-autofill:active {
transition-delay: 9999s;
-webkit-transition-property: background-color, color;
transition-property: background-color, color;
}
textarea[type=hidden] {
display: none;
}
section {
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
}
section .mbr-background-video,
section .mbr-background-video-preview {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 0;
}
.hidden {
visibility: hidden;
}
.mbr-z-index20 {
z-index: 20;
}
/*! Base colors */
.mbr-white {
color: #ffffff;
}
.mbr-black {
color: #111111;
}
.mbr-bg-white {
background-color: #ffffff;
}
.mbr-bg-black {
background-color: #000000;
}
/*! Text-aligns */
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/*! Font-weight */
.mbr-light {
font-weight: 300;
}
.mbr-regular {
font-weight: 400;
}
.mbr-semibold {
font-weight: 500;
}
.mbr-bold {
font-weight: 700;
}
/*! Media */
.media-content {
flex-basis: 100%;
}
.media-container-row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: start;
}
.media-container-row .media-size-item {
width: 400px;
}
.media-container-column {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: stretch;
}
.media-container-column > * {
width: 100%;
}
@media (min-width: 992px) {
.media-container-row {
flex-wrap: nowrap;
}
}
figure {
margin-bottom: 0;
overflow: hidden;
}
figure[mbr-media-size] {
transition: width 0.1s;
}
img,
iframe {
display: block;
width: 100%;
}
.card {
background-color: transparent;
border: none;
}
.card-box {
width: 100%;
}
.card-img {
text-align: center;
flex-shrink: 0;
-webkit-flex-shrink: 0;
}
.media {
max-width: 100%;
margin: 0 auto;
}
.mbr-figure {
align-self: center;
}
.media-container > div {
max-width: 100%;
}
.mbr-figure img,
.card-img img {
width: 100%;
}
@media (max-width: 991px) {
.media-size-item {
width: auto !important;
}
.media {
width: auto;
}
.mbr-figure {
width: 100% !important;
}
}
/*! Buttons */
.mbr-section-btn {
margin-left: -0.6rem;
margin-right: -0.6rem;
font-size: 0;
}
.btn {
font-weight: 600;
border-width: 1px;
font-style: normal;
margin: 0.6rem 0.6rem;
white-space: normal;
transition: all 0.2s ease-in-out;
display: inline-flex;
align-items: center;
justify-content: center;
word-break: break-word;
}
.btn-sm {
font-weight: 600;
letter-spacing: 0px;
transition: all 0.3s ease-in-out;
}
.btn-md {
font-weight: 600;
letter-spacing: 0px;
transition: all 0.3s ease-in-out;
}
.btn-lg {
font-weight: 600;
letter-spacing: 0px;
transition: all 0.3s ease-in-out;
}
.btn-form {
margin: 0;
}
.btn-form:hover {
cursor: pointer;
}
nav .mbr-section-btn {
margin-left: 0rem;
margin-right: 0rem;
}
/*! Btn icon margin */
.btn .mbr-iconfont,
.btn.btn-sm .mbr-iconfont {
order: 1;
cursor: pointer;
margin-left: 0.5rem;
vertical-align: sub;
}
.btn.btn-md .mbr-iconfont,
.btn.btn-md .mbr-iconfont {
margin-left: 0.8rem;
}
.mbr-regular {
font-weight: 400;
}
.mbr-semibold {
font-weight: 500;
}
.mbr-bold {
font-weight: 700;
}
[type=submit] {
-webkit-appearance: none;
}
/*! Full-screen */
.mbr-fullscreen .mbr-overlay {
min-height: 100vh;
}
.mbr-fullscreen {
display: flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
align-items: center;
min-height: 100vh;
padding-top: 3rem;
padding-bottom: 3rem;
}
/*! Map */
.map {
height: 25rem;
position: relative;
}
.map iframe {
width: 100%;
height: 100%;
}
/*! Scroll to top arrow */
.mbr-arrow-up {
bottom: 25px;
right: 90px;
position: fixed;
text-align: right;
z-index: 5000;
color: #ffffff;
font-size: 22px;
}
.mbr-arrow-up a {
background: rgba(0, 0, 0, 0.2);
border-radius: 50%;
color: #fff;
display: inline-block;
height: 60px;
width: 60px;
border: 2px solid #fff;
outline-style: none !important;
position: relative;
text-decoration: none;
transition: all 0.3s ease-in-out;
cursor: pointer;
text-align: center;
}
.mbr-arrow-up a:hover {
background-color: rgba(0, 0, 0, 0.4);
}
.mbr-arrow-up a i {
line-height: 60px;
}
.mbr-arrow-up-icon {
display: block;
color: #fff;
}
.mbr-arrow-up-icon::before {
content: "";
display: inline-block;
font-family: serif;
font-size: 22px;
line-height: 1;
font-style: normal;
position: relative;
top: 6px;
left: -4px;
transform: rotate(-90deg);
}
/*! Arrow Down */
.mbr-arrow {
position: absolute;
bottom: 45px;
left: 50%;
width: 60px;
height: 60px;
cursor: pointer;
background-color: rgba(80, 80, 80, 0.5);
border-radius: 50%;
transform: translateX(-50%);
}
@media (max-width: 767px) {
.mbr-arrow {
display: none;
}
}
.mbr-arrow > a {
display: inline-block;
text-decoration: none;
outline-style: none;
animation: arrowdown 1.7s ease-in-out infinite;
color: #ffffff;
}
.mbr-arrow > a > i {
position: absolute;
top: -2px;
left: 15px;
font-size: 2rem;
}
#scrollToTop a i::before {
content: "";
position: absolute;
display: block;
border-bottom: 2.5px solid #fff;
border-left: 2.5px solid #fff;
width: 27.8%;
height: 27.8%;
left: 50%;
top: 51%;
transform: translateY(-30%) translateX(-50%) rotate(135deg);
}
@keyframes arrowdown {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-5px);
}
100% {
transform: translateY(0px);
}
}
@media (max-width: 500px) {
.mbr-arrow-up {
left: 0;
right: 0;
text-align: center;
}
}
/*Gradients animation*/
@keyframes gradient-animation {
from {
background-position: 0% 100%;
animation-timing-function: ease-in-out;
}
to {
background-position: 100% 0%;
animation-timing-function: ease-in-out;
}
}
.bg-gradient {
background-size: 200% 200%;
animation: gradient-animation 5s infinite alternate;
-webkit-animation: gradient-animation 5s infinite alternate;
}
.menu .navbar-brand {
display: -webkit-flex;
}
.menu .navbar-brand span {
display: flex;
display: -webkit-flex;
}
.menu .navbar-brand .navbar-caption-wrap {
display: -webkit-flex;
}
.menu .navbar-brand .navbar-logo img {
display: -webkit-flex;
width: auto;
}
@media (min-width: 768px) and (max-width: 991px) {
.menu .navbar-toggleable-sm .navbar-nav {
display: -ms-flexbox;
}
}
@media (max-width: 991px) {
.menu .navbar-collapse {
max-height: 93.5vh;
}
.menu .navbar-collapse.show {
overflow: auto;
}
}
@media (min-width: 992px) {
.menu .navbar-nav.nav-dropdown {
display: -webkit-flex;
}
.menu .navbar-toggleable-sm .navbar-collapse {
display: -webkit-flex !important;
}
.menu .collapsed .navbar-collapse {
max-height: 93.5vh;
}
.menu .collapsed .navbar-collapse.show {
overflow: auto;
}
}
@media (max-width: 767px) {
.menu .navbar-collapse {
max-height: 80vh;
}
}
.nav-link .mbr-iconfont {
margin-right: 0.5rem;
}
.navbar {
display: -webkit-flex;
-webkit-flex-wrap: wrap;
-webkit-align-items: center;
-webkit-justify-content: space-between;
}
.navbar-collapse {
-webkit-flex-basis: 100%;
-webkit-flex-grow: 1;
-webkit-align-items: center;
}
.nav-dropdown .link {
padding: 0.667em 1.667em !important;
margin: 0 !important;
}
.nav {
display: -webkit-flex;
-webkit-flex-wrap: wrap;
}
.row {
display: -webkit-flex;
-webkit-flex-wrap: wrap;
}
.justify-content-center {
-webkit-justify-content: center;
}
.form-inline {
display: -webkit-flex;
}
.card-wrapper {
-webkit-flex: 1;
}
.carousel-control {
z-index: 10;
display: -webkit-flex;
}
.carousel-controls {
display: -webkit-flex;
}
.media {
display: -webkit-flex;
}
.form-group:focus {
outline: none;
}
.jq-selectbox__select {
padding: 7px 0;
position: relative;
}
.jq-selectbox__dropdown {
overflow: hidden;
border-radius: 10px;
position: absolute;
top: 100%;
left: 0 !important;
width: 100% !important;
}
.jq-selectbox__trigger-arrow {
right: 0;
transform: translateY(-50%);
}
.jq-selectbox li {
padding: 1.07em 0.5em;
}
input[type=range] {
padding-left: 0 !important;
padding-right: 0 !important;
}
.modal-dialog,
.modal-content {
height: 100%;
}
.modal-dialog .carousel-inner {
height: calc(100vh - 1.75rem);
}
@media (max-width: 575px) {
.modal-dialog .carousel-inner {
height: calc(100vh - 1rem);
}
}
.carousel-item {
text-align: center;
}
.carousel-item img {
margin: auto;
}
.navbar-toggler {
align-self: flex-start;
padding: 0.25rem 0.75rem;
font-size: 1.25rem;
line-height: 1;
background: transparent;
border: 1px solid transparent;
border-radius: 0.25rem;
}
.navbar-toggler:focus,
.navbar-toggler:hover {
text-decoration: none;
box-shadow: none;
}
.navbar-toggler-icon {
display: inline-block;
width: 1.5em;
height: 1.5em;
vertical-align: middle;
content: "";
background: no-repeat center center;
background-size: 100% 100%;
}
.navbar-toggler-left {
position: absolute;
left: 1rem;
}
.navbar-toggler-right {
position: absolute;
right: 1rem;
}
.card-img {
width: auto;
}
.menu .navbar.collapsed:not(.beta-menu) {
flex-direction: column;
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: flex;
}
.note-air-layout .dropup .dropdown-menu,
.note-air-layout .navbar-fixed-bottom .dropdown .dropdown-menu {
bottom: initial !important;
}
html,
body {
height: auto;
min-height: 100vh;
}
.dropup .dropdown-toggle::after {
display: none;
}
.form-asterisk {
font-family: initial;
position: absolute;
top: -2px;
font-weight: normal;
}
.form-control-label {
position: relative;
cursor: pointer;
margin-bottom: 0.357em;
padding: 0;
}
.alert {
color: #ffffff;
border-radius: 0;
border: 0;
font-size: 1.1rem;
line-height: 1.5;
margin-bottom: 1.875rem;
padding: 1.25rem;
position: relative;
text-align: center;
}
.alert.alert-form::after {
background-color: inherit;
bottom: -7px;
content: "";
display: block;
height: 14px;
left: 50%;
margin-left: -7px;
position: absolute;
transform: rotate(45deg);
width: 14px;
}
.form-control {
background-color: #ffffff;
background-clip: border-box;
color: #232323;
line-height: 1rem !important;
height: auto;
padding: 1.2rem 2rem;
transition: border-color 0.25s ease 0s;
border: 1px solid transparent !important;
border-radius: 4px;
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px 0px, rgba(0, 0, 0, 0.07) 0px 1px 3px 0px, rgba(0, 0, 0, 0.03) 0px 0px 0px 1px;
}
.form-active .form-control:invalid {
border-color: red;
}
.row > * {
padding-right: 1rem;
padding-left: 1rem;
}
form .row {
margin-left: -0.6rem;
margin-right: -0.6rem;
}
form .row [class*=col] {
padding-left: 0.6rem;
padding-right: 0.6rem;
}
form .mbr-section-btn {
padding-left: 0.6rem;
padding-right: 0.6rem;
}
form .form-check-input {
margin-top: 0.5;
}
textarea.form-control {
line-height: 1.5rem !important;
}
.form-group {
margin-bottom: 1.2rem;
}
.form-control,
form .btn {
min-height: 48px;
}
.gdpr-block label span.textGDPR input[name=gdpr] {
top: 7px;
}
.form-control:focus {
box-shadow: none;
}
:focus {
outline: none;
}
.mbr-overlay {
background-color: #000;
bottom: 0;
left: 0;
opacity: 0.5;
position: absolute;
right: 0;
top: 0;
z-index: 0;
pointer-events: none;
}
blockquote {
font-style: italic;
padding: 3rem;
font-size: 1.09rem;
position: relative;
border-left: 3px solid;
}
ul,
ol,
pre,
blockquote {
margin-bottom: 2.3125rem;
}
.mt-4 {
margin-top: 2rem !important;
}
.mb-4 {
margin-bottom: 2rem !important;
}
.container,
.container-fluid {
padding-left: 16px;
padding-right: 16px;
}
.row {
margin-left: -16px;
margin-right: -16px;
}
.row > [class*=col] {
padding-left: 16px;
padding-right: 16px;
}
@media (min-width: 992px) {
.container-fluid {
padding-left: 32px;
padding-right: 32px;
}
}
@media (max-width: 991px) {
.mbr-container {
padding-left: 16px;
padding-right: 16px;
}
}
.app-video-wrapper > img {
opacity: 1;
}
.app-video-wrapper {
background: transparent;
}
.item {
position: relative;
}
.dropdown-menu .dropdown-menu {
left: 100%;
}
.dropdown-item + .dropdown-menu {
display: none;
}
.dropdown-item:hover + .dropdown-menu,
.dropdown-menu:hover {
display: block;
}
@media (min-aspect-ratio: 16/9) {
.mbr-video-foreground {
height: 300% !important;
top: -100% !important;
}
}
@media (max-aspect-ratio: 16/9) {
.mbr-video-foreground {
width: 300% !important;
left: -100% !important;
}
}.engine {
position: absolute;
text-indent: -2400px;
text-align: center;
padding: 0;
top: 0;
left: -2400px;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,70 @@
/*
yt-player. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.makeIterator=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):$jscomp.arrayIterator(a)};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
$jscomp.objectCreate=$jscomp.ASSUME_ES5||"function"==typeof Object.create?Object.create:function(a){var b=function(){};b.prototype=a;return new b};$jscomp.underscoreProtoCanBeSet=function(){var a={a:!0},b={};try{return b.__proto__=a,b.a}catch(c){}return!1};$jscomp.setPrototypeOf="function"==typeof Object.setPrototypeOf?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null;
$jscomp.inherits=function(a,b){a.prototype=$jscomp.objectCreate(b.prototype);a.prototype.constructor=a;if($jscomp.setPrototypeOf){var c=$jscomp.setPrototypeOf;c(a,b)}else for(c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.superClass_=b.prototype};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};$jscomp.polyfill=function(a,b,c,d){if(b){c=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in c||(c[e]={});c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};$jscomp.FORCE_POLYFILL_PROMISE=!1;
$jscomp.polyfill("Promise",function(a){function b(){this.batch_=null}function c(a){return a instanceof e?a:new e(function(b,c){b(a)})}if(a&&!$jscomp.FORCE_POLYFILL_PROMISE)return a;b.prototype.asyncExecute=function(a){if(null==this.batch_){this.batch_=[];var b=this;this.asyncExecuteFunction(function(){b.executeBatch_()})}this.batch_.push(a)};var d=$jscomp.global.setTimeout;b.prototype.asyncExecuteFunction=function(a){d(a,0)};b.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var a=
this.batch_;this.batch_=[];for(var b=0;b<a.length;++b){var c=a[b];a[b]=null;try{c()}catch(l){this.asyncThrow_(l)}}}this.batch_=null};b.prototype.asyncThrow_=function(a){this.asyncExecuteFunction(function(){throw a;})};var e=function(a){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var b=this.createResolveAndReject_();try{a(b.resolve,b.reject)}catch(h){b.reject(h)}};e.prototype.createResolveAndReject_=function(){function a(a){return function(d){c||(c=!0,a.call(b,d))}}var b=this,c=!1;
return{resolve:a(this.resolveTo_),reject:a(this.reject_)}};e.prototype.resolveTo_=function(a){if(a===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(a instanceof e)this.settleSameAsPromise_(a);else{a:switch(typeof a){case "object":var b=null!=a;break a;case "function":b=!0;break a;default:b=!1}b?this.resolveToNonPromiseObj_(a):this.fulfill_(a)}};e.prototype.resolveToNonPromiseObj_=function(a){var b=void 0;try{b=a.then}catch(h){this.reject_(h);return}"function"==typeof b?
this.settleSameAsThenable_(b,a):this.fulfill_(a)};e.prototype.reject_=function(a){this.settle_(2,a)};e.prototype.fulfill_=function(a){this.settle_(1,a)};e.prototype.settle_=function(a,b){if(0!=this.state_)throw Error("Cannot settle("+a+", "+b+"): Promise already settled in state"+this.state_);this.state_=a;this.result_=b;this.executeOnSettledCallbacks_()};e.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var a=0;a<this.onSettledCallbacks_.length;++a)f.asyncExecute(this.onSettledCallbacks_[a]);
this.onSettledCallbacks_=null}};var f=new b;e.prototype.settleSameAsPromise_=function(a){var b=this.createResolveAndReject_();a.callWhenSettled_(b.resolve,b.reject)};e.prototype.settleSameAsThenable_=function(a,b){var c=this.createResolveAndReject_();try{a.call(b,c.resolve,c.reject)}catch(l){c.reject(l)}};e.prototype.then=function(a,b){function c(a,b){return"function"==typeof a?function(b){try{d(a(b))}catch(m){f(m)}}:b}var d,f,g=new e(function(a,b){d=a;f=b});this.callWhenSettled_(c(a,d),c(b,f));return g};
e.prototype.catch=function(a){return this.then(void 0,a)};e.prototype.callWhenSettled_=function(a,b){function c(){switch(d.state_){case 1:a(d.result_);break;case 2:b(d.result_);break;default:throw Error("Unexpected state: "+d.state_);}}var d=this;null==this.onSettledCallbacks_?f.asyncExecute(c):this.onSettledCallbacks_.push(c)};e.resolve=c;e.reject=function(a){return new e(function(b,c){c(a)})};e.race=function(a){return new e(function(b,d){for(var e=$jscomp.makeIterator(a),f=e.next();!f.done;f=e.next())c(f.value).callWhenSettled_(b,
d)})};e.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?c([]):new e(function(a,e){function f(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,c(d.value).callWhenSettled_(f(g.length-1),e),d=b.next();while(!d.done)})};return e},"es6","es3");$jscomp.owns=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};
$jscomp.polyfill("Object.entries",function(a){return a?a:function(a){var b=[],d;for(d in a)$jscomp.owns(a,d)&&b.push([d,a[d]]);return b}},"es8","es3");$jscomp.assign="function"==typeof Object.assign?Object.assign:function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)$jscomp.owns(d,e)&&(a[e]=d[e])}return a};$jscomp.polyfill("Object.assign",function(a){return a||$jscomp.assign},"es6","es3");
$jscomp.findInternal=function(a,b,c){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(b.call(c,f,e,a))return{i:e,v:f}}return{i:-1,v:void 0}};$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,c){return $jscomp.findInternal(this,a,c).v}},"es6","es3");$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};
$jscomp.SymbolClass=function(a,b){this.$jscomp$symbol$id_=a;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:b})};$jscomp.SymbolClass.prototype.toString=function(){return this.$jscomp$symbol$id_};$jscomp.Symbol=function(){function a(c){if(this instanceof a)throw new TypeError("Symbol is not a constructor");return new $jscomp.SymbolClass($jscomp.SYMBOL_PREFIX+(c||"")+"_"+b++,c)}var b=0;return a}();
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("Symbol.iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}});$jscomp.initSymbolIterator=function(){}};
$jscomp.initSymbolAsyncIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.asyncIterator;a||(a=$jscomp.global.Symbol.asyncIterator=$jscomp.global.Symbol("Symbol.asyncIterator"));$jscomp.initSymbolAsyncIterator=function(){}};$jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[$jscomp.global.Symbol.iterator]=function(){return this};return a};
$jscomp.iteratorFromArray=function(a,b){$jscomp.initSymbolIterator();a instanceof String&&(a+="");var c=0,d={next:function(){if(c<a.length){var e=c++;return{value:b(e,a[e]),done:!1}}d.next=function(){return{done:!0,value:void 0}};return d.next()}};d[Symbol.iterator]=function(){return d};return d};$jscomp.polyfill("Array.prototype.entries",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a,c){return[a,c]})}},"es6","es3");
$jscomp.polyfill("Array.from",function(a){return a?a:function(a,c,d){c=null!=c?c:function(a){return a};var b=[],f="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];if("function"==typeof f){a=f.call(a);for(var g=0;!(f=a.next()).done;)b.push(c.call(d,f.value,g++))}else for(f=a.length,g=0;g<f;g++)b.push(c.call(d,a[g],g));return b}},"es6","es3");$jscomp.polyfill("Object.is",function(a){return a?a:function(a,c){return a===c?0!==a||1/a===1/c:a!==a&&c!==c}},"es6","es3");
$jscomp.polyfill("Array.prototype.includes",function(a){return a?a:function(a,c){var b=this;b instanceof String&&(b=String(b));var e=b.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var f=b[c];if(f===a||Object.is(f,a))return!0}return!1}},"es7","es3");
$jscomp.checkStringArgs=function(a,b,c){if(null==a)throw new TypeError("The 'this' value for String.prototype."+c+" must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype."+c+" must not be a regular expression");return a+""};$jscomp.polyfill("String.prototype.includes",function(a){return a?a:function(a,c){return-1!==$jscomp.checkStringArgs(this,a,"includes").indexOf(a,c||0)}},"es6","es3");var EventEmitter=function(){this.events={}};
EventEmitter.prototype.on=function(a,b){"object"!==typeof this.events[a]&&(this.events[a]=[]);this.events[a].push(b)};EventEmitter.prototype.removeListener=function(a,b){"object"===typeof this.events[a]&&(b=this.indexOf(this.events[a],b),-1<b&&this.events[a].splice(b,1))};EventEmitter.prototype.emit=function(a){var b,c=[].slice.call(arguments,1);if("object"===typeof this.events[a]){var d=this.events[a].slice();var e=d.length;for(b=0;b<e;b++)d[b].apply(this,c)}};
EventEmitter.prototype.once=function(a,b){this.on(a,function d(){this.removeListener(a,d);b.apply(this,arguments)})};
var loadScript=function(a,b,c){return new Promise(function(d,e){var f=document.createElement("script");f.async=!0;f.src=a;for(var g=$jscomp.makeIterator(Object.entries(b||{})),k=g.next();!k.done;k=g.next()){var h=$jscomp.makeIterator(k.value);k=h.next().value;h=h.next().value;f.setAttribute(k,h)}f.onload=function(){f.onerror=f.onload=null;d(f)};f.onerror=function(){f.onerror=f.onload=null;e(Error("Failed to load "+a))};(c||document.head||document.getElementsByTagName("head")[0]).appendChild(f)})},
YOUTUBE_IFRAME_API_SRC="https://www.youtube.com/iframe_api",YOUTUBE_STATES={"-1":"unstarted",0:"ended",1:"playing",2:"paused",3:"buffering",5:"cued"},YOUTUBE_ERROR={INVALID_PARAM:2,HTML5_ERROR:5,NOT_FOUND:100,UNPLAYABLE_1:101,UNPLAYABLE_2:150},loadIframeAPICallbacks=[],C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0=function(a,b){EventEmitter.call(this);var c=this;a="string"===typeof a?
document.querySelector(a):a;this._id=a.id?a.id:a.id="ytplayer-"+Math.random().toString(16).slice(2,8);this._opts=Object.assign({width:640,height:360,autoplay:!1,captions:void 0,controls:!0,keyboard:!0,fullscreen:!0,annotations:!0,modestBranding:!1,related:!0,timeupdateFrequency:1E3,playsInline:!0,start:0},b);this.videoId=null;this.destroyed=!1;this._api=null;this._autoplay=!1;this._player=null;this._ready=!1;this._queue=[];this.replayInterval=[];this._interval=null;this._startInterval=this._startInterval.bind(this);
this._stopInterval=this._stopInterval.bind(this);this.on("playing",this._startInterval);this.on("unstarted",this._stopInterval);this.on("ended",this._stopInterval);this.on("paused",this._stopInterval);this.on("buffering",this._stopInterval);this._loadIframeAPI(function(a,b){if(a)return c._destroy(Error("YouTube Iframe API failed to load"));c._api=b;c.videoId&&c.load(c.videoId,c._autoplay,c._start)})};
$jscomp.inherits(C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0,EventEmitter);C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.indexOf=function(a,b){for(var c=0,d=a.length,e=-1,f=!1;c<d&&!f;)a[c]===b&&(e=c,f=!0),c++;return e};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.load=function(a,b,c){b=void 0===b?!1:b;c=void 0===c?0:c;this.destroyed||(this._startOptimizeDisplayEvent(),this._optimizeDisplayHandler("center, center"),this.videoId=a,this._autoplay=b,this._start=c,this._api&&(this._player?this._ready&&(b?this._player.loadVideoById(a,c):this._player.cueVideoById(a,c)):this._createPlayer(a)))};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.play=function(){this._ready?this._player.playVideo():this._queueCommand("play")};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.replayFrom=function(a){var b=this;!this.replayInterval.find(function(a){return a.iframeParent===b._player.i.parentNode})&&a&&this.replayInterval.push({iframeParent:this._player.i.parentNode,interval:setInterval(function(){if(b._player.getCurrentTime()>=b._player.getDuration()-Number(a)){b.seek(0);for(var c=$jscomp.makeIterator(b.replayInterval.entries()),
d=c.next();!d.done;d=c.next()){d=$jscomp.makeIterator(d.value);var e=d.next().value;d.next();Object.hasOwnProperty.call(b.replayInterval,e)&&(clearInterval(b.replayInterval[e].interval),b.replayInterval.splice(e,1))}}},1E3*Number(a))})};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.pause=function(){this._ready?this._player.pauseVideo():this._queueCommand("pause")};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.stop=function(){this._ready?this._player.stopVideo():this._queueCommand("stop")};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.seek=function(a){this._ready?this._player.seekTo(a,!0):this._queueCommand("seek",a)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._optimizeDisplayHandler=function(a){if(this._player){var b=this._player.i;a=a.split(",");if(b){var c;if(c=b.parentElement){var d=window.getComputedStyle(c);var e=c.clientHeight+parseFloat(d.marginTop,10)+parseFloat(d.marginBottom,10)+parseFloat(d.borderTopWidth,10)+parseFloat(d.borderBottomWidth,10);c=c.clientWidth+parseFloat(d.marginLeft,
10)+parseFloat(d.marginRight,10)+parseFloat(d.borderLeftWidth,10)+parseFloat(d.borderRightWidth,10);e+=80;b.style.width=c+"px";b.style.height=Math.ceil(parseFloat(b.style.width,10)/1.7)+"px";b.style.marginTop=Math.ceil(-((parseFloat(b.style.height,10)-e)/2))+"px";b.style.marginLeft=0;if(d=parseFloat(b.style.height,10)<e)b.style.height=e+"px",b.style.width=Math.ceil(1.7*parseFloat(b.style.height,10))+"px",b.style.marginTop=0,b.style.marginLeft=Math.ceil(-((parseFloat(b.style.width,10)-c)/2))+"px";
for(var f in a)if(a.hasOwnProperty(f))switch(a[f].replace(/ /g,"")){case "top":b.style.marginTop=d?-((parseFloat(b.style.height,10)-e)/2)+"px":0;break;case "bottom":b.style.marginTop=d?0:-(parseFloat(b.style.height,10)-e)+"px";break;case "left":b.style.marginLeft=0;break;case "right":b.style.marginLeft=d?-(parseFloat(b.style.width,10)-c):"0px";break;default:parseFloat(b.style.width,10)>c&&(b.style.marginLeft=-((parseFloat(b.style.width,10)-c)/2)+"px")}}}}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.stopResize=function(){window.removeEventListener("resize",this._resizeListener);this._resizeListener=null};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.stopReplay=function(a){for(var b=$jscomp.makeIterator(this.replayInterval.entries()),c=b.next();!c.done;c=b.next()){c=$jscomp.makeIterator(c.value);var d=c.next().value;c.next();Object.hasOwnProperty.call(this.replayInterval,d)&&a===this.replayInterval[d].iframeParent&&(clearInterval(this.replayInterval[d].interval),this.replayInterval.splice(d,
1))}};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.setVolume=function(a){this._ready?this._player.setVolume(a):this._queueCommand("setVolume",a)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.loadPlaylist=function(){this._ready?this._player.loadPlaylist(this.videoId):this._queueCommand("loadPlaylist",this.videoId)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.setLoop=function(a){this._ready?this._player.setLoop(a):this._queueCommand("setLoop",a)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getVolume=function(){return this._ready&&this._player.getVolume()||0};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.mute=function(){this._ready?this._player.mute():this._queueCommand("mute")};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.unMute=function(){this._ready?this._player.unMute():this._queueCommand("unMute")};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.isMuted=function(){return this._ready&&this._player.isMuted()||!1};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.setSize=function(a,b){this._ready?this._player.setSize(a,b):this._queueCommand("setSize",a,b)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.setPlaybackRate=function(a){this._ready?this._player.setPlaybackRate(a):this._queueCommand("setPlaybackRate",a)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.setPlaybackQuality=function(a){this._ready?this._player.setPlaybackQuality(a):this._queueCommand("setPlaybackQuality",a)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getPlaybackRate=function(){return this._ready&&this._player.getPlaybackRate()||1};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getAvailablePlaybackRates=function(){return this._ready&&this._player.getAvailablePlaybackRates()||[1]};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getDuration=function(){return this._ready&&this._player.getDuration()||0};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getProgress=function(){return this._ready&&this._player.getVideoLoadedFraction()||0};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getState=function(){return this._ready&&YOUTUBE_STATES[this._player.getPlayerState()]||"unstarted"};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.getCurrentTime=function(){return this._ready&&this._player.getCurrentTime()||0};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype.destroy=function(){this._destroy()};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._destroy=function(a){this.destroyed||(this.destroyed=!0,this._player&&(this._player.stopVideo&&this._player.stopVideo(),this._player.destroy()),this._player=this._api=this._opts=this._id=this.videoId=null,this._ready=!1,this._queue=null,this._stopInterval(),this.removeListener("playing",this._startInterval),this.removeListener("paused",
this._stopInterval),this.removeListener("buffering",this._stopInterval),this.removeListener("unstarted",this._stopInterval),this.removeListener("ended",this._stopInterval),a&&this.emit("error",a))};C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._queueCommand=function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];this.destroyed||this._queue.push([a,c])};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._flushQueue=function(){for(;this._queue.length;){var a=this._queue.shift();this[a[0]].apply(this,a[1])}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._loadIframeAPI=function(a){if(window.YT&&"function"===typeof window.YT.Player)return a(null,window.YT);loadIframeAPICallbacks.push(a);Array.from(document.getElementsByTagName("script")).some(function(a){return a.src===YOUTUBE_IFRAME_API_SRC})||loadScript(YOUTUBE_IFRAME_API_SRC).catch(function(a){for(;loadIframeAPICallbacks.length;)loadIframeAPICallbacks.shift()(a)});
var b=window.onYouTubeIframeAPIReady;window.onYouTubeIframeAPIReady=function(){for("function"===typeof b&&b();loadIframeAPICallbacks.length;)loadIframeAPICallbacks.shift()(null,window.YT)}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._createPlayer=function(a){var b=this;if(!this.destroyed){var c=this._opts;this._player=new this._api.Player(this._id,{width:c.width,height:c.height,videoId:a,host:c.host,playerVars:{autoplay:c.autoplay?1:0,mute:c.mute?1:0,hl:null!=c.captions&&!1!==c.captions?c.captions:void 0,cc_lang_pref:null!=c.captions&&!1!==c.captions?c.captions:
void 0,controls:c.controls?2:0,enablejsapi:1,allowfullscreen:!0,iv_load_policy:c.annotations?1:3,modestbranding:c.modestBranding?1:0,origin:"*",rel:c.related?1:0,mode:"transparent",showinfo:0,html5:1,version:3,playerapiid:"iframe_YTP_1624972482514"},events:{onReady:function(){return b._onReady(a)},onStateChange:function(a){return b._onStateChange(a)},onPlaybackQualityChange:function(a){return b._onPlaybackQualityChange(a)},onPlaybackRateChange:function(a){return b._onPlaybackRateChange(a)},onError:function(a){return b._onError(a)}}})}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onReady=function(a){this.destroyed||(this._ready=!0,this.load(this.videoId,this._autoplay,this._start),this._flushQueue())};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onStateChange=function(a){if(!this.destroyed){var b=YOUTUBE_STATES[a.data];if(b)["paused","buffering","ended"].includes(b)&&this._onTimeupdate(),this.emit(b),["unstarted","playing","cued"].includes(b)&&this._onTimeupdate();else throw Error("Unrecognized state change: "+a);}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onPlaybackQualityChange=function(a){this.destroyed||this.emit("playbackQualityChange",a.data)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onPlaybackRateChange=function(a){this.destroyed||this.emit("playbackRateChange",a.data)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onError=function(a){if(!this.destroyed&&(a=a.data,a!==YOUTUBE_ERROR.HTML5_ERROR)){if(a===YOUTUBE_ERROR.UNPLAYABLE_1||a===YOUTUBE_ERROR.UNPLAYABLE_2||a===YOUTUBE_ERROR.NOT_FOUND||a===YOUTUBE_ERROR.INVALID_PARAM)return this.emit("unplayable",this.videoId);this._destroy(Error("YouTube Player Error. Unknown error code: "+a))}};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._startOptimizeDisplayEvent=function(){var a=this;this._resizeListener||(this._resizeListener=function(){return a._optimizeDisplayHandler("center, center")},window.addEventListener("resize",this._resizeListener))};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._onTimeupdate=function(){this.emit("timeupdate",this.getCurrentTime())};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._startInterval=function(){var a=this;this._interval=setInterval(function(){return a._onTimeupdate()},this._opts.timeupdateFrequency)};
C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0.prototype._stopInterval=function(){clearInterval(this._interval);this._interval=null};YouTubePlayer=C_$hudson$workspace$Mobirise_Windows_release_web$Release$release$win_ia32_unpacked$resources$_app_asar$web$app$themes$startm5$plugins$ytplayer$index$classdecl$var0;

View File

@ -17,8 +17,8 @@
<% } %>
<div class="input-box">
<span class="details">Username</span>
<input type="text" name="usernameOrEmail" placeholder="Enter your email" required>
<span class="details">Username or Email</span>
<input type="text" name="usernameOrEmail" placeholder="Enter your Username or Email" required>
</div>
<div class="button">

View File

@ -20,7 +20,8 @@
<nav>
<a href="/inusers">In-House Users</a>
<a href="#">Users</a>
<a href="#">Sensors</a>
<a href="/sensors">Sensors</a>
<a href="/locations">Locations</a>
<a href="/logout">Logout</a>
</nav>

222
Sean/views/index.ejs Normal file
View File

@ -0,0 +1,222 @@
<!DOCTYPE html>
<html >
<head>
<!-- Site made with Mobirise Website Builder v5.9.13, https://mobirise.com -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="generator" content="Mobirise v5.9.13, mobirise.com">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="description" content="">
<title>Home</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap-grid.min.css">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap-reboot.min.css">
<link rel="stylesheet" href="assets/parallax/jarallax.css">
<link rel="stylesheet" href="assets/animatecss/animate.css">
<link rel="stylesheet" href="assets/dropdown/css/style.css">
<link rel="stylesheet" href="assets/socicon/css/styles.css">
<link rel="stylesheet" href="assets/theme/css/style.css">
<link rel="preload" href="https://fonts.googleapis.com/css?family=Inter+Tight:100,200,300,400,500,600,700,800,900,100i,200i,300i,400i,500i,600i,700i,800i,900i&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter+Tight:100,200,300,400,500,600,700,800,900,100i,200i,300i,400i,500i,600i,700i,800i,900i&display=swap"></noscript>
<link rel="preload" as="style" href="assets/mobirise/css/mbr-additional.css?v=b1g2Yh"><link rel="stylesheet" href="assets/mobirise/css/mbr-additional.css?v=b1g2Yh" type="text/css">
</head>
<body>
<section data-bs-version="5.1" class="menu menu5 cid-u2mrL2wdLO" once="menu" id="menu05-1i">
<nav class="navbar navbar-dropdown navbar-fixed-top navbar-expand-lg">
<div class="container">
<div class="navbar-brand">
<span class="navbar-caption-wrap"><a class="navbar-caption text-black display-4" href="https://mobiri.se">EcoSaver Management</a></span>
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-bs-toggle="collapse" data-target="#navbarSupportedContent" data-bs-target="#navbarSupportedContent" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<div class="hamburger">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav nav-dropdown" data-app-modern-menu="true">
<li class="nav-item">
<a class="nav-link link text-black display-4" href="index.html#header01-7">About</a>
</li>
<li class="nav-item">
<a class="nav-link link text-black display-4" href="index.html#features04-w" aria-expanded="false">Services</a>
</li>
<li class="nav-item">
<a class="nav-link link text-black display-4" href="index.html#contacts02-9">Contacts</a>
</li>
</ul>
<div class="navbar-buttons mbr-section-btn"><a class="btn btn-primary display-4" href="https://mobiri.se">Login</a></div>
</div>
</div>
</nav>
</section>
<section data-bs-version="5.1" class="header5 cid-tJS6uM4N87" id="header05-1">
<div class="topbg"></div>
<div class="align-center container">
<div class="row justify-content-center">
<div class="col-md-12 col-lg-9">
<h1 class="mbr-section-title mbr-fonts-style mb-4 display-1"><strong>WELCOME TO ECOSAVER MANAGEMENT</strong></h1>
<p class="mbr-text mbr-fonts-style mb-4 display-7">Here at ECOSAVER MANAGEMENT, we are tasked to secure and protect ECOSAVER to provide<br>consumers with the best experience</p>
</div>
</div>
<div class="row mt-5 justify-content-center">
<div class="col-12 col-lg-12">
<img src="assets/images/ecosostenibilita-1000x500.jpeg" alt="Mobirise Website Builder" title="">
</div>
</div>
</div>
</section>
<section data-bs-version="5.1" class="features4 cid-tMlEXTHLbS" id="features04-w">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-12 content-head">
<div class="mbr-section-head mb-5">
<h4 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2"><strong>Our Services</strong></h4>
<h5 class="mbr-section-subtitle mbr-fonts-style align-center mb-0 mt-4 display-7">At EcoSaver, we are committed to empowering individuals and businesses to embrace a greener, more sustainable lifestyle. We are designed to make eco-friendly choices accessible and effortless, ensuring a positive impact on both the environment and your bottom line.</h5>
</div>
</div>
</div>
<div class="row">
<div class="item features-image col-12 col-md-6 col-lg-6 active">
<div class="item-wrapper">
<div class="item-img">
<img src="assets/images/air-pollution-1679x944.jpg" alt="Mobirise Website Builder" data-slide-to="1" data-bs-slide-to="1">
</div>
<div class="item-content">
<h5 class="item-title mbr-fonts-style display-5"><strong>Ecosaver</strong></h5>
<p class="mbr-text mbr-fonts-style display-7">EcoSaver is proud to offer a cutting-edge Air Quality Service, providing real-time air quality data for Singapore. It allows anyone to access crucial information about the air they breathe, empowering individuals and communities to make informed decisions for their well-being.</p>
<div class="mbr-section-btn item-footer"><a href="" class="btn item-btn btn-primary display-7">Learn more</a></div>
</div>
</div>
</div><div class="item features-image col-12 col-md-6 col-lg-6">
<div class="item-wrapper">
<div class="item-img">
<img src="assets/images/the-expansion-of-cloud-applications-has-added-to...-766x476.png" alt="Mobirise Website Builder" data-slide-to="0" data-bs-slide-to="0">
</div>
<div class="item-content">
<h5 class="item-title mbr-fonts-style display-5"><strong>Ecosaver Management</strong></h5>
<p class="mbr-text mbr-fonts-style display-7">
EcoSaver Management is unwaveringly dedicated to delivering paramount security within the EcoSaver system. Our paramount objective is to establish and maintain a secure environment, ensuring the safety of every individual who engages with the EcoSaver platform.</p>
<div class="mbr-section-btn item-footer"><a href="" class="btn item-btn btn-primary display-7">Learn more</a></div>
</div>
</div>
</div>
</div>
</div>
</section>
<section data-bs-version="5.1" class="header1 cid-tJS9vXDdRK" id="header01-7">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-12 col-lg-7 image-wrapper">
<img class="w-100" src="assets/images/gallery01.jpg" alt="Mobirise Website Builder">
</div>
<div class="col-12 col-lg col-md-12">
<div class="text-wrapper align-left">
<h1 class="mbr-section-title mbr-fonts-style mb-4 display-2"><strong>About us</strong></h1>
<p class="mbr-text mbr-fonts-style mb-4 display-7">
EcoSaver is made by 4 student of Temasek Polytechnic studying cyber security and digital forensics for their major project</p>
</div>
</div>
</div>
</div>
</section>
<section data-bs-version="5.1" class="contacts2 map1 cid-tLdYHD757A mbr-parallax-background" id="contacts02-9">
<div class="mbr-overlay" style="opacity: 0.5; background-color: rgb(0, 0, 0);"></div>
<div class="container-fluid">
<div class="mbr-section-head mb-5">
<h3 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2">
<strong>Contacts</strong>
</h3>
</div>
<div class="row justify-content-center mt-4">
<div class="card col-12 col-md-5">
<div class="card-wrapper">
<div class="text-wrapper">
<h5 class="cardTitle mbr-fonts-style mb-2 display-5">
<strong>Get in touch</strong></h5>
<ul class="list mbr-fonts-style display-7">
<li class="mbr-text item-wrap"><span style="font-size: 1.4rem;">Phone: 6666 6666</span></li>
<li class="mbr-text item-wrap">Email: ecosaverx@gmail.com</li><li class="mbr-text item-wrap"><br></li>
<li class="mbr-text item-wrap">Address: </li><li class="mbr-text item-wrap">21 Tampines Ave 1, Singapore 529757</li><li class="mbr-text item-wrap"><span style="font-size: 1.4rem;">Working hours:</span><br></li><li class="mbr-text item-wrap">8:30AM - 6:00PM</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<section data-bs-version="5.1" class="footer1 programm5 cid-tJS9NNcTLZ" once="footers" id="footer03-8">
<div class="container">
<div class="row">
<div class="row-links mb-4">
<ul class="header-menu">
<li class="header-menu-item mbr-fonts-style display-5"><a href="index.html#header01-7" class="text-danger">About</a></li><li class="header-menu-item mbr-fonts-style display-5"><a href="index.html#features04-w" class="text-danger text-primary">Services</a></li><li class="header-menu-item mbr-fonts-style display-5"><a href="index.html#contacts02-9" class="text-danger">Contacts</a></li></ul>
</div>
<div class="col-12">
</div>
<div class="col-12 mt-5">
<p class="mbr-fonts-style copyright display-7">
© Copyright 2030 Ecosaver - All Rights Reserved
</p>
</div>
</div>
</div>
</section><section class="display-7" style="padding: 0;align-items: center;justify-content: center;flex-wrap: wrap; align-content: center;display: flex;position: relative;height: 4rem;"><a href="https://mobiri.se/3136804" style="flex: 1 1;height: 4rem;position: absolute;width: 100%;z-index: 1;"><img alt="" style="height: 4rem;" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></a><p style="margin: 0;text-align: center;" class="display-7">&#8204;</p><a style="z-index:1" href="https://mobirise.com/builder/ai-website-builder.html">AI Website Builder</a></section><script src="assets/bootstrap/js/bootstrap.bundle.min.js"></script> <script src="assets/parallax/jarallax.js"></script> <script src="assets/smoothscroll/smooth-scroll.js"></script> <script src="assets/ytplayer/index.js"></script> <script src="assets/dropdown/js/navbar-dropdown.js"></script> <script src="assets/theme/js/script.js"></script>
<input name="animation" type="hidden">
</body>
</html>

View File

@ -173,21 +173,19 @@
</div>
<script nonce="<%= nonce %>">
<script >
const allUsers = <%- JSON.stringify(allUsers) %>;
const currentUsername = '<%= currentUsername %>';
const nonce = "<%= nonce %>"
console.log('Nonce:', nonce);
</script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js" nonce="<%= nonce %>"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.bundle.min.js" nonce="<%= nonce %>" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.4/xlsx.full.min.js" nonce="<%= nonce %>"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js" nonce="<%= nonce %>"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.2.1/exceljs.min.js" nonce="<%= nonce %>"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" nonce="<%= nonce %>"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.js" nonce="<%= nonce %>"></script>
<script src="inusers.js" nonce="<%= nonce %>"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.4/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.2.1/exceljs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.js"></script>
<script src="inusers.js"></script>
</body>

180
Sean/views/location.js Normal file
View File

@ -0,0 +1,180 @@
$(document).ready(function () {
$('#allLocationLink').on('click', function () {
$('#locationContainer').show();
$('#createLocationForm').hide();
$('#updateLocationForm').hide();
$('#deleteLocationForm').hide();
});
$('#addLocationLink').on('click', function () {
$('#locationContainer').hide();
$('#createLocationForm').show();
$('#updateLocationForm').hide();
$('#deleteLocationForm').hide();
});
$('#updateLocationLink').on('click', function () {
$('#locationContainer').hide();
$('#createLocationForm').hide();
$('#updateLocationForm').show();
$('#deleteLocationForm').hide();
});
$('#deleteLocationLink').on('click', function () {
$('#locationContainer').hide();
$('#createLocationForm').hide();
$('#updateLocationForm').show();
$('#deleteLocationForm').show();
});
});
let locationArray = [];
function populateTableAndArray(data) {
const tableBody = document.getElementById("locationTableBody");
// Clear existing rows and array
tableBody.innerHTML = "";
locationArray.length = 0;
// Loop through the data and create table rows
data.forEach(location => {
const row = document.createElement("tr");
row.innerHTML = `
<td>${location.id}</td>
<td>${location.location}</td>
<td>${location.description}</td>
`;
tableBody.appendChild(row);
// Push location data to the array
locationArray.push(location);
});
}
populateTableAndArray(locationsData);
populateLocationDropdown();
$('#locationForm').on('submit', function (e) {
e.preventDefault();
const location= $('#location').val();
const user = req.session.jobTitle
const description= $('#description').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('/location/new', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: location,
added_by: user,
description: description,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Location added successfully. Message: ${data.message}`);
alert('Location added successfully!');
resetFormFields();
})
.catch(error => {
console.error('Location not added successfully', error);
// Handle error as needed
});
});
function populateLocationDropdown() {
// Clear existing options
$('#locationDropdown').empty();
// Populate the dropdown with options from locationArray
locationArray.forEach(location => {
$('#locationDropdown').append(`<option value="${location.id}">${location.name}</option>`);
});
}
$('#updateForm').on('submit', function (e) {
e.preventDefault();
const selectedLocationId = $('#locationDropdown').val();
const location= $('#location').val();
const user = req.session.jobTitle
const description=$('#description').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('/location/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id:selectedLocationId,
name: location,
added_by: user,
description: description,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Location uppdated successfully. Message: ${data.message}`);
alert('Location updated successfully!');
resetFormFields();
})
.catch(error => {
console.error('Location not updated successfully', error);
// Handle error as needed
});
});
$('#deleteForm').on('submit', function (e) {
e.preventDefault();
const selectedLocationId = $('#locationDropdown').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('/location/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id:selectedLocationId,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Location deleted successfully. Message: ${data.message}`);
alert('Location deleted successfully!');
resetFormFields();
})
.catch(error => {
console.error('Location not deleted successfully', error);
// Handle error as needed
});
});

120
Sean/views/locations.ejs Normal file
View File

@ -0,0 +1,120 @@
<!-- views/location.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap">
</head>
<body>
<header>
<h1>ECOSAVER MANAGEMENT</h1>
</header>
<nav>
<a href="#" id="allLocationLink">All Locations</a>
<a href="#" id="addLocationLink">Add Locations</a>
<a href="#" id="updateLocationLink">Update Locations</a>
<a href="#">Delete Locations</a>
<a href="/home" id="homeLink">Home</a>
</nav>
<main>
<h2>Welcome to the Location Page</h2>
</main>
<div id="locationContainer">
<table class="nice-table">
<thead>
<tr>
<th>ID</th>
<th>Location</th>
<th>Descriptions</th>
</tr>
</thead>
<tbody id="locationTableBody"></tbody>
</table>
</div>
<div id="createLocationForm" class="location-creation-container custom-location-form" style="display: none;">
<h3>Add Location</h3>
<div class="content">
<form action="/location/new" id="locationForm" method="post">
<div class="Location-details">
<div class="input-box">
<span class="details">Location Name</span>
<input type="text" name="location" id="location" placeholder="Enter Location name" required>
</div>
<div class="input-box">
<span class="details">Description</span>
<input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="submit">
</div>
</form>
</div>
</div>
<div id="updateLocationForm" class="location-update-container" style="display: none;">
<h3>Update Location</h3>
<div class="content">
<form action="/location/update" id="updateForm" method="put">
<div class="Location-details">
<div class="input-box">
<span class="details">Location to Update</span>
<select name="location" id="locationDropdown" required>
</select>
</div>
<div class="input-box">
<span class="details">Location Name</span>
<input type="text" name="location" id="location" placeholder="Enter Location name" required>
</div>
<div class="input-box">
<span class="details">Description</span>
<input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="submit">
</div>
</form>
</div>
</div>
<div id="deleteLocationForm" class="location-delete-container" style="display: none;">
<h3>Delete Location</h3>
<div class="content">
<form action="/location/delete" id="deleteForm" method="delete">
<div class="Location-details">
<div class="input-box">
<span class="details">Location to Delete</span>
<select name="location" id="locationDropdown" required>
</select>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="submit">
</div>
</form>
</div>
</div>
<footer>
Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com
</footer>
<script>
const locationsData = <%- JSON.stringify(locationsData) %>;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="location.js"></script>
</body>
</html>

225
Sean/views/sensor.js Normal file
View File

@ -0,0 +1,225 @@
$(document).ready(function () {
$('#allSensorLink').on('click', function () {
$('#sensorContainer').show();
$('#createSensorForm').hide();
$('#additional-text4').hide();
$('#updateSensorForm').hide();
$('#deleteSensorForm').hide();
});
$('#addSensorLink').on('click', function () {
$('#sensorContainer').hide();
$('#createSensorForm').show();
$('#additional-text4').show();
$('#updateSensorForm').hide();
$('#deleteSensorForm').hide();
});
$('#updateSensorLink').on('click', function () {
$('#sensorContainer').hide();
$('#createSensorForm').show();
$('#additional-text4').show();
$('#updateSensorForm').show();
$('#deleteSensorForm').hide();
});
$('#deleteSensorLink').on('click', function () {
$('#sensorContainer').hide();
$('#createSensorForm').show();
$('#additional-text4').show();
$('#updateSensorForm').hide();
$('#deleteSensorForm').show();
});
});
function populateTableAndArray(data, locationsArray) {
const tableBody = document.getElementById("sensorTableBody");
// Clear existing rows and array
tableBody.innerHTML = "";
sensorArray.length = 0;
// Loop through the data and create table rows
data.forEach(sensor => {
const location = locationsArray.find(loc => loc.id === sensor.location);
const row = document.createElement("tr");
row.innerHTML = `
<td>${sensor.id}</td>
<td>${sensor.sensorname}</td>
<td>${sensor.added_by}</td>
<td>${sensor.description}</td>
<td>${location ? location.name : 'Unknown Location'}</td>
`;
tableBody.appendChild(row);
// Push sensor data to the array
sensorArray.push(sensor);
});
}
// Assuming locationsArray is defined elsewhere in your code
populateTableAndArray(sensorData);
console.log(sensorArray);
function populateLocationDropdown() {
const locationDropdown = document.getElementById('locationDropdown');
// Clear existing options
locationDropdown.innerHTML = '';
// Add a default option
const defaultOption = document.createElement('option');
defaultOption.text = 'Select a Location';
defaultOption.value = '';
locationDropdown.add(defaultOption);
// Add locations as options
locationsArray.forEach(location => {
const option = document.createElement('option');
option.text = location.location;
option.value = location.id;
locationDropdown.add(option);
});
}
populateLocationDropdown();
function populateSensorDropdown() {
const sensorDropdown = document.getElementById('sensorDropdown');
// Clear existing options
sensorDropdown.innerHTML = '';
// Add a default option
const defaultOption = document.createElement('option');
defaultOption.text = 'Select a Sensor';
defaultOption.value = '';
sensorDropdown.add(defaultOption);
// Add locations as options
sensorArray.forEach(location => {
const option = document.createElement('option');
option.text = sensor.sensorname;
option.value = sensor.id;
sensorDropdown.add(option);
});
}
populateSensorDropdown();
$('#sensorForm').on('submit', function (e) {
e.preventDefault();
const sensor = $('#sensor').val();
const user = req.session.jobTitle;
const macAddress = $('#macAddress').val();
const description = $('#description').val();
const location = $('#location').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('sensor/new', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
sensorname: sensor,
added_by: user,
mac_address: macAddress,
description: description,
location: location,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Sensor added successfully. Message: ${data.message}`);
alert('Sensor added successfully!');
resetFormFields();
})
.catch(error => {
console.error('Location not added successfully', error);
// Handle error as needed
});
});
$('#updatesensorForm').on('submit', function (e) {
e.preventDefault();
const id = $('#sensorDropdown').val();
const sensorname = $('#sensorname').val();
const user = req.session.jobTitle;
const macAddress = $('#macAddress').val();
const description = $('#description').val();
const location = $('#locationDropdown').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('sensor/update', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: id,
sensorname: sensorname,
added_by: user,
mac_address: macAddress,
description: description,
location: location,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Sensor updated successfully. Message: ${data.message}`);
alert('Sensor updated successfully!');
resetFormFields();
})
.catch(error => {
console.error('Sensor not updated successfully', error);
// Handle error as needed
});
});
$('#deleteForm').on('submit', function (e) {
e.preventDefault();
const selectedSensorId = $('#sensorDropdown').val();
const csrf_token = $('#userForm input[name="csrf_token"]').val();
fetch('/sensor/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id:selectedSensorId,
csrf_token: csrf_token
}),
})
.then(response => {
if (response.ok) {
// Status 201 indicates successful creation
return response.json();
} else {
return response.json().then(data => {
throw new Error(data.message || `HTTP error! Status: ${response.status}`);
});
}
})
.then(data => {
console.log(`Sensor deleted successfully. Message: ${data.message}`);
alert('Sensor deleted successfully!');
resetFormFields();
})
.catch(error => {
console.error('Sensor not deleted successfully', error);
// Handle error as needed
});
});

153
Sean/views/sensors.ejs Normal file
View File

@ -0,0 +1,153 @@
<!-- views/sensor.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap">
</head>
<body>
<header>
<h1>ECOSAVER MANAGEMENT</h1>
</header>
<nav>
<a href="#" id="allSensorLink">All Sensor</a>
<a href="#" id="addSensorLink">Add Sensor</a>
<a href="#" id="updateSensorLink">Update Sensor</a>
<a href="#" id="deleteSensorLink">Delete Sensor</a>
<a href="/home" id="homeLink">Home</a>
</nav>
<main>
<h2>Welcome to the Sensor Page</h2>
</main>
<div id="sensorContainer">
<table class="nice-table">
<thead>
<tr>
<th>ID</th>
<th>Sensor Name</th>
<th>Added By</th>
<th>Mac Address</th>
<th>Description</th>
<th>Location</th>
</tr>
</thead>
<tbody id="sensorTableBody"></tbody>
</table>
</div>
<div id="createSensorForm" class="sensor-creation-container" style="display: none;">
<h3>Add Sensor</h3>
<div class="content">
<form action="/api/v0/sensor/new" id="sensorForm" method="post">
<div class="Sensor-details">
<div class="input-box">
<span class="details">Sensor Name</span>
<input type="text" name="sensor" id="sensor" placeholder="Enter Sensor name" required>
</div>
<div class="input-box">
<span class="details">Mac Address</span>
<input type="text" name="macAddress" id="macAddress" placeholder="Enter the Mac Address" required>
</div>
<div class="input-box">
<span class="details">Description</span>
<input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div>
<div class="input-box">
<span class="details">Location</span>
<select name="location" id="locationDropdown" required>
</select>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="Submit">
</div>
</form>
</div>
</div>
<div id="additional-text4" style="display: none;">
<div class="condition">
<span>Conditions for creating a Sensor:</span>
<ul>
<li class="error">Please Remember to fill all inputs.</li>
<li class="error">Please ensure all inputs are correct before adding</li>
</ul>
</div>
</div>
<div id="updateSensorForm" class="sensor-update-container" style="display: none;">
<h3>Add Location</h3>
<div class="content">
<form action="/sensor/update" id="updateForm" method="put">
<div class="Location-details">
<div class="input-box">
<span class="details">Sensor to Update</span>
<select name="Sensor" id="sensorDropdown" required>
</select>
</div>
<div class="input-box">
<span class="details">Sensor Name</span>
<input type="text" name="sensorname" id="sensorname" placeholder="Enter Sensor name" required>
</div>
<div class="input-box">
<span class="details">Mac Address</span>
<input type="text" name="macAddress" id="macAddress" placeholder="Enter the Mac Address" required>
</div>
<div class="input-box">
<span class="details">Description</span>
<input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div>
</div>
<div class="input-box">
<span class="details">Location</span>
<select name="location" id="locationDropdown" required>
</select>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="submit">
</div>
</form>
</div>
</div>
<div id="deleteSensorForm" class="sensor-delete-container" style="display: none;">
<h3>Delete Location</h3>
<div class="content">
<form action="/sensor/delete" id="deleteForm" method="delete">
<div class="Location-details">
<div class="input-box">
<span class="details">Sensor to Delete</span>
<select name="sensor" id="sensorDropdown" required>
</select>
</div>
</div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button">
<input type="submit" value="submit">
</div>
</form>
</div>
</div>
<footer>
Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com
</footer>
</body>
<script>
const locationsArray = <%-JSON.stringify(locationsData) %>;
const sensorArray = <%- JSON.stringify(sensorData) %>;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="sensor.js"></script>
</html>

View File

@ -556,4 +556,83 @@ footer {
font-weight: bold; /* Make condition labels bold */
}
.sensor-creation-container {
max-width: 600px;
margin: 10px auto;
background-color: #f9f9f9;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-left: 20px; /* Adjust the value as needed */
}
.input-box {
margin-bottom: 15px;
}
.input-box input,
.input-box select {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
.button input {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
.button input:hover {
background-color: #45a049;
}
#additional-text4 {
width: 30%; /* Adjust the width as needed */
margin-left: 500px; /* Push it to the right */
margin-top: -450px; /* Adjust the negative margin to move it up */
padding: 10px; /* Add padding for spacing */
background-color: #f4f4f4; /* Add background color if desired */
border-radius: 5px; /* Add border-radius for rounded corners */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Add box shadow for a subtle effect */
border: 1px solid #ddd; /* Add a 1px solid border with light gray color */
font-family: 'Open Sans', sans-serif;
}
#additional-text4 p {
font-size: 16px; /* Adjust font size as needed */
line-height: 1.6; /* Adjust line height for better readability */
}
#additional-text4 .condition {
margin-bottom: 10px; /* Add space between conditions */
}
#additional-text4 .condition span {
font-weight: bold; /* Make condition labels bold */
}
#additional-text4 .condition.error {
color: red; /* Change text color for error conditions */
}
#additional-text4 .condition.success {
color: green; /* Change text color for success conditions */
}
.custom-location-form {
max-width: 600px;
margin: 10px auto 20px; /* Adjust the top and bottom margins */
background-color: #f9f9f9;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-left: 20px; /* Adjust the left margin as needed */
margin-top: 0px; /* Adjust the top margin to move it up */
}
/* Add any other specific styles for this form */
.custom-location-form h3 {
color: #333; /* Customize the heading color */
}

3597
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
},
"homepage": "https://github.com/Newtbot/MP#readme",
"dependencies": {
"axios": "^1.6.5",
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"cookie-parser": "^1.4.6",