First version
gitea/worker-time-control/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Andrés 2021-10-19 10:52:45 +02:00
parent 03d0f42308
commit 5c05bdc835
14 changed files with 975 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

View File

@ -4,3 +4,10 @@ Launch application in development environment.
```
$ php -S 0.0.0.0:9090 -t .
```
Enable CORS on server side
```
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: *");
if($_SERVER['REQUEST_METHOD'] == "OPTIONS") die();
```

72
clockIn.html Normal file
View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>FichApp</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/style.css" rel="stylesheet" type="text/css"/>
<script src="node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
<script src="node_modules/fastclick/lib/fastclick.js" type="text/javascript"></script>
</head>
<body class="pinLogin">
<header>
<div class="btnSalir">Cerrar</div>
<h2 id="txtNombre"></h2>
</header>
<div class="paneles">
<div class="planPanel">
<div class="container">
<h2>Tus fichadas</h2>
<h3>Situación de los ultimos 7 días</h3>
<div class="total">Total: 7.7h</div>
<ul class="listHorario">
</ul>
</div>
</div>
</div>
<div class="footer">
<div class="in">Inicio jornada</div>
<div class="inMiddle">Inicio descanso</div>
<div class="outMiddle">Fin descanso</div>
<div class="out">Fin jornanda</div>
</div>
<p></p>
<div class="loading">
<div class="loadingcontent">
<div class="sk-cube-grid">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div>
</div>
</div>
</div>
<div class="confirm">
<div class="contConfirm">
<h4 class="txtConfirm"></h4>
</div>
</div>
<script src="config.js" type="text/javascript"></script>
<script src="js/main.js" type="text/javascript"></script>
<script src="js/clock.js" type="text/javascript"></script>
</body>
</html>

13
config.js Normal file
View File

@ -0,0 +1,13 @@
var process = {
env: {NODE_ENV: 'development'}
};
var config = {
development: {
urlBase: 'http://localhost:8080'
},
production: {
urlBase: '//app.verdnatura.es'
}
};

440
css/style.css Normal file
View File

