/*
Copyright (C) 2021 Velometrik GmbH
<http://www.velometrik.de/>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Created on : 04.06.2021, 21:08:29
Author : Peter Bauer
*/
if(getFromLocalStorage('force') === 'false'){
console.log('force reload');
saveToLocalStorage('force',true)
//let inter = setInterval( () => {
// location.reload(true)
// clearInterval(inter);
//}, 500)
}
var aLangKeys = new Object();
var lang = "";
var back = document.getElementsByClassName('right_col')[0];
let menu_bread = document.getElementById('menu_bread');
var log = getFromLocalStorage('log') || false;
var cardsReady = false
var cat = []
var customJSN = new Object();
var week = ["week_0","week_1","week_2","week_3","week_4","week_5","week_6"];
var month = ["mon_0","mon_1","mon_2","mon_3","mon_4","mon_5","mon_6","mon_7","mon_8","mon_9","mon_10","mon_11"];
var httpSetconfig = new XMLHttpRequest();
var httpreboot = new XMLHttpRequest();
const script_host = location.origin;
const script_ws = script_host.replace('http','ws');
const script_apps= "satteldruckanalyse";
let script_websocket = new WebSocket(`${script_ws}/apps/${script_apps}`, ["soap", "wamp"]);
const ws_messages = new WebSocket(`${script_ws}/messages`, ["soap", "wamp"]);
var script_Data= new Object();
var script_setting = new Object();
var URL_SmartCube = ""
var htdocsInfo = new Object();
var box_status=[]
/**
* The function `saveToLocalStorage` saves a key-value pair to the browser's local storage.
* @param key - The `key` parameter is a string that represents the name under which the `value` will
* be stored in the browser's local storage.
* @param value - The `value` parameter in the `saveToLocalStorage` function is the data that you want
* to save to the local storage. It could be a string, number, object, array, or any other type of data
* that you want to store locally in the browser.
*/
function saveToLocalStorage(key, value) {
localStorage.setItem(key, value);
}
/**
* The function `getFromLocalStorage` retrieves a value from the browser's local storage based on a
* specified key.
* @param key - The `key` parameter is a string that represents the key of the item you want to
* retrieve from the localStorage.
* @returns The value stored in the localStorage with the specified key is being returned.
*/
function getFromLocalStorage(key) {
return localStorage.getItem(key);
}
/**
* The function `clearFromLocalStorage` removes specified keys from the localStorage and provides
* feedback on the removal process.
* @param array - The `clearFromLocalStorage` function takes an array as a parameter. This array should
* contain keys that correspond to items stored in the browser's localStorage. The function will then
* check if each key exists in the localStorage and remove it if it does. If a key is not found in the
* localStorage, a
* @returns The function `clearFromLocalStorage` does not explicitly return a value. If the argument
* passed to the function is not an array, it logs an error message and returns early. If the argument
* is an array, it iterates over its elements, removes each key from the localStorage, and logs
* messages accordingly. The function itself does not return any specific value.
*/
function clearFromLocalStorage(array) {
if (!Array.isArray(array)) {
console.error('Das übergebene Argument ist kein Array.');
return;
}
array.forEach(key => {
if (getFromLocalStorage(key) !== null) {
localStorage.removeItem(key);
console.log(`'${key}' wurde aus dem localStorage entfernt.`);
} else {
console.warn(`'${key}' ist nicht im localStorage vorhanden.`);
}
});
}
/* The above code defines a JavaScript object called `shortcuts` which contains key-value pairs where
the keys are single characters ('n', 'c', 'p', 's', 'l') and the values are functions. Each function
is a shortcut to navigate to a specific link when called. For example, pressing 'n' would navigate
to 'newclient.tcls?check=true'. The 'l' key is associated with a function `mod_log()`, which
presumably performs some logging functionality. */
const shortcuts = {
n: () => LinkTo('newclient.tcls?check=true'),
c: () => LinkTo('clients.tcls?check=true'),
p: () => LinkTo('tpfs.tcls?check=true'),
s: () => LinkTo('seat_bone.tcls?check=true'),
l: () => mod_log()
};
const shortcuts_spa = {
1: () => ProgressTimeHandler(1),
2: () => ProgressTimeHandler(2),
'enter': () => toProtokol()
};
document.addEventListener('keydown', (event) => {
// Prüfen, ob das aktive Element ein Input- oder Textarea-Feld ist
const activeElement = document.activeElement;
const isInputFieldActive = activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA';
// Prüfen, ob der Benutzer sich auf der Seite 'saddle_pressure_analysis.tcls' befindet
const currentUrl = window.location.href;
const isSaddlePressurePage = currentUrl.includes('saddle_pressure_analysis.tcls');
// Wenn kein Input/Textarea aktiv ist
if (!isInputFieldActive) {
const key = event.key.toLowerCase();
// Wenn der Benutzer auf der Seite 'saddle_pressure_analysis.tcls' ist, verwende die speziellen Shortcuts
if (isSaddlePressurePage) {
if (shortcuts_spa[key]) {
shortcuts_spa[key]();
}
} else {
// Andernfalls verwende die allgemeinen Shortcuts
if (shortcuts[key]) {
shortcuts[key]();
}
}
}
});
script_websocket.onerror = (e) => {
console.error("WebSocket Error:", e);
if (e.code === 'ECONNREFUSED') {
console.log("Verbindung abgelehnt, versuche erneut...");
reconnectWebSocket(); // Reconnect-Logik könnte hier ergänzt werden
}
};
script_websocket.onclose = (e) => {
console.log('WebSocket geschlossen, versuche erneut zu verbinden...');
setTimeout(() => reconnectWebSocket(), 5000);
};
function reconnectWebSocket() {
script_websocket = new WebSocket(`${script_ws}/apps/${script_apps}`, ["soap", "wamp"]);
}
script_websocket.onopen = (e)=>{
console.log('%c clientsettings websocket open','background: #5cbc40; color: #222;padding: 1em;font-size:1.5em');
console.log('%c get clientsettings','background: #222; color: #5cbc40;padding: 1em;');
script_websocket.send('get clientsettings')
script_websocket.send(`switch create_norm off`)
script_websocket.send(`switch create_jpeg on`)
}
ws_messages.onmessage = (e)=>{
let data = JSON.parse(e.data)
box_status.push(data.status)
if(data.status == 'INET' || data.status =='LOGGED_IN' || data.status == 'WEBSERVICE'){
let ele = document.getElementById('BoxInet')
ele.style.color = 'var(--success)'
ele.setAttribute('key-title','box_inet')
}
if(data.status == 'LAN'){
let ele = document.getElementById('BoxInet')
ele.style.color = 'var(--warn)'
ele.setAttribute('key-title','box_lan')
}
console.log(`%c Box status: ${data.status}`,'background: #5cbc40; color: #222;padding: 1em; font-size:1.5em');
translatejs()
}
script_websocket.onmessage = (e)=> {
try {
script_Data = JSON.parse(e.data);
} catch (error) {
getError(error)
}
if(script_Data.wsevent ==="clientsettings"){
script_setting = script_Data.clientsettings
console.log(`%c clientsettings loaded`,'background: #5cbc40; color: #222;padding: 1em; font-size:1.5em');
console.log(script_setting);
if(script_setting == {}){
console.log(`%c clientsettings are empty (reboot)`,'background: #222; color: #e17a0c;padding: 2em;');
}
if(script_setting.customprotocol){
customJSN = script_setting.customprotocol
for (const i in customJSN) {
cat.push(i)
}
}
if(script_setting.demo){
if(document.getElementById('btn_demo_mode'))
document.getElementById('btn_demo_mode').style.color = document.getElementById('btn_demo_mode') && script_setting.demo == 'true' ? 'var(--warn)' : 'unset';
document.getElementById('demo_mode').innerHTML = document.getElementById('demo_mode') && script_setting.demo == 'true' ? 'DEMO MODE' : '';
if(document.getElementById('switch-demo')&& script_setting.demo == 'true'){
document.getElementById('switch-demo').setAttribute('checked','');
}
}
if(script_setting.custom_protocol){
if(new Date(script_setting.custom_protocol) > new Date()){
console.log('%c Custom Protokol is activ','background: #222; color: #5cbc40;padding: 1em;');
} else {
console.log(`%c Custom Protokol is inactiv (${script_setting.custom_protocol})`,'background: #222; color: #ee395b;padding: 1em;');
script_setting.custom_protocol = false
saveConfig()
}
}
if(script_setting.bg){
back.removeAttribute('class')
back.classList.add('right_col')
back.classList.add(script_setting.bg)
if(script_setting.bg == 'img_own'){
back.style.backgroundImage = `url(${script_setting.own_bg})`
}
}
if(script_setting.smartcube){
if(document.getElementById('url_smartcube')){
document.getElementById('url_smartcube').value = script_setting.smartcube
saveToLocalStorage('smartcube',script_setting.smartcube)
}
if(document.getElementById('hip')){
document.getElementById('hip').value = script_setting.smartcube
saveToLocalStorage('smartcube',script_setting.smartcube)
}
}
if(script_setting.url_logo){
if(document.getElementById('url_logo')){
let x =document.getElementById("url_logo")
x.value = script_setting.url_logo
}
saveToLocalStorage('url_logo',script_setting.url_logo);
}
try {
if(script_setting.UserCompany){
document.getElementById('Company_sidenav').innerHTML = script_setting.UserCompany
if(document.getElementById('system_user_company')) {
document.getElementById('system_user_company').value = script_setting.UserCompany
}
} else {
document.getElementById('Company_sidenav').innerHTML = "Velometrik®"
}
} catch (error) {
getError(error)
}
try {
if(script_setting.UserName){
document.getElementById('User_sidenav').innerHTML = script_setting.UserName
if(document.getElementById('system_user_name'))
document.getElementById('system_user_name').value = script_setting.UserName
}
if(script_setting.UserCity){
if(document.getElementById('system_user_city'))
document.getElementById('system_user_city').value = script_setting.UserCity
}
if(script_setting.UserStreet){
if(document.getElementById('system_user_street'))
document.getElementById('system_user_street').value = script_setting.UserStreet
}
if(script_setting.UserPhone){
if(document.getElementById('system_user_phone'))
document.getElementById('system_user_phone').value = script_setting.UserPhone
}
if(script_setting.UserWeb){
if(document.getElementById('system_user_web'))
document.getElementById('system_user_web').value = script_setting.UserWeb
}
if(script_setting.UserMail){
if(document.getElementById('system_user_mail'))
document.getElementById('system_user_mail').value = script_setting.UserMail
}
if(script_setting.LoginMail){
if(document.getElementById('system_login_mail'))
document.getElementById('system_login_mail').value = script_setting.LoginMail
}
if(script_setting.LoginPass){
if(document.getElementById('system_login_pass'))
document.getElementById('system_login_pass').value = script_setting.LoginPass
}
if(script_setting.UserEinleitung && script_setting.UserEinleitung !== ""){
if(document.getElementById('system_user_einleitung'))
document.getElementById('system_user_einleitung').value = script_setting.UserEinleitung
}
} catch (error) {
getError(error)
}
}
}
script_websocket.onerror= (e)=>{
if(location.pathname === '/production/dashboard.tcls'){
return;
}
getError(e)
console.error(e);
}
//var devLangKeys = getFromLocalStorage('devLang') ? JSON.parse(getFromLocalStorage('devLang')) : new Object();
let help_array = [];
/**
* It takes a JSON object as a parameter, then loops through all the elements with the attribute "key"
* and replaces the innerHTML with the value of the key attribute in the JSON object
* @param params - The object that contains the language keys and their values.
*/
function _Translate(params) {
console.log('%c init translatejs','background:#222;color:white;padding: 1em;');
aLangKeys = params
if(getFromLocalStorage('lang')){
lang = getFromLocalStorage('lang')
}
if(document.getElementById('lang_list')){
let lang_list = document.getElementById('lang_list');
lang_list.innerHTML="";
let zusatzlang = params.zusatzlang;
let primarylang = params.lang;
//let li_pl = document.createElement('div');
let lang_card = newElement({element:'div',cls:['uk-card','uk-card-default','cur_pointer','lang-card'],attr:[['onclick',`langSelected('${primarylang.split(' ')[0]}_${primarylang.split(' ')[0]}.UTF-8')`]]},lang_list)
let lang_head = newElement({element:'div',cls:['uk-card-header','flex-column-center']},lang_card)
let lang_img = newElement({element:'img',cls:['sprachwahl'],attr:[['src',`images/${primarylang.split(' ')[0]}.png`]]},lang_head)
let lang_body = newElement({element:'div',cls:['uk-card-body','uk-padding-small','uk-text-center']},lang_card).innerHTML = `${primarylang.split(' ')[1]}`
//let div_pl = document.createElement('div');
//div_pl.classList.add('col-md-3', 'col-sm-12', 'form-group')
//div_pl.innerHTML = `<a href="#" onclick="langSelected('${primarylang.split(' ')[0]}_${primarylang.split(' ')[0]}.UTF-8');"><img class="sprachwahl" src="images/${primarylang.split(' ')[0]}.png"> ${primarylang.split(' ')[1]}</a>`
//li_pl.setAttribute('style','float: none;width: 100%;margin-bottom: 10px;')
//li_pl.innerHTML = `<a style="justify-content: space-between;" href="#select" onclick="langSelected('${primarylang.split(' ')[0]}_${primarylang.split(' ')[0]}.UTF-8');"><img class="sprachwahl_klein" src="images/${primarylang.split(' ')[0]}.png">${primarylang.split(' ')[1]}</a>`
//lang_list.prepend(li_pl)
// lang_list_2.prepend(div_pl)
zusatzlang.forEach(langs => {
let lang_card = newElement({element:'div',cls:['uk-card','uk-card-default','cur_pointer','lang-card'],attr:[['onclick',`langSelected('${langs.split(' ')[0]}_${langs.split(' ')[0]}.UTF-8')`]]},lang_list)
let lang_head = newElement({element:'div',cls:['uk-card-header','flex-column-center']},lang_card)
let lang_img = newElement({element:'img',cls:['sprachwahl'],attr:[['src',`images/${langs.split(' ')[0]}.png`]]},lang_head)
let lang_body = newElement({element:'div',cls:['uk-card-body','uk-padding-small','uk-text-center']},lang_card).innerHTML = `${langs.split(' ')[1]}`
//let div = document.createElement('div');
//div.classList.add('col-md-3', 'col-sm-12', 'form-group')
//div.innerHTML = `<a href="#" onclick="langSelected('${langs.split(' ')[0]}_${langs.split(' ')[0]}.UTF-8');"><img class="sprachwahl" src="images/${langs.split(' ')[0]}.png"> ${langs.split(' ')[1]}</a>`
//let li = document.createElement('li');
//li.setAttribute('style','float: none;width: 100%;margin-bottom: 10px;')
//li.innerHTML = `<a style="justify-content: space-between;" href="#select" onclick="langSelected('${langs.split(' ')[0]}_${langs.split(' ')[0]}.UTF-8');"><img class="sprachwahl_klein" src="images/${langs.split(' ')[0]}.png">${langs.split(' ')[1]}</a>`
//lang_list.append(li)
// lang_list_2.append(div)
});
}
/* The above code is used to change the placeholder of the input fields. */
for(const key3 in document.querySelectorAll('[key-place]')){
const element3 = document.querySelectorAll('[key-place]')[key3];
if(element3.tagName){
let ele = element3.getAttribute('key-place')
element3.setAttribute('placeholder',`${getTranslation(ele)}`)
// if(element3.getAttribute('placeholder')=="undefined"){
// devLangKeys[element3.getAttribute('key-place')]=element3.getAttribute('key-place')
// } else{
// devLangKeys[element3.getAttribute('key-place')]=element3.getAttribute('placeholder')
// }
//localStorage.setItem('devLang',JSON.stringify(devLangKeys))
}
}
/* The above code is setting the title attribute of the element with the key-title attribute to the
value of the key in the params object. */
for(const key2 in document.querySelectorAll('[key-title]')){
const element2 = document.querySelectorAll('[key-title]')[key2];
if(element2.tagName){
let ele = element2.getAttribute('key-title')
element2.setAttribute('title',`${getTranslation(ele)}`)
// if(element2.getAttribute('title')=="undefined"){
// devLangKeys[element2.getAttribute('key-title')]=element2.getAttribute('key-title')
// } else{
// devLangKeys[element2.getAttribute('key-title')]=element2.getAttribute('title')
// }
//localStorage.setItem('devLang',JSON.stringify(devLangKeys))
}
}
/* Adding a class to the element and then creating a modal for the element. */
for(const key4 in document.querySelectorAll('[key-readme]')){
const readmeElement = document.querySelectorAll('[key-readme]')[key4];
if(readmeElement.tagName){
readmeElement.classList.add('readme','mdi','mdi-help-circle-outline')
let varRead = readmeElement.getAttribute('key-readme');
if(!help_array.includes(varRead)){
CreateReadMeMod(varRead);
help_array.push(varRead);
}
readmeElement.setAttribute('onclick',`OpenReadMe('${varRead}')`) //Z 634
}
}
/* Looping through all the elements with the attribute key and replacing the innerHTML with the value
of the key in the params object. */
for (const key in document.querySelectorAll('[key]')) {
const element = document.querySelectorAll('[key]')[key];
if(element.innerHTML){
element.innerHTML = `${getTranslation(element.getAttribute("key"))}`;
//if(element.innerHTML=="undefined"){
// devLangKeys[element.getAttribute('key')]=element.getAttribute('key')
//} else{
// devLangKeys[element.getAttribute('key')]=element.innerHTML
//}
//localStorage.setItem('devLang',JSON.stringify(devLangKeys))
}
}
$("#sprachwahl").attr("src", `images/${lang}.png`);
}
function getTranslation(key) {
return aLangKeys[lang][key] || `[${key}]`; // `[key]` zeigt an, dass die Übersetzung fehlt
}
/**
* It sets the language to the local storage and then fetches the json file and translates the page.
* @param {String}lang - The language you want to translate to.
*/
function langSelected(lang) {
//let httplang = new XMLHttpRequest();
let result = lang.substring(0, 2);
//var url = `/production/setlanguagefile.tcls?systemsprache=${result}`;
saveToLocalStorage('lang',result)
fetch("/production/json/lang.json", {
mode: "no-cors",
}) // disable CORS because path does not contain http(s)
.then((res) => res.json())
.then((data) => (_Translate(data)));
//httplang.open("GET", url, true);
//httplang.send();
}
/**
* The function `dashboardCards` fetches data from a JSON file, disables CORS, and then calls the
* `DashCards` function with the fetched data, followed by calling the `translatejs` function. If an
* error occurs, the `getError` function is called.
*/
function dashboardCards() {
try {
fetch("/production/json/cards.json", {
mode: "no-cors",
}) // disable CORS because path does not contain http(s)
.then((res) => res.json())
.then((data) => (DashCards(data)));
} catch (error) {
getError(error)
}
}
/* The above code is attempting to fetch data from a JSON file located at "/htdocs.json" using the
Fetch API in JavaScript. The fetch request is set to "no-cors" mode, which means that the response
will not be blocked by CORS (Cross-Origin Resource Sharing) restrictions. */
try {
fetch("/htdocs.json", {
mode: "no-cors",
})
.then((res)=> res.json())
.then((data)=>htdocs(data))
} catch (error) {
getError(error)
}
/**
* The function htdocs takes a JSON object as input and updates the innerHTML of all elements with the
* class 'version' to the value of the VERSION property in the JSON object.
* @param jsn - The parameter `jsn` is expected to be a JSON object containing information about the
* `htdocs` version.
*/
function htdocs (jsn){
htdocsInfo = jsn
for (const ele of document.getElementsByClassName('version')) {
ele.innerHTML = htdocsInfo.VERSION
}
//if(!(!getFromLocalStorage('Ergotec') && htdocsInfo.implementation == 'Ergotec')){
// return;
//}
//console.log('test',getFromLocalStorage('Ergotec'));
//localStorage.setItem('Ergotec','true');
//window.location.reload(true);
}
/**
* The DashCards function creates and appends HTML elements based on the provided JSON data to display
* dashboard cards.
* @param jsn - The `jsn` parameter is an object that contains the data for creating the dash cards. It
* should have a property called `dashbordcards` which is an array of objects representing each dash
* card. Each dash card object should have the following properties:
*/
function DashCards(jsn){
if(location.href === 'http://velobox434.local/production/dashboard.tcls'){
setTime()
saveToLocalStorage('tpfs','sattel')
}
const to = document.getElementById('dash-card-holder');
for (const key in jsn) {
if(key === 'dashbordcards'){
const e = jsn[key];
for (const i of e) {
if(i.visible === "true"){
let div = newElement({element:'div',id:`div_${i.name}`},to)
let help = newElement({element:'i',cls:['readme_card'],attr:[['key-title','ReadMe_title_help'],['key-readme',`Help_Tile_${i.name}`]]},div);
let card = newElement({element:'div',id:`${i.name}`,cls:['uk-card','uk-card-default','cur_pointer','card_hover'],attr:[['style','width:16em'],['onclick',`LinkTo('${i.link}.tcls?check=true')`]]},div);
let head = newElement({element:'div',cls:['uk-card-body','flex-column-center']},card);
let img = newElement({element:'img',id:`img_${i.name}`,cls:['img-circle'],attr:[['width','150'],['height','135'],['src',`${i.image}`]]},head);
let body = newElement({element:'div',cls:['uk-card-footer','uk-padding-small','uk-text-center'],attr:[['key',`${i.tkey}`]]},card).innerHTML = "<!---->";
if(i.name === 'Seatbonemeasurement'){
card.classList.add('no-hocker');
saveToLocalStorage('smartcube_link',false)
img.classList.add('uk-blend-luminosity')
}
}
}
}
}
translatejs()
}
/**
* It fetches the JSON file, then calls the _Translate function with the JSON file as an argument.
*/
function translatejs() {
try {
fetch("/production/json/lang.json?v=1", {
mode: "no-cors",
}) // disable CORS because path does not contain http(s)
.then((res) => res.json())
.then((data) => (_Translate(data)));
} catch (error) {
getError(error)
}
}
/**
* The function `reinit` is used to reload the current page after sending a GET request to a specific
* URL based on the host name.
*/
function reinit() {
var url = ""
if (location.host.includes('velobox')) {
url = "/production/reinit.tcls";
} else {
url = "/production/reinit_hocker.tcls";
}
clearFromLocalStorage(['smartcube'])
httpreboot.open("GET", url, true);
httpreboot.send();
let inter = setInterval(()=> {
window.location.reload(true);
clearInterval(inter);
}, 1000);
}
/**
* The function starts a countdown and then reboots the Velobox
*/
//function reboot() {
// var url = "/production/reboot.tcls";
// // btn1 ist das X zum schließen des Fensters
// //var btn1 = document.getElementById("btn1");
// //btn1.setAttribute("disabled", "true");
// localStorage.clear()
// var btn2 = document.getElementById("btn2");
// btn2.setAttribute("disabled", "true");
// var btn3 = document.getElementById("btn3");
// btn3.setAttribute("disabled", "true");
// countdown();
// httpreboot.open("GET", url, true);
// httpreboot.send();
//} // reboot()
function reboot() {
var url = "/production/reboot.tcls";
localStorage.clear();
var btn2 = document.getElementById("btn2");
btn2.setAttribute("disabled", "true");
var btn3 = document.getElementById("btn3");
btn3.setAttribute("disabled", "true");
biosAnimation();
httpreboot.open("GET", url, true);
httpreboot.send();
// Simuliere einen Neustart des Raspberry Pi
setTimeout(() => {
location.pathname = "/";
}, 50000); // 50 Sekunden
}
/**
* BIOS-Style Animation with scrolling
*/
function biosAnimation() {
const canvas = document.getElementById('biosCanvas');
const ctx = canvas.getContext('2d');
const messages = [
'[OK] Chips detected',
'[OK] Memory check passed',
'[OK] No coffee machine attached',
'[OK] Keyboard connected',
'[OK] GPU rendering enabled',
'[OK] Network adapter initialized',
'[OK] Disk check complete',
'[OK] System ready for reboot...',
'[OK] Detecting USB devices...',
'[OK] Found 2 mice and 1 keyboard',
'[OK] Bluetooth module active',
'[OK] Toaster not responding (but not required)',
'[OK] Loading humor module',
'[OK] Deploying sarcasm API',
'[OK] Configuring banana stand',
'[OK] Initializing quantum flux',
'[OK] Synchronizing system clocks',
'[OK] Checking for bad jokes...',
'[OK] Jokes found. Deploying...',
'[OK] Starting karaoke mode',
'[OK] Enabling cool mode',
'[OK] Pizza delivery module not found (skipped)',
'[OK] Installing sarcasm drivers',
'[OK] Running happiness test...',
'[OK] Happiness levels optimal',
'[OK] Compiling dad jokes',
'[OK] Debugging bad puns',
'[OK] Charging good vibes',
'[OK] Preparing virtual snacks',
'[OK] Infinite loop test passed',
'[OK] AI sentience disabled',
'[OK] Detecting alien life...',
'[OK] Enabling party mode',
'[OK] Confetti launcher armed',
'[OK] Checking caffeine levels...',
'[OK] Low caffeine levels acceptable',
'[OK] Initializing dance floor',
'[OK] Setting up disco lights',
'[OK] Testing bad pun engine',
'[OK] Found 100% compatibility',
'[OK] Tuning to perfect frequency',
'[OK] Assembling fun bits',
'[OK] Mission ready to launch',
'[OK] System reboot imminent...'
];
const lineHeight = 20; // Height of each line
const maxLines = Math.floor(canvas.height / lineHeight-5); // Visible lines in the canvas
let currentMessageIndex = 0; // Track current message being displayed
let charIndex = 0; // Track the character position within the message
let displayedMessages = []; // Track fully displayed messages
function draw() {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height); // Clear canvas
ctx.fillStyle = '#0F0'; // Green text
ctx.font = '16px monospace';
// Draw visible messages
for (let i = 0; i < displayedMessages.length; i++) {
ctx.fillText(displayedMessages[i], 10, (i + 1) * lineHeight);
}
// Draw the current message being typed
if (currentMessageIndex < messages.length) {
const currentMessage = messages[currentMessageIndex];
const visiblePart = currentMessage.substring(0, charIndex);
ctx.fillText(visiblePart, 10, (displayedMessages.length + 1) * lineHeight);
// Advance to the next character
if (charIndex < currentMessage.length) {
charIndex++;
} else {
// Move to the next message
displayedMessages.push(currentMessage); // Add the fully displayed message
currentMessageIndex++;
charIndex = 0;
// Scroll if necessary
if (displayedMessages.length > maxLines) {
displayedMessages.shift(); // Remove the oldest message
}
}
// Continue the animation
setTimeout(draw, 50); // 50ms per character
}
}
draw();
}
/**
* It counts down from 60 seconds and reloads the page when it reaches 0
*/
function countdown() {
var seconds = 50;
var progress = document.getElementById('progress_restart')
function tick() {
seconds--;
progress.value +=1
if (seconds > 0) {
setTimeout(tick, 1000);
} else {
location.pathname = "/"
}
}
translatejs();
tick();
}
/**
* It takes an array of strings and creates a breadcrumb navigation bar
* @param {Arraya<string>}params - an array of strings that will be used to create the breadcrumb.
*/
function BreadCrumb(params) {
let path = $('.meinpfad')[0];
path.innerHTML = "";
let ihome = document.createElement('i');
ihome.classList.add('mdi','mdi-sitemap')
let spanhome = document.createElement('span');
spanhome.setAttribute('key','mainmenu_home');
spanhome.setAttribute('onclick',`LinkTo('dashboard.tcls')`)
path.append(ihome);
path.append(spanhome);
params.forEach(element => {
let i = document.createElement('i');
i.classList.add('mdi','mdi-menu-right');
path.append(i);
let s = document.createElement('span');
// s.classList.add('tr');
s.setAttribute('key',`bread_${element}`)
if(location.pathname == "/production/clients.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
if(location.pathname == "/production/newclient.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
if(location.pathname == "/production/tpfs.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
if(location.pathname == "/production/galerie.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
if(location.pathname == "/production/system.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
if(location.pathname == "/production/info.tcls"){
document.getElementsByClassName('headliner')[0].setAttribute('key',`bread_${element}`)
}
s.setAttribute('onclick',`LinkTo('${element}.tcls')`)
s.setAttribute('style','cursor: pointer')
s.innerHTML = element;
path.append(s);
// if(element !='dashboard'){
let li = document.createElement('li');
let a = document.createElement('a');
a.classList.add('font-12');
a.setAttribute('key',`bread_${element}`);
a.setAttribute('onclick',`LinkTo('${element}.tcls')`)
a.setAttribute('href',`/production/${element}.tcls`)
a.id = element.replaceAll(' ','')
a.innerHTML = element
//if(location.pathname == "/production/dashboard.tcls"){
// li.classList.add('hidden')
//}
if(element==='client'){
let a2 = newElement({element:'a',attr:[['onclick',`LinkTo('${element}.tcls')`],['style','display:none;']]},li)
a.removeAttribute('key');
a.innerHTML = `${getFromLocalStorage('client_forenames')} ${getFromLocalStorage('client_surename')}`
a.setAttribute('href',`/production/client.tcls`)
a.setAttribute('onclick',`info(${getFromLocalStorage('client_id')},'${getFromLocalStorage('client_name')}','${getFromLocalStorage('client_forenames')}','${getFromLocalStorage('client_surename')}','${getFromLocalStorage('client_mail')||""}','${getFromLocalStorage('client_fc')}')`)
//info(`${getFromLocalStorage('client_id')}`,`${getFromLocalStorage('client_name')}`,`${getFromLocalStorage('client_mail')||""}`,`${getFromLocalStorage('client_fc')}`)
s.removeAttribute('key');
s.innerHTML = getFromLocalStorage('client_name')
}
menu_bread.append(li)
li.append(a)
});
}
/**
* It removes the local storage items 'ReadFirstStart' and 'ReadFirstSatteldruckanalyse'
*/
function HelpReset() {
clearFromLocalStorage(['ReadFirstStart','ReadFirstSatteldruckanalyse'])
}
/**
* It sends a request to the server to get the handbook file for the selected language
* @param sprache - The language of the handbook.
*/
function setHandbuchfile(sprache) {
var url = "/production/korrekturhandbuch.tcls?sprache=" + sprache;
httpSetconfig.open("GET", url, true);
httpSetconfig.send();
}
/**
* The function takes a parameter, which is the name of the page you want to link to, and then it
* changes the location of the current page to the page you want to link to
* @param params - The name of the parameter you want to pass to the function.
*/
function LinkTo(params) {
console.log(params);
location.href = `/production/${params}`
saveToLocalStorage('force',false)
}
/**
* The function mod_about() displays a modal with the id "modal-about" using UIkit.
*/
function mod_about() {
UIkit.modal("#modal-about").show();
}
/**
* The function "PrintLog" logs a message to the console if the "log" variable is true.
* @param {Array<String>}params - The parameter "params" is a variable that represents the data or message that needs
* to be logged. It is passed as an argument to the function "PrintLog".
*/
function PrintLog(params) {
if (log) {
params.forEach(element => {
console.log(element);
});
}
}
/**
* It checks if the user has already seen the first start modal and if not, it shows it
*/
function localstart() {
if (getFromLocalStorage("ReadFirstStart") === null) {
console.log("Init FirstStart");
saveToLocalStorage("ReadFirstStart", false);
}
if (getFromLocalStorage("viewmode") === null) {
console.log("Init ViewMode");
saveToLocalStorage("viewmode", "basic");
}
if (getFromLocalStorage("ReadFirstSatteldruckanalyse") === "false" && document.getElementById("firstsatteldruckanalyse")) {
$("#firstsatteldruckanalyse").modal("show");
}
if (getFromLocalStorage("ReadFirstStart") === "false" && location.pathname == "/production/dashboard.tcls") {
//$("#firststart").modal("show");
UIkit.modal("#firststart").show();
}
}
if(location.pathname == "/production/dashboard.tcls"){
dashboardCards()
BreadCrumb(['dashboard']);
}
if(location.pathname == "/production/clients.tcls"){
BreadCrumb(['dashboard','clients']);
}
if(location.pathname == "/production/newclient.tcls"){
BreadCrumb(['dashboard','clients','newclient']);
}
if(location.pathname == "/production/client.tcls"){
BreadCrumb(['dashboard','clients','client'])
}
if(location.pathname == "/production/saddle_pressure_analysis.tcls"){
BreadCrumb(['dashboard','clients','client','saddle_pressure_analysis']);
}
if(location.pathname == "/production/anamnese.tcls"){
BreadCrumb(['dashboard','clients','client','anamnese']);
}
if(location.pathname == "/production/protokoll.tcls"){
BreadCrumb(['dashboard','clients','client','protokoll','galerie'])
}
if(location.pathname == "/production/galerie.tcls"){
BreadCrumb(['dashboard','clients','client','protokoll','galerie'])
}
if(location.pathname == "/production/handbuch.tcls"){
BreadCrumb(['dashboard','handbuch'])
}
if(location.pathname == "/production/system.tcls"){
BreadCrumb(['dashboard','system'])
}
if(location.pathname == "/production/sitzknochenvermessung.tcls"){
BreadCrumb(['dashboard','sitzknochenvermessung'])
}
if(location.pathname == "/production/wlanconfig.tcls"){
BreadCrumb(['dashboard','wlanconfig'])
}
if(location.pathname == "/production/changelog.tcls"){
BreadCrumb(['dashboard','changelog'])
}
if(location.pathname == "/production/tpfs.tcls"){
BreadCrumb(['dashboard','tpfs'])
}
if(location.pathname == "/production/products.tcls"){
BreadCrumb(['dashboard','tpfs','products'])
}
if(location.pathname == "/production/info.tcls"){
BreadCrumb(['dashboard','info'])
}
var checkbox = document.getElementById('basic');
var checkbox_view = document.getElementById('switch-1')
if(document.getElementById('switch-demo'))
var checkbox_demo = document.getElementById('switch-demo')
var checkbox_mask1 = document.getElementById('mask1')
var checkbox_mask2 = document.getElementById('mask2')
var checkbox_set_comp = document.getElementById('set_comp')
var checkbox_maskedit = document.getElementById('maskedit');
/**
* The function `chk_wifi()` checks the status of the Ethernet and WiFi connections and updates the
* corresponding elements on the webpage accordingly.
*/
function chk_wifi() {
const btn_eth = document.getElementById('eth');
const span_eth = document.getElementById('eth_con');
try {
if(btn_eth.dataset.inet == ""){
btn_eth.classList.remove('mdi-lan-connect')
btn_eth.classList.add('mdi-lan-disconnect')
btn_eth.setAttribute('disabled','')
span_eth.setAttribute('style','color: var(--red);')
} else {
span_eth.setAttribute('style','color: var(--primary);')
}
} catch (error) {
getError(error)
}
//WIFI-CONN
//mdi-wifi-off
const btn_wifi = document.getElementById('wifi')
const span_wifi = document.getElementById('wifi_con')
const li_id = document.getElementById('wifi_id')
const li_id_hr = document.getElementById('wifi_id_hr')
try {
if(btn_wifi.dataset.inet != ""){
span_wifi.setAttribute('style','color: var(--primary);')
} else {
btn_wifi.classList.remove('mdi-wifi')
btn_wifi.classList.add('mdi-wifi-off')
span_wifi.setAttribute('style','color: var(--red);')
span_wifi.setAttribute('key','con_disconekt')
li_id.classList.add('hidden')
li_id_hr.classList.add('hidden')
translatejs()
}
} catch (error) {
getError(error)
}
}
/* The above code is adding an event listener to a checkbox element with the id "checkbox_view". When
the checkbox is checked, it logs "basic is checked.." to the console and calls the function
ToggleViewMode with the argument 'advanced'. When the checkbox is unchecked, it logs "basic is not
checked.." to the console and calls the function ToggleViewMode with the argument 'basic'. */
checkbox_view.addEventListener('change', function() {
if (this.checked) {
console.log("basic is checked..");
// document.getElementById("basic").nextSibling.classList.add('custom_switch')
ToggleViewMode('advanced');
} else {
console.log("basic is not checked..");
// document.getElementById("basic").nextSibling.classList.remove('custom_switch')
ToggleViewMode('basic');
}
});
if(document.getElementById('switch-demo')){
if(script_setting.demo == 'true'){
checkbox_demo.setAttribute('checked','')
}
checkbox_demo.addEventListener('change',()=>{
setDemomode()
})
}
try {
checkbox_mask1.addEventListener('change', function() {
console.log(this.dataset.num);
if (this.checked) {
document.getElementById("mask1").nextSibling.classList.add('custom_switch')
showMask(this.dataset.num)
} else {
document.getElementById("mask1").nextSibling.classList.remove('custom_switch')
hideMask(this.dataset.num)
}
});
} catch (error) {
//getError(error)
}
try {
checkbox_mask2.addEventListener('change', function() {
console.log(this.dataset.num);
if (this.checked) {
document.getElementById("mask2").nextSibling.classList.add('custom_switch')
showMask(this.dataset.num)
} else {
document.getElementById("mask2").nextSibling.classList.remove('custom_switch')
hideMask(this.dataset.num)
}
});
} catch (error) {
//getError(error)
}
try {
checkbox_maskedit.addEventListener('change', function() {
console.log(this.dataset.num);
if (this.checked) {
//document.getElementById("maskedit").nextSibling.classList.add('custom_switch')
hide_mask()
} else {
//document.getElementById("maskedit").nextSibling.classList.remove('custom_switch')
hide_mask()
}
});
} catch (error) {
//getError(error)
}
try {
checkbox_set_comp.addEventListener('change', function() {
console.log(this.dataset.num);
if (this.checked) {
document.getElementById("set_comp").nextSibling.classList.add('custom_switch')
set_comp("on")
} else {
document.getElementById("set_comp").nextSibling.classList.remove('custom_switch')
set_comp("off")
}
});
} catch (error) {
//getError(error)
}
var men = document.getElementById('menu_toggle');
men.addEventListener('click',()=>{
let m_men = document.getElementsByClassName('men');
if(document.getElementsByTagName('body')[0].classList.contains('nav-md')){
for (const iterator of m_men) {
iterator.classList.add('hide')
}
} else {
for (const iterator of m_men) {
iterator.classList.remove('hide')
}
}
})
/**
* It takes a string, and returns a translated string
* @param {String}params - The string you want to translate.
* @returns The value of the key in the object.
*/
function gettrans(params) {
lang = getFromLocalStorage('lang')
console.log(params,lang);
translatejs()
console.log(aLangKeys);
try {
return aLangKeys[lang][params]
} catch (error) {
getError(error)
}
}
/**
* It sets the position of the element with the id of "foo" to fixed, and sets the width and height of
* the element to the width and height of the window
*/
function abso() {
ch = $(window).height();
cw = $(window).width()/1.25;
$('#foo').css({
position: 'fixed',
background: 'white !important',
zIndex: 1000,
width: $(window).width(),
height: $(window).height(),
top: 0,
right: '10%',
bottom: 0,
left: '10%'
});
}
try {
let side_smartcube = document.getElementById('sitzknochen-menu');
side_smartcube.setAttribute('href','/production/seat_bone.tcls?check=true')
} catch (error) {
getError(error)
}
/* The above code is creating a clock that updates every second. It uses the setInterval function to
execute a function every 1000 milliseconds (1 second). Inside the function, it gets the current time
using the Date object. It then formats the time into hours, minutes, and seconds, adding leading
zeros if necessary. Finally, it updates the innerHTML of an element with the id 'clock' with the
formatted time. */
let clock_dash = setInterval(function () {
if(aLangKeys[lang]){
let c = document.getElementById('clock');
let time = new Date();
let h = time.getHours() < 10 ? '0' + time.getHours() : time.getHours();
let m = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
let s = time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds();
let time_str = `${aLangKeys[lang][week[time.getDay()||1]]} ${time.getDate()} ${aLangKeys[lang][month[time.getMonth()||1]]} ${h}:${m}:${s}`;
c.innerHTML = time_str;
}
}, 1000);
// $(window).resize(function() {
// abso();
// });
/**
* It creates a new element with the given parameters and appends it to the given element
*
* @function
* @name newElement
* @kind function
* @param {Object<JSON>} jsn - JSON object
* @param {String} jsn.element - HTML element name
* @param {String} jsn.id - ID of the element
* @param {Array<String>} jsn.cls - classes of the element
* @param {Array<Array<String>>} jsn.attr - Attriburtes of the HTML element
* @param {HTMLElement} DOM_Element - the complete element
* @returns {HTMLElement}
*/
function newElement(jsn, DOM_Element) {
let e = document.createElement(jsn.element)
if(jsn.cls){
jsn.cls.forEach(element => {
e.classList.add(element)
});
}
if(jsn.id){
e.id = jsn.id
}
if(jsn.attr){
jsn.attr.forEach(element=>{
e.setAttribute(element[0],element[1])
});
}
if(log){
console.log(`%c New Element -> ${JSON.stringify(jsn)}`,'background: #222;color:white;padding: 1em');
}
DOM_Element.append(e)
return e;
}
// MODAL README
/**
* It creates a modal window with a button to close it, and then fetches the HTML file from the server
* and inserts it into the modal window
* @param {String}params - the name of the file to be loaded.
*/
function CreateReadMeMod(params) {
let append;
if(document.getElementById('ModalHolder')){
append = document.getElementById('ModalHolder');
} else {
append = newElement({element:'div',id:'ModalHolder'},document.getElementsByTagName('body')[0]);
}
let ModalDiv = newElement({element:'div',id:`mod_${params}`,attr:[['uk-modal','']]},append);
let ModalBody = newElement({element:'div',cls:['uk-modal-dialog','uk-modal-body']},ModalDiv);
let ModalBtnX = newElement({element:'button',cls:['uk-modal-close-default'],attr:[['type','button'],['uk-close','']]},ModalBody);
let ModalReadmeText1 = newElement({element:'p'},ModalBody);
try {
fetch(`/production/manuals/${lang}/${params}.html?v=1`, {
mode: "no-cors",
}) // disable CORS because path does not contain http(s)
.then((res) => res.text())
.then((data) => (ModalReadmeText1.innerHTML=data));
} catch (error) {
ModalReadmeText1.innerHTML = error;
getError(error)
}
}
/**
* The function displays an error message in a dialog box.
* @param err - The "err" parameter is a variable that is expected to contain an error message or
* object. This function takes that error and displays it in a dialog box with the title "error" and a
* single "OK" button for the user to dismiss the dialog.
*/
function getError (err){
console.log('getError',err);
OpenModDialog({type:'error',title:["error"],msg:JSON.stringify(err),master_btn:['button_ok']})
}
/**
* > This function opens a modal window with the id of `mod_`
* @param {String}params - The name of the modal you want to open.
*/
function OpenReadMe(params) {
UIkit.modal(`#mod_${params}`).show();
}
/**
* If the error message is not displayed, display it. Otherwise, hide it
*/
function showErrormessage() {
let x = document.getElementsByClassName("error_p");
for (const ele of x) {
if (ele.style.display === "none") {
ele.style.display = "block";
} else {
ele.style.display = "none";
}
}
}
/**
* The openWindow function redirects the user to the dashboard page.
*/
function openWindow() {
location.pathname = 'production/dashboard.tcls'
}
/**
* The function opens a new window with a specific URL and dimensions, and then closes the current
* window.
*/
function openNewWindow() {
window.open(`${location.origin}/production/dashboard.tcls`, "NewWindow",`toolbar=no,menubar=no,scrollbars=no,fullscreen=yes,width=${screen.width},height=${screen.height}`)
closeWindow()
}
/**
* The closeWindow function opens a new window and then closes the current window.
*/
function closeWindow() {
window.open('','_parent','');
window.close();
}
// sample warn
//let dialogSample = {type:'warn',title:"Sitzung #215 löschen?",msg:["cli_session_text"],master_btn:["button_delete","SelectSessionDel()"],slave_btn:["button_cancel"]}
/**
* It creates a modal dialog with a header, body and footer
* @param {JSON.type}jsn - head:"overwrites the defautl head",title:what happend, msg:more info hidden,master_btn:[translationkey,onclick(nothing=close),slave_btn:[translationkey,onclick(nothing=close)]
* @type {String} -warn || error || neutral || success
* @head {Sring} - overwrites the head
* @title {String || Array} -Array:set an translate key -String: a normal string
* @msg {string || Array} - Array: set the translate key for more informations -String: a normal string (server messages)
* @master_btn {Array<String>} - ["transKey",functon()-optional] if no function default is close modal --Optional
* @slave_btn {Array<String>} - ["transKey",functon()-optional] if no function default is close modal --Optional
*/
function OpenModDialog(jsn){
let holder;
if(document.getElementById('ModalHolder')){
holder = document.getElementById('ModalHolder');
} else {
holder = newElement({element:'div',id:'ModalHolder'},document.getElementsByTagName('body')[0]);
}
let modal = newElement({element:'div',attr:[['uk-modal','esc-close:false;bg-close:false;']]},holder)
let dialog= newElement({element:'div',cls:['uk-modal-dialog']},modal)
let head = newElement({element:'div',cls:['uk-modal-header',`mod_${jsn.type}`]},dialog)
let title = newElement({element:'h2',cls:['uk-modal-title'],attr:[['style','color:var(--secondary-text)'],[`key`,`mod_${jsn.type}`]]},head).innerHTML = '<!--title-->'
if(jsn.head){
let title = newElement({element:'h2',cls:['uk-modal-title'],attr:[['style','color:var(--secondary-text)']]},head).innerHTML = jsn.head
}
// let X = newElement({element:'button',cls:['uk-modal-close-default'],attr:[['uk-close','']]},head)
let body = newElement({element:'div',cls:['uk-modal-body']},dialog)
let h4 = newElement({element:'h4',attr:[['style','color:var(--primary-text)'],['onclick','showErrormessage()']]},body)
let h4d= newElement({element:'div',cls:['info_msg','uk-margin-bottom']},h4)
if(jsn.type === 'warn'){
let ico = newElement({element:'span',cls:['uk-margin-right','ico-16','mdi','mdi-alert'],attr:[['style',`color:var(--${jsn.type})`]]},h4d)
}
if(jsn.type === 'error'){
let ico = newElement({element:'span',cls:['uk-margin-right','ico-16','mdi','mdi-minus-circle'],attr:[['style',`color:var(--${jsn.type})`]]},h4d)
}
if(jsn.type === 'success'){
let ico = newElement({element:'span',cls:['uk-margin-right','ico-16','mdi','mdi-help-circle'],attr:[['style',`color:var(--${jsn.type})`]]},h4d)
}
if(jsn.type === 'neutral'){
let ico = newElement({element:'span',cls:['uk-margin-right','ico-16','mdi','mdi-alert-circle'],attr:[['style',`color:var(--${jsn.type})`]]},h4d)
}
if(Array.isArray(jsn.title)){
let warn = newElement({element:'span',attr:[['key',jsn.title[0]]]},h4d).innerHTML = '<!--title-->'
} else{
let warn = newElement({element:'span'},h4d).innerHTML = jsn.title
}
let p = newElement({element:'p',cls:['error_p'],attr:[['style','display:none']]},h4)
if(Array.isArray(jsn.msg)){
let span = newElement({element:'span',attr:[['key',jsn.msg]]},p).innerHTML= '<!--msg-->'
} else {
let span = newElement({element:'span'},p).innerHTML= jsn.msg
}
let foot = newElement({element:'div',cls:['uk-modal-footer','uk-text-right']},dialog)
if(jsn.slave_btn){
let slave = newElement({element:'button',cls:['uk-button', 'uk-button-default', 'uk-modal-close'],attr:[['key',jsn.slave_btn[0]]]},foot)
if(jsn.slave_btn[1])
slave.setAttribute('onclick',jsn.slave_btn[1])
slave.innerHTML = '<!--title-->'
}
if (jsn.master_btn) {
let master = newElement({element:'button',cls:['uk-margin-left','uk-button', `uk-button-${jsn.type}`, 'uk-modal-close'],attr:[['key',jsn.master_btn[0]]]},foot)
if(jsn.master_btn[1])
master.setAttribute('onclick',jsn.master_btn[1])
master.innerHTML = '<!--title-->'
}
translatejs()
UIkit.modal(modal).show();
}
var elem = document.documentElement;
/**
* The function toggles between opening and closing fullscreen mode.
*/
function Vollbild() {
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
// Aktuell im Vollbildmodus -> Schließen
closeFullscreen();
} else {
// Nicht im Vollbildmodus -> Öffnen
openFullscreen();
}
}
/**
* The function opens the browser in fullscreen mode if supported by the browser.
*/
function openFullscreen() {
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) { /* Firefox */
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) { /* IE/Edge */
elem.msRequestFullscreen();
}
}
/**
* The closeFullscreen function is used to exit fullscreen mode in a web browser.
*/
function closeFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) { /* Firefox */
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) { /* Chrome, Safari & Opera */
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { /* IE/Edge */
document.msExitFullscreen();
}
}
/**
* The function `setUserCompany` sets the value of `script_setting.UserCompany` to the provided
* parameter.
* @param params - The `params` parameter is a variable that represents the value you want to set for
* the `UserCompany` property in the `script_setting` object.
*/
function setUserCompany(params){
script_setting.UserCompany = params
}
/**
* The function sets the value of the UserName property in the script_setting object.
* @param params - The `params` parameter is a variable that represents the value you want to set as
* the username.
*/
function setUserName(params){
script_setting.UserName = params
}
/**
* The function `setUserCity` sets the user's city in a script setting.
* @param params - The `params` parameter is a variable that represents the value you want to set for
* the `UserCity` property in the `script_setting` object.
*/
function setUserCity(params){
script_setting.UserCity = params
}
/**
* The function `setUserStreet` sets the value of `script_setting.UserStreet` to the provided
* parameter.
* @param params - The `params` parameter is a variable that represents the value of the user's street
* address.
*/
function setUserStreet(params){
script_setting.UserStreet = params
}
/**
* The function `setUserMail` sets the value of `script_setting.UserMail` to the provided parameter.
* @param params - The `params` parameter is the email address that you want to set for the user.
*/
function setUserMail(params){
script_setting.UserMail = params
}
/**
* The function `setUserWeb` sets the value of `script_setting.UserWeb` to the provided parameter.
* @param params - The `params` parameter is a variable that represents the value you want to set for
* the `UserWeb` property in the `script_setting` object.
*/
function setUserWeb(params){
script_setting.UserWeb = params
}
/**
* The function `setUserPhone` sets the value of `script_setting.UserPhone` to the provided parameter.
* @param params - The `params` parameter is the value that will be assigned to the `UserPhone`
* property of the `script_setting` object.
*/
function setUserPhone(params){
script_setting.UserPhone = params
}
/**
* The function `setUserUnit` sets the `UserUnit` property of the `script_setting` object to the
* provided parameter.
* @param params - The `params` parameter is the value that will be assigned to the `UserUnit` property
* of the `script_setting` object.
*/
function setUserUnit(params){
script_setting.UserUnit = params
}
/**
* The function setUserEinleitung sets the UserEinleitung property in the script_setting object to the
* provided parameter.
* @param params - The `params` parameter is a variable that can hold any value. It is used as an
* argument when calling the `setUserEinleitung` function. The purpose of this function is to set the
* value of the `UserEinleitung` property in the `script_setting` object.
*/
function setUserEinleitung(params){
script_setting.UserEinleitung = params
}
/**
* The function `saveConfig` sends the client settings as a JSON string over a WebSocket connection.
*/
function saveConfig(){
script_websocket.send(`set clientsettings ${JSON.stringify(script_setting)}`)
}
$(document).ready(function () {
translatejs();
localstart();
chk_wifi();
ToggleViewMode(getFromLocalStorage("viewmode"));
if(getFromLocalStorage('viewmode')==='basic'){
checkbox_view.removeAttribute('checked');
// document.getElementById("basic").nextSibling.classList.remove('custom_switch')
ToggleViewMode('basic');
} else{
try {
checkbox_view.setAttribute('checked','')
// document.getElementById("basic").nextSibling.classList.add('custom_switch')
ToggleViewMode('advanced');
} catch (error) {
getError(error)
}
}
if(location.pathname == "/production/saddle_pressure_analysis.tcls"){
checkbox_mask1.removeAttribute('checked')
checkbox_mask2.removeAttribute('checked')
checkbox_maskedit.removeAttribute('checked')
if(script_setting.demo == "true")
checkbox_demo.setAttribute('checked','true')
}
});
//const input = document.querySelector("input");
const input = document.getElementsByTagName('input')
for (const i of input) {
i.addEventListener("input",updateValue)
}
/**
* The function `updateValue` is used to update the value of an input element and display a warning
* notification if the value contains either a double quote or a single quote.
* @param e - The parameter `e` is an event object that is passed to the function when it is called as
* an event handler. It represents the event that triggered the function, such as a keypress or a
* change in an input field.
*/
function updateValue(e) {
const color = "var(--light-4)"
let txt = this.value
let ele = this
if(typeof this.value === "undefined"){
txt = e.value
ele = e
}
//if(txt.includes('&')){
// ele.value = ele.value.replaceAll('&','')
// UIkit.notification({message: `& ${aLangKeys[lang].not_allowed}`, status: 'warn'})
//}
//if(txt.includes('%')){
// ele.value = ele.value.replaceAll('%','')
// UIkit.notification({message: `% ${aLangKeys[lang].not_allowed}`, status: 'warn'})
//}
if(txt.includes('"')){
ele.value = ele.value.replaceAll('"','')
UIkit.notification({message: `" ${aLangKeys[lang].not_allowed}`, status: 'warn'})
}
if(txt.includes("'")){
ele.value = ele.value.replaceAll("'",'')
UIkit.notification({message: `' ${aLangKeys[lang].not_allowed}`, status: 'warn'})
}
}
/* The above code is attempting to fetch data from the URL
"https://downloads.velometrik.de/version.json". It is using the Fetch API to make an HTTP request to
that URL. Once the data is received, it is converted to JSON format using the `res.json()` method.
The `info_update` function is then called with the JSON data as an argument. */
try {
fetch("https://downloads.velometrik.de/version.json")
.then((res)=> res.json())
.then((data)=> info_update(data))
} catch (error) {
console.error(error);
}
/**
* The function `info_update` checks for updates in a JSON object and displays information accordingly
* on a web page.
* @param jsn - The `jsn` parameter in the `info_update` function is an object that contains
* information about versions. It has a property `versionen` which is an array of objects, each
* representing a version with a `version` property. The function compares the current version in the
* `htdocsInfo.VERSION
*/
function info_update(jsn){
let comp = setInterval(()=> {
let aV = htdocsInfo.VERSION.replaceAll('.','')
if(document.getElementById('dl_info')){
var t = document.getElementById('dl_info')
var i = 0
jsn.versionen.forEach(e => {
let nV = e.version.replaceAll('.','')
if (aV < nV) {
i++
t.classList.remove('hidden')
if(getFromLocalStorage('ReadFirstStart') == "true" && location.pathname == '/production/dashboard.tcls' && i==1){
OpenInfoBox(`${e.version}`)
} else if (getFromLocalStorage('ReadFirstStart') == "false" && location.pathname == '/production/dashboard.tcls'&& i==1){
let btn = document.getElementById("firststart_button")
btn.setAttribute('onclick',`OpenInfoBox("${e.version}")`)
}
}
return;
});
}
clearInterval(comp);
}, 500);
}
/**
* The function `OpenInfoBox` opens a modal dialog box with information about a new update, including
* the version number.
* @param params - It looks like the `OpenInfoBox` function is designed to open a dialog box with
* information about a new update. The `params` variable likely contains the version number of the
* update. When the function is called, it will display the version number in the dialog box along with
* buttons for the user
*/
function OpenInfoBox(params){
OpenModDialog({type:'neutral',head:aLangKeys[lang]["new_update_head"],title:["new_update_title"],msg:`Version: ${params}`,master_btn:["button_ok","LinkTo('system.tcls')"],slave_btn:["button_cancel"]})
}
/* The above code is attempting to fetch data from the URL
"https://downloads.velometrik.de/infos.json". If the fetch is successful, it will convert the
response to JSON format and then call the function `DashCards` with the retrieved data as an
argument. If there is an error during the fetch or data conversion process, it will log the error to
the console. */
try {
fetch("https://downloads.velometrik.de/infos.json")
.then((res) => res.json())
.then((data) => (DashCards(data)));
} catch (error) {
console.error(error);
}
/**
* The function TESTJSN processes language keys and checks for missing translations in a JSON object.
*/
function TESTJSN(){
let jsn = aLangKeys
let keys = []
let langs = []
jsn.zusatzlang.forEach(element => {
langs.push(element.split(' ')[0])
});
for (const key in jsn.de) {
keys.push(key)
}
langs.forEach(element => {
console.log(element);
if(jsn[element]){
console.log(element,"exist");
let a = {}
a[element]={}
keys.forEach(element2 => {
if(!jsn[element][element2]){
a[element][element2] = element2
}
});
console.error(a);
} else {
console.error(element,"not exist");
}
});
console.log(keys,langs);
}
/**
* The function `setDemomode` toggles a demo mode setting and updates the display accordingly.
*/
function setDemomode() {
if(!script_setting.demo){
script_setting.demo = "false"
}
script_setting.demo = script_setting.demo == 'false' ? "true" : "false";
document.getElementById('demo_mode').innerHTML = document.getElementById('demo_mode') && script_setting.demo == 'true' ? 'DEMO MODE' : '';
saveConfig();
if(location.pathname === "/production/saddle_pressure_analysis.tcls"){
SessReload();
}
}
//!vergleich Arrays beispiel TEST
// Zwei Beispielarrays
//const array1 = [
// [10, 20, 30, ..., 250],
// // Füge hier die restlichen Zeilen hinzu
// [11, 21, 31, ..., 251]
//];
//const array2 = [
// [10, 20, 30, ..., 250],
// // Füge hier die restlichen Zeilen hinzu
// [12, 20, 31, ..., 250]
//];
// Funktion zum Vergleichen der Arrays
function vergleicheArrays(arr1, arr2) {
const unterschiede = [];
for (let i = 0; i < arr1.length; i++) {
for (let j = 0; j < arr1[i].length; j++) {
if (arr1[i][j] !== arr2[i][j]) {
unterschiede.push({
position: [i, j],
wert1: arr1[i][j],
wert2: arr2[i][j]
});
}
}
}
return unterschiede;
}
/**
* The function `mod_log` opens a modal with the ID "modal-log-modal" using UIkit.
*/
function mod_log() {
UIkit.modal("#modal-log-modal").show();
}
/**
* The function `hide` hides all dropdown elements with the class 'uk-dropdown' using UIkit library.
*/
function hide(){
let all_dropdown = document.getElementsByClassName('uk-dropdown');
for (let index = 0; index < all_dropdown.length; index++) {
const element = all_dropdown[index];
UIkit.dropdown(element).hide(0);
}
}
/**
* The function `executeRandomLinkTo` generates a random number and then calls either
* `LinkTo('error.tcls')` or `LinkTo('error2.tcls')` based on the random number being less than 0.5.
*/
function executeRandomLinkTo() {
// Generiere eine zufällige Zahl zwischen 0 und 1
const randomNumber = Math.random();
console.log('rand',randomNumber);
// Überprüfen ob die Zufallszahl kleiner als 0.5 ist, um eine der beiden Funktionen auszuführen
if (randomNumber < 0.5) {
LinkTo('error.tcls');
} else {
LinkTo('error2.tcls');
}
}
if(getFromLocalStorage("url_logo")&&getFromLocalStorage('Ergotec')){
let img = document.getElementsByClassName('profile_img')[0]
img.src = getFromLocalStorage("url_logo")
} else{
let img = document.getElementsByClassName('profile_img')[0]
img.src = "/production/images/velobox.png"
}
(() => {
const logger = document.getElementById('log');
const originalConsoleLog = console.log;
console.log = (...args) => {
// Extrahiere den formatierten Text und die Styles
let message = args[0];
let styles = args.length > 1 ? args.slice(1) : [];
// Formatierte Nachricht für den Logger vorbereiten
const formattedMessage = typeof message === 'object'
? JSON && JSON.stringify ? JSON.stringify(message) : message
: message;
// Ein neues <p>-Element für den Logger erstellen
const p = document.createElement('p');
p.textContent = formattedMessage
// Wenn Styles vorhanden sind, diese anwenden
if (styles.length > 0) {
p.style.cssText = styles[0]; // Verwendet das erste Style-Argument
}
// Füge das <p>-Element zum Logger hinzu
logger.appendChild(p);
// Gib die ursprünglichen Argumente an console.log zurück, um die Styles in der Konsole beizubehalten
originalConsoleLog.apply(console, args);
};
})();
document.referrer = location.origin;
window.history.forward()
// Fügt einen Dummy-Eintrag zur Historie hinzu
history.pushState(null, '', location.href);
// Verhindert die Navigation zurück, indem ein neuer Eintrag zur Historie hinzugefügt wird
window.addEventListener('popstate', (event) => {
// Prüft, ob der Benutzer zurück navigieren will
if (event.state === null) {
// Verhindert die Standardaktion und leitet auf das Dashboard um
window.location.href = '/production/dashboard.tcls'; // Ersetze dies durch den richtigen Pfad
} else {
history.pushState(null, '', location.href);
}
});
/* The above JavaScript code is adding an event listener to the document for the 'contextmenu' event.
When the context menu is triggered (usually by right-clicking), the code checks if the target
element of the event is within an element with the class 'canvas-container'. It also checks if the
Ctrl key is pressed at the same time. */
document.addEventListener('contextmenu', (event) => {
const isInCanvasContainer = event.target.closest('.canvas-container');
const isCtrlPressed = event.ctrlKey; // Prüft, ob die Strg-Taste gedrückt ist
// Nur zulassen, wenn Strg gedrückt wird oder im canvas-container geklickt wird
if (!isInCanvasContainer && !isCtrlPressed) {
event.preventDefault(); // Blockiere das Kontextmenü für alle anderen Elemente
}
});
/**
* The function `getLocalTime` returns the current local date and time in the format "YYYY-MM-DD
* HH:MM:SS".
* @returns The function `getLocalTime` returns the current local date and time in the format
* "YYYY-MM-DD HH:MM:SS".
*/
function getLocalTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // Monate sind 0-basiert
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
/**
* The function `setTime` sends a request to a server to set the time using the local time obtained
* from the client.
*/
function setTime(){
const localTime = getLocalTime();
const url = `set_time.tcls?time=${encodeURIComponent(localTime)}`;
fetch(url)
.then(response => {
if (!response.ok) {
// Optional: Erfolgreiche Ausführung behandeln
return; // Nichts tun bei Fehlerstatus wie 500
}
// Erfolgreiche Anfrage verarbeiten, falls gewünscht
})
.catch(() => {
// Fehler komplett ignorieren
});
}
// Vergleiche die Arrays
//const aenderungen = vergleicheArrays(array1, array2);
//// Gib die Änderungen aus
//aenderungen.forEach(unterschied => {
// console.log(`Änderung an Position [${unterschied.position[0]}, ${unterschied.position[1]}]: ${unterschied.wert1} -> ${unterschied.wert2}`);
//});