@ -0,0 +1,440 @@
/*
Created on : 29-jul-2019, 11:30:28
Author : enrique blasco blanquer
*/
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,body{
width: 100%;
height: 100%;
font-family: sans-serif;
background: #000;
}
h1{
position: fixed;
bottom: 20px;
right: 20px;
font-size: 1em;
color: #fff;
}
span{
color: #ED4947;
}
.total{
float: right;
font-weight: bold;
font-size: 1.4em;
margin-top: -40px;
}
ul{
list-style: none;
}
.pinLogin{
background-image: url(../img/logo.png);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
#logoVerd{
width: 200px;
margin: 20px;
}
#logoVerdHeader{
width: 50px;
margin: 0;
position: fixed;
top: 12px;
left: 20px;
}
.pinContainer{
width: 350px;
height: 460px;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
text-align: center;
}
#txtPin{
text-align: center;
padding: 15px 5px;
background: rgba(255,255,255,.90);
border: none;
font-weight: bold;
font-size: 1.5em;
display: block;
width: 250px;
margin: auto;
margin-bottom: 10px;
}
.btnPin{
float: left;
width: calc(100% / 3);
height: calc(500px/5);
padding: 5px;
}
.btnPinNum{
width: 100%;
height: 100%;
font-size: 2.5em;
background: rgba(255,255,255,.90);
padding-top: 18px;
}
.btnCancel{
width: 100%;
height: 100%;
font-size: 2.5em;
padding-top: 18px;
background: rgba(237,73,71,.90);
color: #fff;
}
.btnOk{
width: 100%;
height: 100%;
font-size: 2.5em;
padding-top: 18px;
background: rgba(163,171,38,.90);
color: #fff;
}
#txtNombre{
padding-top: 0px;
padding-left: 10px;
float: left;
color: #fff;
text-align: right;
font-size: 1.8em;
font-weight: bold;
}
.paneles{
overflow: hidden;
width: 100%;
}
.planPanel{
float: left;
width: 100%;
padding: 20px 20px 0 20px;
height: auto;
}
.problemsPanel{
float: left;
width: 100%;
height: auto;
padding: 20px;
}
.container{
width: 100%;
height: 100%;
background: rgba(255,255,255,.90);
padding: 20px;
overflow: hidden;
box-shadow: 0 0 5px rgba(0,0,0,.2);
border-radius: 8px;
}
h2{
font-size: 1.3em;
}
h3{
font-size: 1em;
color: #9EA7AC;
font-weight: normal;
}
.footer{
display: none;
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
text-align: center;
}
.in,.inMiddle {
display: inline;
position: static;
width: 350px;
background: #8DD202;
padding: 20px 40px;
font-size: 2em;
color: #fff;
text-align: center;
border-radius: 10px;
}
.out,.outMiddle{
display: inline;
position: static;
width: 350px;
background: rgba(237,73,71,.90);
padding: 20px 40px;
font-size: 2em;
color: #fff;
text-align: center;
border-radius: 10px;
}
header{
overflow: hidden;
padding: 20px 20px 0px 20px;
}
.btnSalir{
float: right;
background: rgba(237,73,71,.90);
padding: 5px 30px;
font-size: 1.2em;
color: #fff;
}
#txtIncidencia{
color: #ED4947;
font-weight: bold;
font-size: 1.4em;
margin-top: 10px;
}
.listHorario{
margin-top: 20px;
width: 100%;
overflow: hidden;
}
.listHorario .headerLi{
width: 100%;
overflow: hidden;
border-bottom: 1px solid #9EA7AC;
padding-bottom: 10px;
}
.listHorario label{
float: left;
width: calc(100% / 7);
text-align: center;
font-weight: bold;
padding: 5px 0;
}
.hoy{
background: #9EA7AC;
color: #fff;
}
.listHorario .time{
float: left;
width: calc(100% / 7);
text-align: center;
padding: 5px 0;
font-size: 1.2em;
overflow: hidden;
}
.listHorario .time img{
width: 20px;
float: left;
margin-right: 5px;
margin-left: 15px;
margin-top: 7px;
}
.listHorario .time p{
float: left;
background: #8DD202;
padding: 5px;
border-radius: 7px;
}
.impar{
color: rgba(163,171,38,.90);
font-weight: bold;
}
.hide{
opacity: 0;
}
.show{
opacity: 1;
}
.confirm{
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #8DD202;
color: #fff;
}
.confirmKO{
display: inline;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(237,73,71);
color: #fff;
}
.contConfirm{
position: fixed;
margin: auto;
top:0;
bottom: 0;
left: 0;
right: 0;
width: 800px;
height: 170px;
text-align: center;
}
.contConfirm h4{
font-size: 2.5em;
margin-bottom: 20px;
}
.btnconfirmar{
float: left;
font-size: 1.2em;
padding: 18px;
background: rgba(163,171,38,.90);
color: #fff;
margin: 15px;
}
.btnnoconfirm{
float: left;
font-size: 1.2em;
padding: 18px;
background: rgba(237,73,71,.90);
color: #fff;
margin: 15px;
}
.botonera{
margin: auto;
width: 310px;
overflow: hidden;
}
.loading{
display: none;
top: 0;
left: 0;
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
background: rgba(25,154,166,1);
background: -moz-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
background: -webkit-gradient(left bottom, right top, color-stop(0%, rgba(25,154,166,1)), color-stop(100%, rgba(39,216,139,1)));
background: -webkit-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
background: -o-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
background: -ms-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
background: linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#199aa6', endColorstr='#27d88b', GradientType=1 );
}
.loadingcontent{
position: fixed;
height: 50px;
width: 100%;
margin: auto;
top: 0;
bottom: 0;
left: 0;
}
.sk-cube-grid {
width: 40px;
height: 40px;
margin: auto;
}
.sk-cube-grid .sk-cube {
width: 33%;
height: 33%;
background-color: #fff;
float: left;
-webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
}
.sk-cube-grid .sk-cube1 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube2 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube3 {
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s; }
.sk-cube-grid .sk-cube4 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube5 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube6 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube7 {
-webkit-animation-delay: 0s;
animation-delay: 0s; }
.sk-cube-grid .sk-cube8 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube9 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
@-webkit-keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1);
} 35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1);
}
}
@keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1);
} 35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1);
}
}

BIN
img/in.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

BIN
img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
img/out.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

110
index.html Normal file
View File

@ -0,0 +1,110 @@
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>FichApp</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/style.css" rel="stylesheet" type="text/css"/>
<script src="node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
<script src="node_modules/fastclick/lib/fastclick.js" type="text/javascript"></script>
</head>
<body class="pinLogin">
<div class="pinContainer">
<p id="txtPin">USUARIO</p>
<div class="btnPin btnnum">
<div class="btnPinNum">
1
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
2
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
3
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
4
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
5
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
6
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
7
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
8
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
9
</div>
</div>
<div class="btnPin">
<div class="btnCancel">
x
</div>
</div>
<div class="btnPin btnnum">
<div class="btnPinNum">
0
</div>
</div>
<div class="btnPin ">
<div class="btnOk">
ok
</div>
</div>
</div>
<h1>
developed with <span>&hearts;</span> by Verdnatura
</h1>
<div class="loading">
<div class="loadingcontent">
<div class="sk-cube-grid">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div>
</div>
</div>
</div>
<div class="confirm">
<div class="contConfirm">
<h4 class="txtConfirm"></h4>
</div>
</div>
<script src="config.js" type="text/javascript"></script>
<script src="js/main.js" type="text/javascript"></script>
<script src="js/index.js" type="text/javascript"></script>
</body>
</html>

187
js/clockIn.js Normal file
View File

@ -0,0 +1,187 @@
var userData = "";
$(document).ready(function () {
userData = $.parseJSON(localStorage.getItem("userData"));
FastClick.attach(document.body);
setView();
setEvents();
});
function setEvents() {
$(".btnSalir").on("click", function () {
cerrar();
});
$(".in").on("click", function () {
fichar('in');
});
$(".inMiddle").on("click", function () {
fichar('middle');
});
$(".outMiddle").on("click", function () {
fichar('middle');
});
$(".out").on("click", function () {
fichar('out');
});
setTimeout(function () {
cerrar();
}, 5000);
}
function setView() {
$(".footer").hide();
$("#txtNombre").text(userData["name"] + " " + userData["surname"]);
getInfo();
$("." + userData["button1"]).show();
$("." + userData["button2"]).show();
}
function fichar(direction) {
$.post({
urlPath: 'clockIn',
jsonData: [userData['userFk'], direction],
processData: false,
success: function (msg) {
if (msg[0].error){
printErrores(msg);
setTimeout(function () {
cerrar();
}, 3000);
}else {
$(".confirm").fadeIn(200);
$(".txtConfirm").append('FICHADA REGISTRADA');
setTimeout(function () {
cerrar();
}, 1000);
}
}
});
}
function setView() {
$(".footer").hide();
$(".in").hide();
$(".inMiddle").hide();
$(".outMiddle").hide();
$(".out").hide();
$("#txtNombre").text(userData["name"] + " " + userData["surname"]);
getInfo();
$("." + userData["button1"]).show();
$("." + userData["button2"]).show();
}
function getInfo() {
$.post({
urlPath: 'getClockIn',
jsonData: [userData['userFk']],
processData: false,
success: function (data) {
$('.footer').show();
printHorario(data);
}
});
}
function printHorario(horarios) {
var c = "in";
for (var i = 0; i < horarios.length; i++) {
if (i % 2 !== 0) {
c = "out";
} else {
c = "in";
}
if (horarios[i]["7_dias_antes"] === "total") {
if (horarios.length > (i + 1)) {
printTotalHours(horarios[i + 1]);
}
if (horarios.length > (i + 2)) {
$(".total").text('Total: ' + horarios[i + 2]["1_dia_antes"] + 'h');
}
break;
}
$(".listHorario").append('<li><div class="time ' + ifIsEmpty(horarios[i]["6_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["6_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["5_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["5_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["4_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["4_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["3_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["3_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["2_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["2_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["1_dia_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["1_dia_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["mismo_dia"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["mismo_dia"]) + '</p></div></li>');
}
var listWeekName = printWeek();
$(".listHorario").prepend('<li class="headerLi"><label>' + listWeekName[5] + '</label><label>' + listWeekName[4] + '</label><label>' + listWeekName[3] + '</label><label>' + listWeekName[2] + '</label><label>' + listWeekName[1] + '</label><label>' + listWeekName[0] + '</label><label class="hoy">HOY</label></li>');
}
function printTotalHours(horarios) {
$(".listHorario").append('<li><br><hr></li>');
$(".listHorario").append('<li><div class="time">' + ifIsEmptyText(horarios["6_dias_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["5_dias_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["4_dias_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["3_dias_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["2_dias_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["1_dia_antes"])
+ '</div><div class="time">' + ifIsEmptyText(horarios["mismo_dia"])
+ '</div></li>');
}
function printWeek() {
var listWeekName = [];
var curr = new Date();
for (var i = 0; i < 7; i++) {
curr.setDate(curr.getDate() - 1);
listWeekName.push(weekDays[curr.getDay()]);
}
return listWeekName;
}
var weekDays = [
'Domingo',
'Lunes',
'Martes',
'Miércoles',
'Jueves',
'Viernes',
'Sábado'
];
function printError(msg){
$(".txtConfirm").empty();
$(".txtConfirm").append(msg);
$(".txtConfirm").append("<br>");
$(".loading").fadeOut(200);
$(".confirm").addClass('confirmKO');
}
function printErrores(errores) {
var error ='';
$(".txtConfirm").empty();
for (var i = 0; i < errores.length; i++) {
if (errores[i].error) {
error += errores[i].error + "<br>";
}
}
printError(error);
}
function ifIsEmpty(value) {
if (value.trim().length === 0) {
return "hide";
} else {
return "show";
}
}
function ifIsEmptyText(value) {
if (value.trim().length === 0) {
return "00:00";
} else {
return value;
}
}
function cerrar(){
$(".loading").fadeIn(200);
localStorage.removeItem("userData");
setTimeout(function () {
window.history.back();
}, 200);
}

45
js/index.js Normal file
View File

@ -0,0 +1,45 @@
var pin = "";
var datoUsuario = "";
$(document).ready(function () {
FastClick.attach(document.body);
setEvents();
});
function setEvents() {
$(".btnnum").on("click", function () {
pin += parseInt($(this).children().html());
$("#txtPin").text(pin);
});
$(".btnCancel").on("click", function () {
pin = "";
$("#txtPin").text("USUARIO");
});
$(".btnOk").on("click", login);
$(".btnconfirmar").on("click", function () {
localStorage.setItem("userData", JSON.stringify(datoUsuario));
setTimeout(function () {
window.location = "clockIn.html";
}, 200);
$(".loading").fadeOut(200);
});
}
function login() {
$.post({
urlPath: 'login',
jsonData: [pin],
processData: false,
success: function (data) {
localStorage.setItem("userData", JSON.stringify(data));
$("#txtPin").text("USUARIO O DNI");
pin = "";
window.location = "clockIn.html";
$(".loading").fadeOut(200);
}
});
}

66
js/main.js Normal file
View File

@ -0,0 +1,66 @@
var config = config[process.env.NODE_ENV];
var urlBase = config.urlBase;
function printError(msg){
$(".txtConfirm").empty();
$(".txtConfirm").append(msg);
$(".confirm").addClass('confirmKO');
pin = "";
$("#txtPin").text("USUARIO");
setTimeout(function() {
$(".confirm").removeClass('confirmKO');
}, 1500);
}
$.ajaxPrefilter(function(xhr) {
$(".loading").fadeIn(200);
Object.assign(xhr, {
url: `${urlBase}/workerTimeControl/${xhr.urlPath}`,
headers: {
'version': '1',
'aplicacion': 'workerTimeControl'
},
timeout: 1000,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
processData: false,
data: JSON.stringify(xhr.jsonData),
error: function (xhr, textStatus, err) {
var mensaje;
switch (textStatus){
case 'parsererror':
mensaje = 'Requested JSON parse failed';
break;
case 'timeout':
mensaje = 'Time out error';
break;
case 'abort':
mensaje = 'Ajax request aborted';
break;
case 'error':
switch (xhr.status){
case 0:
mensaje = 'Not connect: Verify Network';
break;
case 555:
mensaje = JSON.parse(xhr.statusText).Message;
break;
default:
if (xhr.status >= 400 && xhr.status < 500)
mensaje = xhr.statusText;
else
mensaje = 'Ha ocurrido un error, consulta con informática';
}
break;
default:
mensaje = 'Ha ocurrido un error, consulta con informática';
}
printError(mensaje);
},
complete: function() {
$(".loading").fadeOut(200);
}
});
});

18
package-lock.json generated Normal file
View File

@ -0,0 +1,18 @@
{
"name": "es.verdnatura.fichador",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"fastclick": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/fastclick/-/fastclick-1.0.6.tgz",
"integrity": "sha1-FhYlsnsaWAZAWTa9qaLBkm0Gvmo="
},
"jquery": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
}
}
}

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "es.verdnatura.worker-time-control",
"displayName": "Fichador",
"version": "1.0.0",
"description": "Fichador",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Verdnatura Levante SL",
"license": "GPL-3.0",
"dependencies": {
"fastclick": "^1.0.6",
"jquery": "^3.6.0"
}
}