ashwini před 2 měsíci
revize
60f5e127a0

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+/node_modules

+ 92 - 0
README.md

@@ -0,0 +1,92 @@
+# Daily Visit Report
+
+
+
+## Getting started
+
+To make it easy for you to get started with GitLab, here's a list of recommended next steps.
+
+Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
+
+## Add your files
+
+- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
+- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
+
+```
+cd existing_repo
+git remote add origin http://192.168.6.229/gitlab-instance-da643b4a/daily-visit-report.git
+git branch -M main
+git push -uf origin main
+```
+
+## Integrate with your tools
+
+- [ ] [Set up project integrations](http://192.168.6.229/gitlab-instance-da643b4a/daily-visit-report/-/settings/integrations)
+
+## Collaborate with your team
+
+- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
+- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
+- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
+- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
+- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
+
+## Test and Deploy
+
+Use the built-in continuous integration in GitLab.
+
+- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
+- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
+- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
+- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
+- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
+
+***
+
+# Editing this README
+
+When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
+
+## Suggestions for a good README
+Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
+
+## Name
+Choose a self-explaining name for your project.
+
+## Description
+Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
+
+## Badges
+On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
+
+## Visuals
+Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
+
+## Installation
+Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
+
+## Usage
+Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
+
+## Support
+Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
+
+## Roadmap
+If you have ideas for releases in the future, it is a good idea to list them in the README.
+
+## Contributing
+State if you are open to contributions and what your requirements are for accepting them.
+
+For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
+
+You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
+
+## Authors and acknowledgment
+Show your appreciation to those who have contributed to the project.
+
+## License
+For open source projects, say how it is licensed.
+
+## Project status
+If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

+ 32 - 0
app.js

@@ -0,0 +1,32 @@
+const express = require('express');
+const bodyParser = require('body-parser');
+const routes = require('../DVR-backend/routes/route');
+//const routes = require('../DVR-BACKEND/routes/route');
+
+const app = express();
+const cors= require('cors');
+const port = process.env.PORT || 9000;
+
+app.use(bodyParser.urlencoded({ extended: false }));
+
+app.use(express.json());
+app.use(express.urlencoded({
+  extended: true
+}));
+
+app.use(cors())
+app.use('/', routes);
+
+app.all('/*', function (req, res, next) {
+  res.header("Access-Control-Allow-Origin", "*");
+  res.header("Access-Control-Allow-Methods", "*");
+  res.header("Access-Control-Allow-Headers", "*");
+  next();
+});
+
+
+
+
+app.listen(port, () => {
+  console.log(` listening port at http://localhost:${port}`)
+});

+ 13 - 0
configs/config.json

@@ -0,0 +1,13 @@
+{
+    "database": {
+        "host": "52.221.194.168",
+        "user": "root",
+        "password": "dvr@123",
+        "database": "dvr",
+        "port":"3306"
+    },
+    "token_header_key":"ABCDEF$123"
+  
+}
+
+

+ 16 - 0
configs/config_local.json

@@ -0,0 +1,16 @@
+{
+    "database": {
+        "host": "localhost",
+        "user": "root",
+        "password": "root@123",
+        "database": "dvr"
+    },
+    "token_header_key":"ABCDEF$123",
+
+    "logfolderpath":""
+
+    
+
+}
+
+

+ 2476 - 0
controllers/dvrReportController.js

@@ -0,0 +1,2476 @@
+const db = require("../services/dbconnection");
+const validation = require("../controllers/validation")
+const moment = require("moment");
+const logger = require('../utils/logger');
+
+module.exports.createContactEntry = async (req, res) => {
+    const validationResp = await validation.createContactentrycheck(req);
+    const createdate = new Date();
+
+    if (validationResp.status) {
+        try {
+            var stage_id;
+            if (req.body.email_id == null || req.body.mobile_no == null) {
+                //|| req.body.department == null || req.body.designation == null) {
+                stage_id = 2;
+                console.log(stage_id);
+
+            } else {
+                stage_id = 1;
+            }
+
+            const query = "INSERT INTO contact_master(first_name,last_name,mobile_number,email_id,designation,department,function_area,created_by,created_on,customer_id,stage_id)" +
+                "VALUES(?,?,?,?,?,?,?,?,?,?,?)";
+            const values = [req.body.first_name, req.body.last_name, req.body.mobile_no, req.body.email_id, req.body.designation, req.body.department, req.body.function, req.body.created_by, createdate, req.body.contact_for, stage_id]
+            const res1 = await db.executevaluesquery(query, values);
+
+            logger.info('log to file', res);
+
+
+            if (res1) {
+
+                const query = "select contact_id,customer_id,first_name,last_name  from contact_master order by contact_id desc limit 1";
+                const queryresult = await db.executequery(query);
+
+                console.log("queryresult", queryresult);
+
+                res.send({
+                    status: true,
+                    data: [{
+                        message: "Contact Entry created Successfully ",
+                        createStatus: "0",
+                        lastinsertedData: queryresult[0].first_name + " " + queryresult[0].last_name,
+                        exception: {
+                            errorid: "",
+                            errormessage: "No Errors"
+                        }
+                    }],
+                    error: " "
+
+
+                })
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        message: "",
+                        createStatus: "1",
+                        exception: {
+                            errorid: "404",
+                            errormessage: "Bad request"
+                        }
+                    }],
+                    error: ""
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true,
+                data: [{
+                    message: "",
+                    createStatus: "1",
+                    exception: {
+                        errorid: "404",
+                        errormessage: "Bad request"
+                    }
+                }],
+                error: err
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+
+module.exports.getdvrDetails = async (req, res) => {
+    console.log("in dvr details for one id");
+    const validationResp = await validation.getdvrDetailscheck(req);
+    if (validationResp.status) {
+        try {
+            const query = "SELECT d.dvr_id,d.date_of_visit,d.customer_name,d.contact_name,d.physical_meeting,d.message,s.stage_desc,d.stage_id,d.created_on FROM dvr_report d JOIN stage_master s ON d.stage_id=s.stage_id WHERE d.dvr_id = '" + req.query.dvrid + "' and d.delete_id = 0";
+            console.log("query", query)
+            const queryresult = await db.executequery(query);
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [
+                        {
+                            getdvrDataStatus: '0',
+                            mesasge: "Data Found",
+                            visit_date: queryresult[0].date_of_visit,
+                            customer_name: queryresult[0].customer_name,
+                            contact_name: queryresult[0].contact_name,
+                            mesasge: queryresult[0].message,
+                            physical_metting: queryresult[0].physical_meeting,
+                            stage_desc: queryresult[0].stage_desc,
+                            stage_id: queryresult[0].stage_id,
+                            created_on: queryresult[0].created_on
+                        }
+                    ],
+                    errors: ""
+
+                })
+
+            } else {
+                res.send({
+                    status: false,
+                    data: [
+                        {
+                            getdvrDataStatus: '1',
+                            mesasge: "Data not Found"
+                        }
+                    ],
+                    errors: ""
+
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+}
+
+
+module.exports.getselectionData = async (req, res) => {
+    try {
+        var customerData = [];
+        var contactData = [];
+        var stageData = [];
+
+        const query = "SELECT customer_id,customer_name FROM customer_master";
+        const queryresult = await db.executequery(query);
+
+        if (queryresult.length > 0) {
+            for (var i = 0; i < queryresult.length; i++) {
+                customerData.push(queryresult[i])
+            }
+
+        }
+
+        const query1 = "SELECT contact_id,first_name,last_name FROM contact_master";
+        const queryresult1 = await db.executequery(query1);
+
+        if (queryresult1.length > 0) {
+            for (var i = 0; i < queryresult1.length; i++) {
+                contactData.push(queryresult1[i])
+            }
+        }
+
+        const query2 = "SELECT stage_id,stage_desc FROM stage_master";
+        const queryresult2 = await db.executequery(query2);
+
+        if (queryresult2.length > 0) {
+            for (var i = 0; i < queryresult2.length; i++) {
+                stageData.push(queryresult2[i])
+            }
+        }
+
+
+        res.send({
+            status: true,
+            data: [{
+                customerData: customerData
+            }, {
+                contactData: contactData
+            }, {
+                stageData: stageData
+            }
+            ],
+            error: ""
+        })
+
+
+    }
+    catch (err) {
+        console.log(err)
+        res.send({
+            status: true, data: [], error: err
+        })
+    }
+}
+
+
+module.exports.getdashboarddetails = async (req, res) => {
+    try {
+        var login_id = req.query.login_id;
+        var sale_person = req.query.salePerson;
+        var customer = req.query.customer;
+        var customer_id = req.query.customerid;
+        var rol_des;
+        var dvrlist = [];
+        var rolData;
+        var rolData1;
+        var dates, firstdate, seconddate;
+
+        var user_id_for_mapp;
+        var emai_id;
+
+        const findRole = "call SP_roleidentify1('" + login_id + "')";
+        const roleidentify = await db.executequery(findRole);
+        rolData = roleidentify[0];
+
+        console.log("findRole", findRole);
+        rolData.forEach(function (item) {
+            console.log(item.role_des);
+            rolData1 = item.role_des;
+            user_id_for_mapp = item.user_id11;
+        });
+
+        //console.log("item",item);
+        rol_des = rolData1;
+
+        console.log("user_id_for_mapp", user_id_for_mapp)
+
+        if (rol_des == 'admin') {
+            //admin
+            console.log("req.query.searchfiltertype", req.query.searchfiltertype);
+            if (req.query.searchfiltertype) {
+                if (req.query.searchfiltertype.length > 1) {
+                    //date seach filter
+                    console.log("in ifffffffffffffffffffffffffffff");
+                    var searchfilter = req.query.searchfiltertype;
+                    console.log("searchfilter", searchfilter);
+                    if (searchfilter == "undefineddate") {
+                        console.log("date not pass");
+                        firstdate = '';
+                        seconddate = '';
+
+                    } else {
+                        dates = searchfilter.split("-");
+                        console.log("dates", dates)
+
+                        firstdate = dates[0] + ' 00:00:00';
+                        seconddate = dates[1] + ' 23:59:59';
+                    }
+
+
+
+                    var querydvr;
+                    var countquery;
+
+                    console.log("firstdate", firstdate);
+                    console.log("seconddate", seconddate);
+                    console.log("ooooooooooooo", sale_person);
+                    if (sale_person != undefined && sale_person != 'undefined' && sale_person != 'all') {
+                        var data = sale_person.split(" ");
+                        console.log("data----->", data)
+
+                        console.log("need to find sale person email id for cound data");
+
+                        var query = "select user_id,login_id from user_master where first_name like '%" + data[0] + "%' and  last_name like '%" + data[1] + "%'";
+                        const res_user = await db.executequery(query);
+                        console.log("res_user", res_user);
+                        console.log("res_user----------->", res_user[0].login_id)
+                        emai_id = res_user[0].login_id;
+
+                    }
+
+                    console.log("customer", customer, "customer_id", customer_id, " email_id-->", emai_id);
+
+                    if (sale_person != undefined && customer == undefined && searchfilter == 'undefineddate' && sale_person != 'all') {
+                        console.log("only for sale_person");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + '' + "','" + '' + "')";
+
+                    } else if (sale_person == undefined && customer != undefined && searchfilter == 'undefineddate' && sale_person != 'all' && customer != 'all') {
+                        console.log("only for customer");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where customer_name like '%" + customer + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + customer + "','" + customer_id + "')";
+
+                    } else if (sale_person != undefined && customer != undefined && customer_id != undefined && sale_person != 'all') {
+                        console.log("for sales_person and Customer");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where customer_name like '%" + customer + "%' and sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + customer + "','" + customer_id + "')";
+
+                    } else if (sale_person != 'all' && firstdate != undefined && seconddate != undefined && sale_person != undefined) {
+                        console.log("date and sale_person");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and  sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + '' + "','" + '' + "')";
+
+
+                    } else if (customer != undefined && firstdate != undefined && seconddate != undefined && sale_person == undefined) {
+                        console.log("for date and customer");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and customer_name like '%" + customer + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + customer + "','" + customer_id + "')";
+
+                    } else if (customer != undefined && firstdate != undefined && seconddate != undefined && sale_person != undefined) {
+                        console.log("all filters");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and customer_name like '%" + customer + "%' and  sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + customer + "','" + customer_id + "')";
+                    }
+                    else {
+                        console.log("only for date");
+                        querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + '' + "','" + '' + "')";
+
+                    }
+
+
+                    // if (sale_person == undefined && customer == undefined && searchfilter != "undefineddate" && sale_person == 'undefined') {
+                    //     console.log("only for date")
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + '' + "','" + '' + "')";
+
+                    // } else if (sale_person != undefined && searchfilter == "undefineddate" && customer == undefined && sale_person !='undefined') {
+                    //     console.log("for sale_peron only")
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + '' + "','" + '' + "')";
+
+                    // }else if(customer != undefined && customer_id !=undefined && searchfilter == "undefineddate" && sale_person !=undefined && sale_person != 'undefined'){
+                    //     console.log("for customer only");
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where customer_name like '%" + customer + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + customer + "','" + customer_id + "')";
+
+                    // }else if(customer !=undefined && sale_person !='undefined' && sale_person !=undefined && searchfilter == "undefineddate"){
+                    //    console.log("for customer and sale_person")
+                    //    querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where customer_name like '%" + customer + "%' and sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //    countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + customer + "','" + customer_id + "')";
+
+                    // }else if(customer !=undefined && searchfilter != "undefineddate" && sale_person ==undefined){
+                    //     console.log("customer and date filter");
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and customer_name like '%" + customer + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + '' + "','" + customer + "','" + customer_id + "')";
+
+                    // }else if(customer !=undefined && searchfilter != "undefineddate" && sale_person !=undefined){
+                    //     console.log("customer, sale person and date")
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and customer_name like '%" + customer + "%' and  sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + customer + "','" + customer_id + "')";
+
+                    // }
+                    // else{
+                    //     console.log("for date and sale_person filters");
+                    //     querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "' and  sale_person like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    //     countquery = "call SP_CountDashboard_admin ('" + firstdate + "','" + seconddate + "','" + emai_id + "','" + '' + "','" + '' + "')";
+
+                    // }
+                    console.log(querydvr);
+                    const queryresult = await db.executequery(querydvr);
+
+                    console.log("firstdate------>", firstdate, "seconddate-------->", seconddate)
+                    if (firstdate == undefined && seconddate == undefined) {
+
+                    } else {
+                        //date is request of api
+                    }
+
+
+
+
+                    console.log("countquery=========>", countquery)
+                    const queryresult1 = await db.executequery(countquery);
+                    console.log("queryresult1========>", queryresult1)
+                    var countdata = queryresult1[0];
+                    console.log("countdata", countdata, queryresult.length);
+                    for (var i = 0; i < queryresult.length; i++) {
+                        //  console.log(queryresult[i]);
+                        dvrlist.push(queryresult[i])
+                    }
+
+                    if (queryresult.length > 0) {
+
+
+                        res.send({
+                            status: true,
+                            data: [{
+                                getdvrDataStatus: '0',
+                                mesasge: "Data Found",
+                                countdata: [{
+                                    no_of_visit: (countdata == undefined ? queryresult.length : countdata[0].allcount),
+                                    no_of_completed: (countdata == undefined ? 0 : countdata[0].completed),
+                                    no_of_incompleted: (countdata == undefined ? 0 : countdata[0].incompleted),
+                                    no_of_contact: (countdata == undefined ? 0 : countdata[0].contactcount)
+
+                                }],
+                                dvrlist,
+                            }],
+                            error: " "
+
+                        })
+
+
+                    } else {
+
+                        res.send({
+                            status: false,
+                            data: [{
+                                getdvrDataStatus: '1',
+                                mesasge: "Data Not Found"
+                            }],
+                            error: " "
+
+                        })
+
+                    }
+
+
+                } else {
+
+                    //last week, month,year searchfilter
+
+                    console.log("in admin else part")
+                    if (req.query.searchfiltertype == '0') {
+                        //for last week
+                        var dvrlist = [];
+                        const lastweek = await getLastWeeksDate();
+                        const currentDate = await getcurrentDate();
+                        console.log(lastweek)
+                        if (sale_person == undefined) {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastweek + "' and '" + currentDate + "' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+
+                        } else {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastweek + "' and '" + currentDate + "' and  contact_name like '%" + sale_person + "%'  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        }
+
+                        const countquery = "call SP_CountDashboard ('" + lastweek + "','" + currentDate + "','" + '' + "')";
+                        const queryresult = await db.executequery(querydvr);
+
+                        console.log("countquery", countquery);
+                        const queryresult1 = await db.executequery(countquery);
+                        var countdata = queryresult1[0];
+
+                        for (var i = 0; i < queryresult.length; i++) {
+                            // console.log(queryresult[i]);
+                            dvrlist.push(queryresult[i])
+                        }
+
+                        if (queryresult.length > 0) {
+
+
+
+                            res.send({
+                                status: true,
+                                data: [{
+                                    getdvrDataStatus: '0',
+                                    mesasge: "Data Found",
+                                    countdata: [{
+                                        no_of_visit: countdata[0].allcount,
+                                        no_of_completed: countdata[0].completed,
+                                        no_of_incompleted: countdata[0].incompleted,
+                                        no_of_contact: countdata[0].contactcount
+                                    }],
+                                    dvrlist,
+                                }],
+                                error: " "
+
+                            })
+
+
+                        } else {
+
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+
+                    } else if (req.query.searchfiltertype == '2') {
+                        //for last year
+                        var dvrlist = [];
+                        const lastyeardate = await getLastYearDate();
+                        const currentDate = await getcurrentDate();
+
+                        if (sale_person == undefined) {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastyeardate + "' and '" + currentDate + "' and delete_id=0  order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+
+                        } else {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastyeardate + "' and '" + currentDate + "' and  contact_name like '%" + sale_person + "%'  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc ";
+                        }
+
+                        console.log("lastyeardate", lastyeardate, " ", currentDate);
+                        const countquery = "call SP_CountDashboard ('" + lastyeardate + "' , '" + currentDate + "','" + '' + "')";
+                        const queryresult = await db.executequery(querydvr);
+                        console.log("querydvr-------->", querydvr);
+
+                        const queryresult1 = await db.executequery(countquery);
+                        var countdata = queryresult1[0];
+                        for (var i = 0; i < queryresult.length; i++) {
+                            //  console.log(queryresult[i]);
+                            dvrlist.push(queryresult[i])
+                        }
+
+                        if (queryresult.length > 0) {
+                            // res.send({
+                            //     getdvrDataStatus: '0',
+                            //     mesasge: "Data Found",
+                            //     countdata: [{
+                            //         no_of_visit: countdata[0].allcount,
+                            //         no_of_completed: countdata[0].completed,
+                            //         no_of_incompleted: countdata[0].incompleted,
+                            //         no_of_contact: countdata[0].contactcount
+                            //     }],
+                            //     dvrlist
+
+
+                            // })
+
+                            res.send({
+                                status: true,
+                                data: [{
+                                    getdvrDataStatus: '0',
+                                    mesasge: "Data Found",
+                                    countdata: [{
+                                        no_of_visit: countdata[0].allcount,
+                                        no_of_completed: countdata[0].completed,
+                                        no_of_incompleted: countdata[0].incompleted,
+                                        no_of_contact: countdata[0].contactcount
+                                    }],
+                                    dvrlist,
+                                }],
+                                error: " "
+
+                            })
+
+
+                        } else {
+                            // res.send({
+                            //     getdvrDataStatus: '1',
+                            //     mesasge: "Data Not Found"
+                            // })
+
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+                    } else {
+                        //by default for last month
+
+                        console.log("normal month");
+                        var dvrlist = [];
+                        const lastmonthDate = await getLastMonthDate();
+                        const currentDate = await getcurrentDate();
+                        console.log("lastmonthDate", lastmonthDate, "currentDate", currentDate);
+
+                        if (sale_person == undefined) {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+
+                        }
+                        else {
+                            querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "' and  contact_name like '%" + sale_person + "%'  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        }
+
+                        const countquery = "call SP_CountDashboard ('" + lastmonthDate + "' , '" + currentDate + "','" + '' + "')";
+                        const queryresult = await db.executequery(querydvr);
+
+
+                        const queryresult1 = await db.executequery(countquery);
+                        var countdata = queryresult1[0];
+
+
+                        for (var i = 0; i < queryresult.length; i++) {
+                            dvrlist.push(queryresult[i])
+                        }
+
+                        if (queryresult.length > 0) {
+                            res.send({
+                                status: true,
+                                data: [{
+                                    getdvrDataStatus: '0',
+                                    mesasge: "Data Found",
+                                    countdata: [{
+                                        no_of_visit: countdata[0].allcount,
+                                        no_of_completed: countdata[0].completed,
+                                        no_of_incompleted: countdata[0].incompleted,
+                                        no_of_contact: countdata[0].contactcount
+                                    }],
+                                    dvrlist,
+                                }],
+                                error: " "
+
+                            })
+
+                        } else {
+                            // res.send({
+                            //     getdvrDataStatus: '1',
+                            //     mesasge: "Data Not Found"
+                            // })
+
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+                    }
+
+
+                }
+            } else {
+                var dvrlist = [];
+                console.log("in else latest condition")
+                const lastmonthDate = await getLastMonthDate();
+                const currentDate = await getcurrentDate();
+                console.log("lastmonthDate ", lastmonthDate, "  currentDate", currentDate)
+                if (sale_person == undefined) {
+                    querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+
+                } else {
+                    querydvr = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "' and  contact_name like '%" + sale_person + "%' and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc ";
+                }
+                const countquery = "call SP_CountDashboard ('" + lastmonthDate + "' , '" + currentDate + "' ,'" + '' + "')";
+
+                console.log("countquery", countquery);
+                console.log("querydvr", querydvr)
+                const queryresult1 = await db.executequery(countquery);
+                var countdata = queryresult1[0];
+
+                console.log("countdata", countdata);
+                const queryresult = await db.executequery(querydvr);
+
+                for (var i = 0; i < queryresult.length; i++) {
+                    // console.log(queryresult[i]);
+                    dvrlist.push(queryresult[i])
+                }
+
+                // if (dvrlist.length > 0) {
+                //     for (var i = 0; i < dvrlist.length; i++) {
+
+                //     }
+
+                // }
+
+
+
+
+
+                if (queryresult.length > 0) {
+
+                    res.send({
+                        status: true,
+                        data: [{
+                            getdvrDataStatus: '0',
+                            mesasge: "Data Found",
+                            countdata: [{
+                                no_of_visit: countdata[0].allcount,
+                                no_of_completed: countdata[0].completed,
+                                no_of_incompleted: countdata[0].incompleted,
+                                no_of_contact: countdata[0].contactcount
+                            }],
+                            dvrlist,
+                        }],
+                        error: " "
+
+                    })
+
+                } else {
+                    res.send({
+                        status: false,
+                        data: [{
+                            getdvrDataStatus: '1',
+                            mesasge: "Data Not Found"
+                        }],
+                        error: " "
+
+                    })
+
+                }
+
+            }
+
+        } else {
+            //other user
+            console.log("in other users");
+            var getcustomer_id = [];
+            var getcustomer_name = [];
+
+
+            if (user_id_for_mapp) {
+                const query = "select customer_id,user_id from customer_user_mapping where user_id=" + user_id_for_mapp;
+                const queryresult_id = await db.executequery(query);
+                console.log("queryresult", queryresult_id);
+                for (var i = 0; i < queryresult_id.length; i++) {
+                    getcustomer_id.push(queryresult_id[i].customer_id);
+                }
+                console.log(getcustomer_id);
+            }
+
+            if (req.query.searchfiltertype) {
+                console.log("in searchfiltertype ");
+                if (req.query.searchfiltertype.length > 1) {
+                    console.log("datafliter");
+                    //date seach filter
+                    var searchfilter = req.query.searchfiltertype;
+                    const dates = searchfilter.split("-");
+                    console.log("dates", dates)
+
+                    const firstdate = dates[0] + ' 00:00:01';
+                    const seconddate = dates[1] + ' 23:59:59';
+
+                    console.log(firstdate);
+                    console.log(seconddate);
+
+                    if (getcustomer_id.length > 0) {
+                        console.log("data present in custmer mapping table");
+                        const getcust_name = "select customer_id,customer_name from customer_master where customer_id in(" + getcustomer_id + ")";
+                        const getqueryresult1 = await db.executequery(getcust_name);
+                        console.log("getcust_name", getcust_name)
+                        console.log("getcust_name============>", getqueryresult1);
+                        for (var i = 0; i < getqueryresult1.length; i++) {
+                            getcustomer_name.push(getqueryresult1[i].customer_name);
+                        }
+                        console.log("getcustomer_name", getcustomer_name);
+
+                        if (getcustomer_name) {
+                            for (var i = 0; i < getcustomer_name.length; i++) {
+                                const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "'  and  customer_name in ('" + getcustomer_name[i] + "')  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                                dvrlist[i] = await db.executequery(query);
+
+                            }
+
+                            var plano = dvrlist.reduce((acc, el) => acc.concat(el), []);
+                            //console.log("plano",plano)
+
+
+                            dvrlist = plano;
+                            console.log("finalResult=================>", dvrlist);
+
+                            const countquery = "call SP_CountDashboard ('" + firstdate + "' , '" + seconddate + "','" + login_id + "')";
+                            const queryresult1 = await db.executequery(countquery);
+                            console.log("queryresult1", countquery);
+                            var countdata = queryresult1[0];
+
+
+                            if (dvrlist.length > 0) {
+                                res.send({
+                                    status: true,
+                                    data: [{
+                                        getdvrDataStatus: '0',
+                                        mesasge: "Data Found",
+                                        countdata: [{
+                                            no_of_visit: countdata[0].allcount,
+                                            no_of_completed: countdata[0].completed,
+                                            no_of_incompleted: countdata[0].incompleted,
+                                            no_of_contact: countdata[0].contactcount
+                                        }],
+                                        dvrlist
+                                    }],
+                                    error: " "
+
+
+                                })
+
+                            } else {
+                                res.send({
+                                    status: false,
+                                    data: [{
+                                        getdvrDataStatus: '1',
+                                        mesasge: "Data Not Found"
+                                    }],
+                                    error: " "
+
+                                })
+
+                            }
+
+
+                        }
+
+
+                    } else {
+                        console.log("data not present in custmer mapping table");
+                        res.send({
+                            status: false,
+                            data: [{
+                                getdvrDataStatus: '1',
+                                mesasge: "Data Not Found"
+                            }],
+                            error: " "
+
+                        })
+
+                    }
+
+
+                    // const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + firstdate + "' and '" + seconddate + "'  and  login_id='" + login_id + "' order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                    // const countquery = "call SP_CountDashboard ('" + firstdate + "' , '" + seconddate + + "','" + login_id + "')";
+                    // const queryresult = await db.executequery(query);
+
+                    // const queryresult1 = await db.executequery(countquery);
+                    // var countdata = queryresult1[0];
+                    // for (var i = 0; i < queryresult.length; i++) {
+                    //     console.log(queryresult[i]);
+                    //     dvrlist.push(queryresult[i])
+                    // }
+
+                    // if (queryresult.length > 0) {
+                    //     res.send({
+                    //         status: true,
+                    //         data: [{
+                    //             getdvrDataStatus: '0',
+                    //             mesasge: "Data Found",
+                    //             countdata: [{
+                    //                 no_of_visit: countdata[0].allcount,
+                    //                 no_of_completed: countdata[0].completed,
+                    //                 no_of_incompleted: countdata[0].incompleted,
+                    //                 no_of_contact: countdata[0].contactcount
+                    //             }],
+                    //             dvrlist,
+                    //         }],
+                    //         error: " "
+
+                    //     })
+
+
+                    // } else {
+                    //     res.send({
+                    //         status: false,
+                    //         data: [{
+                    //             getdvrDataStatus: '1',
+                    //             mesasge: "Data Not Found"
+                    //         }],
+                    //         error: " "
+
+                    //     })
+
+                    // }
+
+
+                } else {
+
+                    //last week, month,year searchfilter
+
+                    if (req.query.searchfiltertype == '0') {
+                        //for last week
+                        var dvrlist = [];
+                        const lastweek = await getLastWeeksDate();
+                        const currentDate = await getcurrentDate();
+
+                        if (getcustomer_id.length > 0) {
+                            console.log("data present in custmer mapping table");
+                            const getcust_name = "select customer_id,customer_name from customer_master where customer_id in(" + getcustomer_id + ")";
+                            const getqueryresult1 = await db.executequery(getcust_name);
+                            console.log("getcust_name", getcust_name)
+                            console.log("getcust_name============>", getqueryresult1);
+                            for (var i = 0; i < getqueryresult1.length; i++) {
+                                getcustomer_name.push(getqueryresult1[i].customer_name);
+                            }
+                            console.log("getcustomer_name", getcustomer_name);
+
+                            if (getcustomer_name) {
+                                for (var i = 0; i < getcustomer_name.length; i++) {
+                                    const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastweek + "' and '" + currentDate + "'  and  customer_name in ('" + getcustomer_name[i] + "')  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                                    dvrlist[i] = await db.executequery(query);
+
+                                }
+
+
+                                var plano = dvrlist.reduce((acc, el) => acc.concat(el), []);
+                                //console.log("plano",plano)
+
+
+                                dvrlist = plano;
+                                console.log("finalResult=================>", dvrlist);
+
+
+
+
+                                const countquery = "call SP_CountDashboard ('" + lastweek + "' , '" + currentDate + "','" + login_id + "')";
+                                const queryresult1 = await db.executequery(countquery);
+                                console.log("queryresult1", countquery);
+                                var countdata = queryresult1[0];
+
+
+                                if (dvrlist.length > 0) {
+                                    res.send({
+                                        status: true,
+                                        data: [{
+                                            getdvrDataStatus: '0',
+                                            mesasge: "Data Found",
+                                            countdata: [{
+                                                no_of_visit: countdata[0].allcount,
+                                                no_of_completed: countdata[0].completed,
+                                                no_of_incompleted: countdata[0].incompleted,
+                                                no_of_contact: countdata[0].contactcount
+                                            }],
+                                            dvrlist
+                                        }],
+                                        error: " "
+
+
+                                    })
+
+                                } else {
+                                    res.send({
+                                        status: false,
+                                        data: [{
+                                            getdvrDataStatus: '1',
+                                            mesasge: "Data Not Found"
+                                        }],
+                                        error: " "
+
+                                    })
+
+                                }
+
+
+                            }
+
+
+                        } else {
+                            console.log("data not present in custmer mapping table");
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+                        // const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastweek + "' and '" + currentDate + "'  and  login_id=" + login_id + "' order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        // const countquery = "call SP_CountDashboard ('" + lastweek + "' , '" + currentDate + "','" + login_id + "')";
+                        // const queryresult = await db.executequery(query);
+
+                        // const queryresult1 = await db.executequery(countquery);
+                        // var countdata = queryresult1[0];
+
+                        // for (var i = 0; i < queryresult.length; i++) {
+                        //     console.log(queryresult[i]);
+                        //     dvrlist.push(queryresult[i])
+                        // }
+
+                        // if (queryresult.length > 0) {
+                        //     res.send({
+                        //         status: true,
+                        //         data: [{
+                        //             getdvrDataStatus: '0',
+                        //             mesasge: "Data Found",
+                        //             countdata: [{
+                        //                 no_of_visit: countdata[0].allcount,
+                        //                 no_of_completed: countdata[0].completed,
+                        //                 no_of_incompleted: countdata[0].incompleted,
+                        //                 no_of_contact: countdata[0].contactcount
+                        //             }],
+                        //             dvrlist
+                        //         }],
+                        //         error: " "
+
+
+                        //     })
+
+
+                        // } else {
+                        //     res.send({
+                        //         status: false,
+                        //         data: [{
+                        //             getdvrDataStatus: '1',
+                        //             mesasge: "Data Not Found"
+                        //         }],
+                        //         error: " "
+
+                        //     })
+
+                        // }
+
+
+                    } else if (req.query.searchfiltertype == '2') {
+                        //for last year
+                        var dvrlist = [];
+                        const lastyeardate = await getLastYearDate();
+                        const currentDate = await getcurrentDate();
+
+                        if (getcustomer_id.length > 0) {
+                            console.log("data present in custmer mapping table");
+                            const getcust_name = "select customer_id,customer_name from customer_master where customer_id in(" + getcustomer_id + ")";
+                            const getqueryresult1 = await db.executequery(getcust_name);
+                            console.log("getcust_name", getcust_name)
+                            console.log("getcust_name============>", getqueryresult1);
+                            for (var i = 0; i < getqueryresult1.length; i++) {
+                                getcustomer_name.push(getqueryresult1[i].customer_name);
+                            }
+                            console.log("getcustomer_name", getcustomer_name);
+
+                            if (getcustomer_name) {
+                                for (var i = 0; i < getcustomer_name.length; i++) {
+                                    const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastyeardate + "' and '" + currentDate + "'  and  customer_name in ('" + getcustomer_name[i] + "')  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                                    dvrlist[i] = await db.executequery(query);
+
+                                }
+
+
+                                var plano = dvrlist.reduce((acc, el) => acc.concat(el), []);
+                                // console.log("plano",plano)
+
+
+                                dvrlist = plano;
+                                console.log("finalResult=================>", dvrlist);
+
+
+                                const countquery = "call SP_CountDashboard ('" + lastyeardate + "' , '" + currentDate + "','" + login_id + "')";
+                                const queryresult1 = await db.executequery(countquery);
+                                console.log("queryresult1", countquery);
+                                var countdata = queryresult1[0];
+
+
+                                if (dvrlist.length > 0) {
+                                    res.send({
+                                        status: true,
+                                        data: [{
+                                            getdvrDataStatus: '0',
+                                            mesasge: "Data Found",
+                                            countdata: [{
+                                                no_of_visit: countdata[0].allcount,
+                                                no_of_completed: countdata[0].completed,
+                                                no_of_incompleted: countdata[0].incompleted,
+                                                no_of_contact: countdata[0].contactcount
+                                            }],
+                                            dvrlist
+                                        }],
+                                        error: " "
+
+
+                                    })
+
+                                } else {
+                                    res.send({
+                                        status: false,
+                                        data: [{
+                                            getdvrDataStatus: '1',
+                                            mesasge: "Data Not Found"
+                                        }],
+                                        error: " "
+
+                                    })
+
+                                }
+
+
+                            }
+
+
+                        } else {
+                            console.log("data not present in custmer mapping table");
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+                        // const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastyeardate + "' and '" + currentDate + "'  and  login_id=" + login_id + "' order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        // const countquery = "call SP_CountDashboard ('" + lastyeardate + "' , '" + currentDate + "','" + login_id + "')";
+                        // const queryresult = await db.executequery(query);
+
+                        // const queryresult1 = await db.executequery(countquery);
+                        // var countdata = queryresult1[0];
+
+                        // for (var i = 0; i < queryresult.length; i++) {
+                        //     console.log(queryresult[i]);
+                        //     dvrlist.push(queryresult[i])
+                        // }
+
+                        // if (queryresult.length > 0) {
+                        //     res.send({
+                        //         status: true,
+                        //         data: [{
+                        //             getdvrDataStatus: '0',
+                        //             mesasge: "Data Found",
+                        //             countdata: [{
+                        //                 no_of_visit: countdata[0].allcount,
+                        //                 no_of_completed: countdata[0].completed,
+                        //                 no_of_incompleted: countdata[0].incompleted,
+                        //                 no_of_contact: countdata[0].contactcount
+                        //             }],
+                        //             dvrlist
+                        //         }],
+                        //         error: " "
+
+
+
+                        //     })
+
+
+                        // } else {
+                        //     res.send({
+                        //         status: false,
+                        //         data: [{
+                        //             getdvrDataStatus: '1',
+                        //             mesasge: "Data Not Found"
+                        //         }],
+                        //         error: " "
+
+                        //     })
+
+                        // }
+
+                    } else {
+                        //by default for last month
+
+                        console.log("users by last month", login_id);
+                        var dvrlist = [];
+                        const lastmonthDate = await getLastMonthDate();
+                        const currentDate = await getcurrentDate();
+
+
+
+                        if (getcustomer_id.length > 0) {
+                            console.log("data present in custmer mapping table");
+                            const getcust_name = "select customer_id,customer_name from customer_master where customer_id in(" + getcustomer_id + ")";
+                            const getqueryresult1 = await db.executequery(getcust_name);
+                            console.log("getcust_name", getcust_name)
+                            console.log("getcust_name============>", getqueryresult1);
+                            for (var i = 0; i < getqueryresult1.length; i++) {
+                                getcustomer_name.push(getqueryresult1[i].customer_name);
+                            }
+                            console.log("getcustomer_name", getcustomer_name);
+
+                            if (getcustomer_name) {
+                                for (var i = 0; i < getcustomer_name.length; i++) {
+                                    const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "'  and  customer_name in ('" + getcustomer_name[i] + "')  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                                    dvrlist[i] = await db.executequery(query);
+
+                                }
+
+
+                                var plano = dvrlist.reduce((acc, el) => acc.concat(el), []);
+                                //console.log("plano",plano)
+
+
+                                dvrlist = plano;
+                                console.log("finalResult=================>", dvrlist);
+
+
+                                const countquery = "call SP_CountDashboard ('" + lastmonthDate + "' , '" + currentDate + "','" + login_id + "')";
+                                const queryresult1 = await db.executequery(countquery);
+                                console.log("queryresult1", countquery);
+                                var countdata = queryresult1[0];
+
+
+                                if (dvrlist.length > 0) {
+                                    res.send({
+                                        status: true,
+                                        data: [{
+                                            getdvrDataStatus: '0',
+                                            mesasge: "Data Found",
+                                            countdata: [{
+                                                no_of_visit: countdata[0].allcount,
+                                                no_of_completed: countdata[0].completed,
+                                                no_of_incompleted: countdata[0].incompleted,
+                                                no_of_contact: countdata[0].contactcount
+                                            }],
+                                            dvrlist
+                                        }],
+                                        error: " "
+
+
+                                    })
+
+                                } else {
+                                    res.send({
+                                        status: false,
+                                        data: [{
+                                            getdvrDataStatus: '1',
+                                            mesasge: "Data Not Found"
+                                        }],
+                                        error: " "
+
+                                    })
+
+                                }
+
+
+                            }
+
+
+                        } else {
+                            console.log("data not present in custmer mapping table");
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+
+                        // const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "'  and  login_id=" + login_id + "' order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                        // const countquery = "call SP_CountDashboard ('" + lastmonthDate + "' , '" + currentDate + "','" + login_id + "')";
+                        // const queryresult = await db.executequery(query);
+
+                        // const queryresult1 = await db.executequery(countquery);
+                        // var countdata = queryresult1[0];
+
+                        // for (var i = 0; i < queryresult.length; i++) {
+                        //     console.log(queryresult[i]);
+                        //     dvrlist.push(queryresult[i])
+                        // }
+
+                        // if (queryresult.length > 0) {
+                        //     console.log("dvrlist12345", dvrlist);
+                        //     res.send({
+                        //         status: true,
+                        //         data: [{
+                        //             getdvrDataStatus: 0,
+                        //             mesasge: "Data Found",
+                        //             countdata: [{
+                        //                 no_of_visit: countdata[0].allcount,
+                        //                 no_of_completed: countdata[0].completed,
+                        //                 no_of_incompleted: countdata[0].incompleted,
+                        //                 no_of_contact: countdata[0].contactcount
+                        //             }],
+                        //             dvrlist
+                        //         }],
+                        //         error: " "
+
+
+                        //     })
+
+                        // } else {
+                        //     res.send({
+                        //         status: false,
+                        //         data: [{
+                        //             getdvrDataStatus: '1',
+                        //             mesasge: "Data Not Found"
+                        //         }],
+                        //         error: " "
+
+                        //     })
+
+                        // }
+
+                    }
+
+
+                }
+            } else {
+
+                console.log("in else part of bydefult");
+                var dvrlist = [];
+
+                const lastmonthDate = await getLastMonthDate();
+                const currentDate = await getcurrentDate();
+
+                console.log("lastmonthDate", lastmonthDate, "currentDate", currentDate);
+
+                if (getcustomer_id.length > 0) {
+                    console.log("data present in custmer mapping table");
+                    const getcust_name = "select customer_id,customer_name from customer_master where customer_id in(" + getcustomer_id + ")";
+                    const getqueryresult1 = await db.executequery(getcust_name);
+                    console.log("getcust_name", getcust_name)
+                    console.log("getcust_name============>", getqueryresult1);
+                    for (var i = 0; i < getqueryresult1.length; i++) {
+                        getcustomer_name.push(getqueryresult1[i].customer_name);
+                    }
+                    console.log("getcustomer_name", getcustomer_name);
+
+                    if (getcustomer_name) {
+                        for (var i = 0; i < getcustomer_name.length; i++) {
+                            const query = "select  dvr_id, date_of_visit,customer_name,contact_name,message,physical_meeting,sale_person from dvr_report where date_of_visit between'" + lastmonthDate + "' and '" + currentDate + "'  and  customer_name in ('" + getcustomer_name[i] + "')  and delete_id=0 order by DATE_FORMAT(date_of_visit, '%Y%m%d') desc";
+                            dvrlist[i] = await db.executequery(query);
+
+                        }
+
+                        var plano = dvrlist.reduce((acc, el) => acc.concat(el), []);
+                        //console.log("plano",plano)
+
+
+                        dvrlist = plano;
+                        console.log("finalResult=================>", dvrlist);
+
+
+
+                        const countquery = "call SP_CountDashboard ('" + lastmonthDate + "' , '" + currentDate + "','" + login_id + "')";
+                        const queryresult1 = await db.executequery(countquery);
+                        console.log("queryresult1", countquery);
+                        var countdata = queryresult1[0];
+
+
+                        if (dvrlist.length > 0) {
+                            res.send({
+                                status: true,
+                                data: [{
+                                    getdvrDataStatus: '0',
+                                    mesasge: "Data Found",
+                                    countdata: [{
+                                        no_of_visit: countdata[0].allcount,
+                                        no_of_completed: countdata[0].completed,
+                                        no_of_incompleted: countdata[0].incompleted,
+                                        no_of_contact: countdata[0].contactcount
+                                    }],
+                                    dvrlist
+                                }],
+                                error: " "
+
+
+                            })
+
+                        } else {
+                            res.send({
+                                status: false,
+                                data: [{
+                                    getdvrDataStatus: '1',
+                                    mesasge: "Data Not Found"
+                                }],
+                                error: " "
+
+                            })
+
+                        }
+
+
+                    }
+
+
+                } else {
+                    console.log("data not present in custmer mapping table");
+                    res.send({
+                        status: false,
+                        data: [{
+                            getdvrDataStatus: '1',
+                            mesasge: "Data Not Found"
+                        }],
+                        error: " "
+
+                    })
+
+                }
+
+
+
+            }
+
+        }
+    }
+    catch (err) {
+        console.log(err)
+        res.send({
+            status: true,
+            data: [],
+            error: err,
+            getdvrDataStatus: '1',
+        })
+    }
+}
+
+
+
+
+module.exports.createDvrEntry = async (req, res) => {
+    const validationResp = await validation.createDvrentrycheck(req);
+    const createdate = new Date();
+
+    if (validationResp.status) {
+        try {
+
+            console.log(" req.body.login_id", req.body.created_by);
+            const date_of_visit = new Date(req.body.visit_date);
+            //const date_of_visit=req.body.visit_date;
+
+            const query = "INSERT INTO dvr_report(date_of_visit,customer_name,contact_name,physical_meeting,message,created_by,created_on,stage_id,login_id,sale_person,delete_id)" +
+                "VALUES(?,?,?,?,?,?,?,?,?,?,?)";
+            const values = [date_of_visit, req.body.customer_name, req.body.contact_name, req.body.physical_metting, req.body.message, req.body.created_by, createdate, req.body.stage_id, req.body.created_by, req.body.sale_person, 0]
+
+            // console.log("query",query);
+            //console.log("values",values);
+            const res1 = await db.executevaluesquery(query, values);
+            console.log("res1", res1);
+            if (res1) {
+                res.send({
+                    status: true,
+                    data: [{
+                        message: "Daily visit Entry created Successfully.",
+                        createDvrStatus: "0",
+                        exception: {
+                            errorid: "",
+                            errormessage: "No Errors"
+                        }
+                    }],
+                    errors: ""
+
+
+                })
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        message: "",
+                        createDvrStatus: "1",
+                        exception: {
+                            errorid: "404",
+                            errormessage: "Bad request"
+                        }
+                    }],
+                    errors: ""
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: false,
+                data: [{
+                    message: "",
+                    createDvrStatus: "1",
+                    exception: {
+                        errorid: "404",
+                        errormessage: "Bad request"
+                    }
+                }],
+                errors: ""
+
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+
+
+module.exports.updatedvrDetails = async (req, res) => {
+    const validationResp = await validation.updatedvrDetailscheck(req);
+    const updatedDate = await getcurrentDate();
+
+    if (validationResp.status) {
+        try {
+            const query = "UPDATE dvr_report SET date_of_visit = '" + req.body.visit_date + "' ,customer_name= '" + req.body.customer_name + "',contact_name= '" + req.body.contact_name + "',message= '" + req.body.message + "' ,physical_meeting= '" + req.body.physical_metting + "' ,updated_by= '" + req.body.updated_by + "', updated_on= '" + updatedDate + "', stage_id= '" + req.body.stage_id + "'  where dvr_id= '" + req.body.dvr_id + "'";
+            console.log("query", query);
+            const queryresult = await db.executequery(query);
+            console.log("queryresult", queryresult);
+
+            if (queryresult) {
+                res.send({
+                    status: true,
+                    data: [
+                        {
+                            getdvrDataStatus: '0',
+                            message: "Daliy visit Report Entry updated suceesfully."
+                        }
+                    ],
+                    errors: " "
+
+                })
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        message: "Daliy visit Report Entry not updated. Please try again after some time!"
+                    }],
+                    errors: ""
+
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: [], errors: err
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+}
+
+
+
+module.exports.createCustomerentry = async (req, res) => {
+    const validationResp = await validation.createCustomerentrycheck(req);
+    const createdate = new Date();
+    if (validationResp.status) {
+        try {
+            const query = "INSERT INTO customer_master(customer_name,created_by,created_on)" +
+                "VALUES(?,?,?)";
+            const values = [req.body.customer_name, req.body.created_by, createdate]
+            const res3 = await db.executevaluesquery(query, values);
+            //console.log("res1", res1);
+            if (res3) {
+                res.send({
+                    message: "Customer Entry created Successfully ",
+                    createcustomerStatus: "0",
+                    exception: {
+                        errorid: "",
+                        errormessage: "No Errors"
+                    }
+
+                })
+            } else {
+                res.send({
+                    message: "",
+                    createStatus: "1",
+                    exception: {
+                        errorid: "404",
+                        errormessage: "Bad request"
+                    }
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+module.exports.updateContactDetails = async (req, res) => {
+    const validationResp = await validation.updateContactDetailscheck(req);
+    const updatedDate = await getcurrentDate();
+
+    if (validationResp.status) {
+        try {
+            const query = "UPDATE contact_master SET customer_id= '" + req.body.customer_id + "',first_name= '" + req.body.first_name + "',last_name= '" + req.body.last_name + "' ,mobile_number= '" + req.body.mobile_number + "' ,email_id= '" + req.body.email_id + "', designation= '" + req.body.designation + "', department= '" + req.body.department + "', updated_on= '" + updatedDate + "'  where customer_id= '" + req.body.customer_id + "'";
+            console.log("query", query);
+            const queryresult = await db.executequery(query);
+            console.log("queryresult", queryresult);
+
+            if (queryresult) {
+                res.send({
+                    updateContactStatus: '0',
+                    mesasge: "Contact Entry updated suceesfully."
+                })
+
+            } else {
+                res.send({
+                    updateContactStatus: '1',
+                    mesasge: "Contact Entry not updated."
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+}
+
+module.exports.updateCustomerDetails = async (req, res) => {
+    const validationResp = await validation.updateCustomerDetailscheck(req);
+    const updatedDate = await getcurrentDate();
+
+    if (validationResp.status) {
+        try {
+            const query = "UPDATE customer_master SET customer_id = '" + req.body.customer_id + "', updated_on= '" + updatedDate + "'  where customer_master= '" + req.body.contact_master + "'";
+            console.log("query", query);
+            const queryresult = await db.executequery(query);
+            console.log("queryresult", queryresult);
+
+            if (queryresult) {
+                res.send({
+                    updateCustomerStatus: '0',
+                    mesasge: "Customer Entry updated suceesfully."
+                })
+
+            } else {
+                res.send({
+                    updateCustomerStatus: '1',
+                    mesasge: "Customer Entry not updated."
+
+                })
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+}
+
+module.exports.getlastestdvr = async (req, res) => {
+    try {
+        var insertedRecord = [];
+
+        var startdate = new Date();
+        var enddate = new Date();
+        const format2 = "YYYY-MM-DD";
+        startdate = moment(startdate).format(format2) + ' 00:00:01';
+        enddate = moment(enddate).format(format2) + ' 23:59:59';
+
+
+        var person_role = req.query.role;
+        var login_id = req.query.login_id;
+        console.log("login_id", login_id);
+
+        if (person_role == 'admin') {
+            //admin show all data
+            const query = "SELECT d.dvr_id,d.date_of_visit,d.customer_name,d.contact_name,d.physical_meeting,d.message,s.stage_desc,d.stage_id FROM dvr_report d JOIN stage_master s ON d.stage_id=s.stage_id where  d.created_on between '" + startdate + "' and '" + enddate + "' and d.delete_id=0 order by d.date_of_visit desc";
+            const queryresult = await db.executequery(query);
+            console.log("query", query);
+
+            for (var i = 0; i < queryresult.length; i++) {
+                console.log(queryresult[i]);
+                insertedRecord.push(queryresult[i])
+            }
+
+            //console.log("res1", res1);
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [{
+                        dvrData: insertedRecord
+                    }],
+                    error: ""
+                })
+
+
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        mesasge: "Data Not Found"
+                    }],
+                    error: ""
+
+                })
+
+            }
+
+        } else {
+            // other users 
+            console.log("other users");
+            const query = "SELECT d.dvr_id,d.date_of_visit,d.customer_name,d.contact_name,d.physical_meeting,d.message,s.stage_desc,d.stage_id FROM dvr_report d JOIN stage_master s ON d.stage_id=s.stage_id where d.login_id='" + login_id + "' and d.created_on between '" + startdate + "' and '" + enddate + "' and d.delete_id=0 order by d.date_of_visit desc";
+            const queryresult = await db.executequery(query);
+            console.log("query", query);
+
+            for (var i = 0; i < queryresult.length; i++) {
+                console.log(queryresult[i]);
+                insertedRecord.push(queryresult[i])
+            }
+
+            //console.log("res1", res1);
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [{
+                        dvrData: insertedRecord
+                    }],
+                    error: ""
+                })
+
+
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        mesasge: "Data Not Found"
+                    }],
+                    error: ""
+
+                })
+
+            }
+
+        }
+
+
+
+
+    }
+    catch (err) {
+        console.log(err)
+        res.send({
+            status: true,
+            data: [],
+            getdvrDataStatus: '1',
+        })
+    }
+}
+
+module.exports.getcontactDetails = async (req, res) => {
+    try {
+        var insertedRecord = [];
+        var startdate = new Date();
+        var enddate = new Date();
+        const format2 = "YYYY-MM-DD";
+        startdate = moment(startdate).format(format2) + ' 00:00:01';
+        enddate = moment(enddate).format(format2) + ' 23:59:59';
+        var person_role = req.query.role;
+        var login_id = req.query.login_id;
+
+
+        if (person_role == 'admin') {
+            //admin show all data
+            const query = "SELECT first_name,last_name,mobile_number,email_id,designation,department FROM contact_master where created_on between '" + startdate + "' and '" + enddate + "' order by contact_id desc";
+            const queryresult = await db.executequery(query);
+            console.log("query", query);
+
+            for (var i = 0; i < queryresult.length; i++) {
+                console.log(queryresult[i]);
+                insertedRecord.push(queryresult[i])
+            }
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [{
+                        conrtactData: insertedRecord
+                    }],
+                    error: ""
+                })
+
+
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        mesasge: "Data Not Found"
+                    }],
+                    error: ""
+
+                })
+
+            }
+
+        } else {
+            //others users
+            const query = "SELECT first_name,last_name,mobile_number,email_id,designation,department FROM contact_master where created_by= '" + login_id + "' and created_on between '" + startdate + "' and '" + enddate + "' order by contact_id desc";
+            const queryresult = await db.executequery(query);
+            console.log("query", query);
+
+            for (var i = 0; i < queryresult.length; i++) {
+                console.log(queryresult[i]);
+                insertedRecord.push(queryresult[i])
+            }
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [{
+                        conrtactData: insertedRecord
+                    }],
+                    error: ""
+                })
+
+
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        mesasge: "Data Not Found"
+                    }],
+                    error: ""
+
+                })
+
+            }
+        }
+
+
+
+
+
+
+    } catch (err) {
+        console.log(err)
+        res.send({
+            status: true,
+            data: [],
+            getdvrDataStatus: '1',
+        })
+    }
+}
+
+module.exports.getsalePersonList = async (req, res) => {
+    console.log("in getsalePersonList");
+
+    try {
+        var salePerson = [];
+        var full_name = [];
+        const query = "SELECT user_id,first_name,last_name from user_master;";
+        const queryresult = await db.executequery(query);
+
+        if (queryresult.length > 0) {
+            for (var i = 0; i < queryresult.length; i++) {
+                console.log("queryresult", queryresult[i])
+                salePerson.push(queryresult[i]);
+            }
+
+        }
+
+        console.log("salePerson", salePerson);
+        res.send({
+            status: true,
+            data: [{
+                salePerson: salePerson
+            }],
+            error: ""
+        })
+
+    } catch (err) {
+        console.log(err)
+        res.send({
+            status: true, data: [], error: err
+        })
+    }
+
+
+}
+
+
+module.exports.getCustcontactDetails = async (req, res) => {
+    try {
+        var contactdetails = [];
+        var customer_id = req.query.customer_id;
+        var check_api = req.query.passid;
+
+        var passing_id;
+        console.log("customer_id", customer_id);
+        console.log("check api", check_api);
+
+        if (check_api == undefined) {
+            console.log("pass customer name");
+
+            const query = "SELECT customer_id,customer_name FROM customer_master where customer_name=  '" + customer_id + "' ";
+            const queryresult = await db.executequery(query);
+            console.log("queryresult", queryresult);
+
+            console.log("result------>", queryresult[0].customer_id);
+            passing_id = queryresult[0].customer_id;
+
+
+            const query_id = "SELECT first_name,last_name,mobile_number,email_id,designation,department,function_area FROM contact_master where customer_id=  '" + passing_id + "' ";
+            const queryresult_id = await db.executequery(query_id);
+            console.log("query", query);
+
+            for (var i = 0; i < queryresult_id.length; i++) {
+                console.log(queryresult_id[i]);
+                contactdetails.push(queryresult_id[i])
+            }
+            if (queryresult.length > 0) {
+                res.send({
+                    status: true,
+                    data: [{
+                        conrtactData: contactdetails
+                    }],
+                    error: ""
+                })
+
+
+
+            } else {
+                res.send({
+                    status: true,
+                    data: [{
+                        getdvrDataStatus: '1',
+                        mesasge: "Data Not Found"
+                    }],
+                    error: ""
+
+                })
+
+            }
+
+        } else {
+            console.log("pass number");
+
+            if (customer_id == 0) {
+                console.log("getting all contact data");
+                const query = "SELECT first_name,last_name,mobile_number,email_id,designation,department,function_area FROM contact_master";
+                const queryresult = await db.executequery(query);
+                console.log("query", query);
+
+                for (var i = 0; i < queryresult.length; i++) {
+                    console.log(queryresult[i]);
+                    contactdetails.push(queryresult[i])
+                }
+                if (queryresult.length > 0) {
+                    res.send({
+                        status: true,
+                        data: [{
+                            conrtactData: contactdetails
+                        }],
+                        error: ""
+                    })
+
+
+
+                } else {
+                    res.send({
+                        status: true,
+                        data: [{
+                            getdvrDataStatus: '1',
+                            mesasge: "Data Not Found"
+                        }],
+                        error: ""
+
+                    })
+
+                }
+
+            } else {
+                console.log("getting only specific customer contact data");
+                const query = "SELECT first_name,last_name,mobile_number,email_id,designation,department,function_area FROM contact_master where customer_id=  '" + customer_id + "' ";
+                const queryresult = await db.executequery(query);
+                console.log("query", query);
+
+                for (var i = 0; i < queryresult.length; i++) {
+                    console.log(queryresult[i]);
+                    contactdetails.push(queryresult[i])
+                }
+                if (queryresult.length > 0) {
+                    res.send({
+                        status: true,
+                        data: [{
+                            conrtactData: contactdetails
+                        }],
+                        error: ""
+                    })
+
+
+
+                } else {
+                    res.send({
+                        status: true,
+                        data: [{
+                            getdvrDataStatus: '1',
+                            mesasge: "Data Not Found"
+                        }],
+                        error: ""
+
+                    })
+
+                }
+            }
+
+
+
+        }
+
+
+    } catch (err) {
+        console.log(err)
+        res.send({
+            status: true,
+            data: [],
+            getdvrDataStatus: '1',
+        })
+    }
+}
+
+
+
+module.exports.createUpdateCustomerentry = async (req, res) => {
+    const validationResp = await validation.createCustomerentrycheck(req);
+    const createdate = new Date();
+
+    if (validationResp.status) {
+        try {
+
+            if (req.body.action == 'insert') {
+                console.log("customer added");
+                const checkdub = "select * from customer_master where customer_name='" + req.body.customer_name + "'";
+                const checkqueryresult = await db.executequery(checkdub);
+                console.log("checkqueryresult", checkqueryresult.length)
+                if (checkqueryresult.length > 0) {
+                    //allready all present
+                    res.send({
+                        status: false,
+                        data: [],
+                        errors: "Customer Entry allready Exit ! Please Enter Correct Customer Name"
+                    })
+
+
+                } else {
+                    //data not is present
+
+                    const query = "INSERT INTO customer_master(customer_name,created_by,created_on)" +
+                        "VALUES(?,?,?)";
+                    const values = [req.body.customer_name, req.body.created_by, createdate]
+                    const res3 = await db.executevaluesquery(query, values);
+                    console.log("response", res3);
+                    if (res3) {
+
+                        const query = "select customer_id from customer_master order by customer_id desc limit 1";
+                        const queryresult = await db.executequery(query);
+                        console.log("query result----->", queryresult);
+
+                        console.log("query result----->", queryresult[0].customer_id);
+                        if (queryresult) {
+                            // const query = "select customer_id from customer_master order by customer_id desc limit 1";
+                            // const queryresult = await db.executequery(query);
+                            var sale_person = req.body.sale_person;
+                            var name = sale_person.split(" ");
+                            console.log("name", name);
+                            var first_name = name[0];
+                            var last_name = name[1];
+                            console.log(first_name, last_name);
+
+                            const queryuserID = "SELECT user_id FROM user_master where first_name='" + first_name + "' and last_name= '" + last_name + "'";
+                            console.log("queryuserID", queryuserID);
+                            const queryresultID = await db.executequery(queryuserID);
+
+                            console.log("queryresultID", queryresultID);
+
+
+                            const finalquery = "INSERT INTO customer_user_mapping(customer_id,user_id,created_by,created_on)" +
+                                "VALUES(?,?,?,?)";
+                            const values = [queryresult[0].customer_id, queryresultID[0].user_id, req.body.created_by, createdate]
+                            const res3 = await db.executevaluesquery(finalquery, values);
+                            console.log("res3", res3);
+                            if (res3) {
+                                res.send({
+
+                                    status: true,
+                                    data: [{
+                                        createcustomerStatus: "0",
+                                        message: "Customer Entry created Successfully!",
+                                        lastinsertedData: req.body.customer_name,
+                                        exception: {
+                                            errorid: "",
+                                            errormessage: "No Errors"
+                                        }
+                                    }],
+                                    error: " "
+
+
+                                })
+
+                            } else {
+                                res.send({
+                                    status: false,
+                                    data: [{
+                                        message: "Customer Entry  Not created",
+                                        createcustomerStatus: "1",
+                                        exception: {
+                                            errorid: "404",
+                                            errormessage: "Bad request"
+                                        }
+                                    }],
+                                    error: ""
+
+                                })
+                            }
+
+                        }
+                    } else {
+                        res.send({
+                            status: true,
+                            data: [],
+                            errors: "Bad Request"
+
+                        })
+
+                    }
+
+
+                }
+
+
+
+            } else {
+                console.log("customer update");
+
+                const query = "UPDATE customer_master SET customer_name= '" + req.body.customer_name + "',updated_on= '" + createdate + "' ,updated_by= '" + req.body.created_by + "' where customer_id= '" + req.body.customer_id + "'";
+                console.log("query", query);
+                const queryresult = await db.executequery(query);
+                console.log("queryresult", queryresult);
+                //dates = searchfilter.split("-");
+
+
+                var saleData = req.body.sale_person.split(" ");
+                console.log("saleData");
+
+                //select user_id from user_master where first_name= "" and last_name="";
+                if (queryresult) {
+                    const getsaleperson = "select user_id from user_master where first_name= '" + saleData[0] + "' and last_name= '" + saleData[1] + "'";
+                    const getqueryresult = await db.executequery(getsaleperson);
+
+                    if (getqueryresult) {
+                        const checkdupli = "select * from customer_user_mapping where user_id=" + getqueryresult[0].user_id + " and customer_id= '" + req.body.customer_id + "' order by idcustCont_mapp desc limit 1";
+                        const checkexcutequer = await db.executequery(checkdupli);
+
+
+                        if (checkexcutequer[0].user_id == getqueryresult[0].user_id) {
+                            //same user for customer update
+                            console.log("same user for customer update");
+                            console.log("database date", formatDateAsPer(checkexcutequer[0].effectivedate_to));
+                            console.log("req body", req.body.effectivedate_to)
+
+                            if (req.body.effectivedate_to.length > 0) {
+                                if (req.body.effectivedate_from > req.body.effectivedate_to) {
+                                    res.send({
+                                        status: false,
+                                        data: [],
+                                        errors: "Please enter correct Effective From Date! Make sure Efffective From Date is less than Effective To Date"
+                                    })
+                                } else {
+                                    const query = "INSERT INTO customer_user_mapping(customer_id,user_id,effiectivedate_from,effectivedate_to,created_by,created_on)" +
+                                        "VALUES(?,?,?,?,?,?)";
+                                    const values = [req.body.customer_id, getqueryresult[0].user_id, req.body.effectivedate_from, req.body.effectivedate_to.length > 0 ? req.body.effectivedate_to : null, req.body.created_by, createdate]
+                                    const res3 = await db.executevaluesquery(query, values);
+                                    console.log("response--------->", res3);
+
+                                    if (res3) {
+                                        res.send({
+
+                                            status: true,
+                                            data: [{
+                                                message: "Customer Entry Update Successfully!",
+                                                createcustomerStatus: "0",
+                                                lastinsertedData: req.body.customer_name,
+                                                exception: {
+                                                    errorid: "",
+                                                    errormessage: "No Errors"
+                                                }
+                                            }],
+                                            error: " "
+
+
+                                        })
+
+                                    } else {
+                                        res.send({
+                                            status: true,
+                                            data: [{
+                                                message: "Customer Entry Not Updated.",
+                                                createStatus: "1",
+                                                exception: {
+                                                    errorid: "404",
+                                                    errormessage: "Bad request"
+                                                }
+                                            }],
+                                            error: ""
+
+                                        })
+                                    }
+
+                                }
+                            } else {
+                                //same user id  for effective different date.
+                                const query = "INSERT INTO customer_user_mapping(customer_id,user_id,effiectivedate_from,effectivedate_to,created_by,created_on)" +
+                                    "VALUES(?,?,?,?,?,?)";
+                                const values = [req.body.customer_id, getqueryresult[0].user_id, req.body.effectivedate_from, req.body.effectivedate_to.length > 0 ? req.body.effectivedate_to : null, req.body.created_by, createdate]
+                                const res3 = await db.executevaluesquery(query, values);
+                                console.log("response--------->", res3);
+
+                                if (res3) {
+                                    res.send({
+
+                                        status: true,
+                                        data: [{
+                                            message: "Customer Entry Update Successfully!",
+                                            createcustomerStatus: "0",
+                                            lastinsertedData: req.body.customer_name,
+                                            exception: {
+                                                errorid: "",
+                                                errormessage: "No Errors"
+                                            }
+                                        }],
+                                        error: " "
+
+
+                                    })
+
+                                } else {
+                                    res.send({
+                                        status: true,
+                                        data: [{
+                                            message: "Customer Entry Not Updated.",
+                                            createStatus: "1",
+                                            exception: {
+                                                errorid: "404",
+                                                errormessage: "Bad request"
+                                            }
+                                        }],
+                                        error: ""
+
+                                    })
+                                }
+
+                            }
+
+
+                        } else {
+                            //other user for customer update
+                            if (req.body.effectivedate_to.length > 0 && checkexcutequer[0].effectivedate_to.length > 0) {
+                                if (req.body.effectivedate_to == formatDateAsPer(checkexcutequer[0].effectivedate_to)) {
+                                    res.send({
+                                        status: false,
+                                        data: [],
+                                        errors: "Please enter correct Effective To Date are same for other sales Person "
+                                    })
+                                }
+
+                            } else if (req.body.effectivedate_to.length > 0) {
+                                if (req.body.effectivedate_from > req.body.effectivedate_to) {
+                                    res.send({
+                                        status: false,
+                                        data: [],
+                                        errors: "Please enter correct Effective From Date! Make sure Efffective From Date is less than Effective To Date"
+                                    })
+                                } else if (req.body.effectivedate_from == req.body.effectivedate_to) {
+
+                                    res.send({
+                                        status: false,
+                                        data: [],
+                                        errors: "Please enter correct Effective From  and Effection To Date ! Both Dates are same"
+                                    })
+                                } else {
+                                    const query = "INSERT INTO customer_user_mapping(customer_id,user_id,effiectivedate_from,effectivedate_to,created_by,created_on)" +
+                                        "VALUES(?,?,?,?,?,?)";
+                                    const values = [req.body.customer_id, getqueryresult[0].user_id, req.body.effectivedate_from, req.body.effectivedate_to.length > 0 ? req.body.effectivedate_to : null, req.body.created_by, createdate]
+                                    const res3 = await db.executevaluesquery(query, values);
+                                    console.log("response--------->", res3);
+                                    if (res3) {
+                                        res.send({
+
+                                            status: true,
+                                            data: [{
+                                                message: "Customer Entry Update Successfully!",
+                                                createcustomerStatus: "0",
+                                                lastinsertedData: req.body.customer_name,
+                                                exception: {
+                                                    errorid: "",
+                                                    errormessage: "No Errors"
+                                                }
+                                            }],
+                                            error: " "
+
+
+                                        })
+
+                                    } else {
+                                        res.send({
+                                            status: true,
+                                            data: [{
+                                                message: "Customer Entry  Not Updated",
+                                                createStatus: "1",
+                                                exception: {
+                                                    errorid: "404",
+                                                    errormessage: "Bad request"
+                                                }
+                                            }],
+                                            error: ""
+
+                                        })
+                                    }
+
+                                }
+
+                            } else {
+                                //all ok
+                                const query = "INSERT INTO customer_user_mapping(customer_id,user_id,effiectivedate_from,effectivedate_to,created_by,created_on)" +
+                                    "VALUES(?,?,?,?,?,?)";
+                                const values = [req.body.customer_id, getqueryresult[0].user_id, req.body.effectivedate_from, req.body.effectivedate_to.length > 0 ? req.body.effectivedate_to : null, req.body.created_by, createdate]
+                                const res3 = await db.executevaluesquery(query, values);
+                                console.log("response--------->", res3);
+                                if (res3) {
+                                    res.send({
+
+                                        status: true,
+                                        data: [{
+                                            message: "Customer Entry Update Successfully!",
+                                            createcustomerStatus: "0",
+                                            lastinsertedData: req.body.customer_name,
+                                            exception: {
+                                                errorid: "",
+                                                errormessage: "No Errors"
+                                            }
+                                        }],
+                                        error: " "
+
+
+                                    })
+
+                                } else {
+                                    res.send({
+                                        status: true,
+                                        data: [{
+                                            message: "Customer Entry  Not Updated",
+                                            createStatus: "1",
+                                            exception: {
+                                                errorid: "404",
+                                                errormessage: "Bad request"
+                                            }
+                                        }],
+                                        error: ""
+
+                                    })
+                                }
+
+                            }
+
+                        }
+
+                    }
+                }
+
+
+            }
+
+
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: [],
+                errors: err
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+
+module.exports.deletedvrEntry = async (req, res) => {
+    try {
+        //DELETE FROM table_name WHERE condition;
+
+        console.log("req.body", req.body);
+        const updatedDate = await getcurrentDate();
+
+        const query = "UPDATE dvr_report SET delete_id = 1,updated_by= '" + req.body.created_by + "', updated_on= '" + updatedDate + "' where dvr_id= " + req.body.dvr_id + "";
+        const checkqueryresult = await db.executequery(query);
+        console.log("checkqueryresult", checkqueryresult)
+        console.log("eeeeeeee", checkqueryresult.affectedRows);
+        if (checkqueryresult) {
+            //entry not deleted
+            res.send({
+                status: true,
+                data: [{
+                    message: "DVR Entry Deleted Successfully!",
+                    deleteStatus: "0"
+                }],
+                error: ""
+
+
+            })
+        } else {
+            //entry deleted
+            res.send({
+                status: true,
+                data: [{
+                    message: "DVR Entry Not Deleted.",
+                    deleteStatus: "1",
+                    exception: {
+                        errorid: "404",
+                        errormessage: "Bad request"
+                    }
+                }],
+                error: ""
+            })
+        }
+
+    } catch (err) {
+        console.log(err)
+        res.send({
+            status: true,
+            data: [],
+            getdvrDataStatus: '1',
+        })
+    }
+}
+
+
+
+function getLastWeeksDate() {
+    const now = new Date();
+    const format2 = "YYYY-MM-DD";
+    const date = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
+    // console.log("date", date);
+
+    const dateTime2 = moment(date).format(format2) + ' 00:00:00';
+
+    //  console.log("date------>", dateTime2);
+    return dateTime2;
+
+}
+
+function getcurrentDate() {
+    const now = new Date();
+    const format2 = "YYYY-MM-DD";
+    const dateTime2 = moment(now).format(format2) + ' 23:59:59';
+
+    // console.log("date------>", dateTime2);
+    return dateTime2;
+}
+
+
+function getLastMonthDate() {
+    const now = new Date();
+    const format2 = "YYYY-MM-DD";
+
+    const date = new Date(now.getFullYear(), now.getMonth() - 1, 1);
+    // console.log("date", date);
+    const dateTime2 = moment(date).format(format2) + ' 00:00:00';
+
+
+    //console.log("date------>", dateTime2);
+    return dateTime2;
+
+}
+
+function getLastYearDate() {
+    const now = new Date();
+    const format2 = "YYYY-MM-DD";
+
+    const date = new Date(now.setFullYear(now.getFullYear() - 1));
+    // console.log("date", date);
+    const dateTime2 = moment(date).format(format2) + ' 00:00:00';
+
+
+    //console.log("date------>", dateTime2);
+    return dateTime2;
+}
+

+ 268 - 0
controllers/loginController.js

@@ -0,0 +1,268 @@
+const db = require("../services/dbconnection");
+const validation = require("../controllers/validation")
+const config = require("../configs/config.json");
+const moment = require('moment');
+const createToken = require("../middlewares/createToken");
+const logger=require("../utils/logger");
+
+
+module.exports.loginUser = async (req, res) => {
+    const validationResp = await validation.logindatacheck(req);
+    if (validationResp.status) {
+        try {
+            const query = "select user_id,login_id,first_name,last_name,last_login_date,password from user_master where login_id='" + req.body.username + "' and password='" + req.body.password + "'";
+            const result = await db.executequery(query);
+            logger.info('log of login api search login user query result', result);
+
+            if (result.length == '0') {
+                res.send({
+                    status: true,
+                    data: [{
+                        message: "Invaild User",
+                        loginStatus: "1",
+                        logindata: {
+                            user_id: "",
+                            user_name: "",
+                            last_loginDate: ""
+                        },
+                        exception: {
+                            errorid: "",
+                            errormessage: "No Errors"
+                        }
+                    }],
+                    error: ""
+
+                })
+            }
+            else {
+                var rolData1;
+               
+             
+                const logindate = moment(new Date()).format("YYYY-MM-DD HH:mm");
+                const login_id = result[0].login_id;
+                const user_id = result[0].user_id;
+                const createdtoken = await createToken.createToken(user_id);
+
+                const findRole = "call SP_roleidentify1('" + login_id + "')";
+                console.log("findRole", findRole);
+
+                const roleidentify = await db.executequery(findRole);
+                rolData = roleidentify[0];
+
+                if (rolData != undefined) {
+                    rolData.forEach(function (item) {
+                        console.log(item.role_des);
+                        rolData1 = item.role_des;
+                    });
+                    console.log(rolData1);
+                }
+                //console.log("item",item);
+                rol_des = rolData1;
+                if(rol_des == undefined){
+                    rol_des="";
+                }
+                console.log("rol_des",rol_des);
+                const query = "update user_master SET last_login_date='" + logindate + "' where  login_id='" + login_id + "'";
+                const queryresult = await db.executequery(query);
+                logger.info('log of login api update user last_login_date query result', queryresult);
+
+                // console.log("queryresult", queryresult);
+                if (queryresult) {
+                    res.send({
+                        status: true,
+                        data: [{
+                            message: "Vaild User",
+                            loginStatus: "0",
+                            logindata: {
+                                user_id: login_id,
+                                user_name: result[0].first_name + " " + result[0].last_name,
+                                last_loginDate: result[0].last_login_date,
+                                role: rol_des
+                            },
+                            exception: {
+                                errorid: "",
+                                errormessage: "No Errors"
+                            },
+                            jwttoken: createdtoken
+                        }],
+                        error: ""
+
+                    })
+
+                } else {
+                    res.send({
+                        status: false,
+                        data: [{
+                            message: "Invaild User",
+                            loginStatus: "1",
+                            logindata: {
+                                user_id: "",
+                                user_name: "",
+                                last_loginDate: ""
+                            },
+                            exception: {
+                                errorid: "",
+                                errormessage: "No Errors"
+                            }
+                        }]
+
+                    })
+
+                }
+            }
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true,
+                data: [],
+                 error:err
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+module.exports.signupuser = async (req, res) => {
+    const validationResp = await validation.signupCheck(req);
+    const createdate = new Date();
+    console.log("Before if condition");
+    if (validationResp.status) {
+
+        console.log("After if condition")
+        try {
+            const query = "select login_id, user_id from user_master where login_id= '" + req.body.login_id + "'";
+            const queryresult = await db.executequery(query);
+            console.log("queryresult", queryresult);
+            if (queryresult.length > 0) {
+                res.send({
+                    message: "User Already Created.",
+                    SingupStatus: "1",
+                    exception: {
+                        errorid: "",
+                        errormessage: "No Errors"
+                    }
+
+                })
+            } else {
+                console.log("create new user");
+                const query1 = "INSERT INTO user_master(login_id,customer_id,password,first_name,last_name,email,mobile_number,created_by,created_on,last_login_date)" +
+                    " VALUES(?,?,?,?,?,?,?,?,?,?)";
+                const values = [req.body.login_id, req.body.customer_id, req.body.password, req.body.first_name, req.body.last_name, req.body.email, req.body.mobile_number, req.body.login_id, createdate, createdate]
+                const res1 = await db.executevaluesquery(query1, values);
+                console.log("res1", res1);
+                if (res1) {
+                    const createdtoken = await createToken.createToken(req.body.login_id);
+
+                    res.send({
+                        message: "User Created Successfully ",
+                        SingupStatus: "0",
+                        exception: {
+                            errorid: "",
+                            errormessage: "No Errors"
+                        },
+                        jwttoken: createdtoken
+
+                    })
+                } else {
+                    res.send({
+                        message: "",
+                        createStatus: "1",
+                        exception: {
+                            errorid: "404",
+                            errormessage: "Bad request"
+                        }
+                    })
+                }
+
+            }
+
+
+        } catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+module.exports.userrolemap = async (req, res) => {
+    const validationResp = await validation.userrolemapcheck(req);
+    const createdate = new Date();
+    if (validationResp.status) {
+        try {
+            const query = "select user_id,login_id from user_master where login_id='" + req.body.login_id + "'";
+            const result = await db.executequery(query);
+            if (result.length == '0') {
+                res.send({
+                    message: "Invaild User.Please enter valid login creditional!",
+                    userrolemapStatus: "1",
+                    exception: {
+                        errorid: "",
+                        errormessage: "No Errors"
+                    }
+                })
+            }
+            else {
+                console.log("valid user", result);
+                var login_id, user_id;
+                login_id = result[0].login_id;
+                console.log("login_id::", login_id);
+                user_id = result[0].user_id;
+                console.log("user_id::", user_id);
+
+
+
+                const query1 = "INSERT INTO user_mapping(user_master_id,user_role_id,created_by,created_on)" +
+                    " VALUES(?,?,?,?)";
+                const values = [user_id, req.body.user_role_id, req.body.login_id, createdate]
+                const res2 = await db.executevaluesquery(query1, values);
+                console.log("res2", res2);
+                if (res2) {
+
+                    res.send({
+                        message: "User Role mapped Successfully. ",
+                        SingupStatus: "0",
+                        exception: {
+                            errorid: "",
+                            errormessage: "No Errors"
+                        }
+                    })
+                } else {
+                    res.send({
+                        message: "",
+                        createStatus: "1",
+                        exception: {
+                            errorid: "404",
+                            errormessage: "Bad request"
+                        }
+                    })
+                }
+
+            }
+
+        }
+        catch (err) {
+            console.log(err)
+            res.send({
+                status: true, data: []
+            })
+        }
+    } else {
+        res.send(validationResp)
+    }
+
+}
+
+
+
+
+
+
+

+ 280 - 0
controllers/validation.js

@@ -0,0 +1,280 @@
+
+module.exports.logindatacheck = async function (req, res) {
+
+    if (req.body.username == "" || req.body.username == undefined || req.body.username == null) {
+        return { status: false, data: {}, errors: "Please enter Username" }
+    }
+    if (req.body.password == "" || req.body.password == undefined || req.body.password == null) {
+        return { status: false, data: {}, errors: "Please enter Password" }
+    }
+    return { status: true };
+}
+
+module.exports.createContactentrycheck = async function (req, res) {
+
+    if (req.body.contact_for == "" || req.body.contact_for == undefined || req.body.contact_for == null) {
+        return { status: false, data: [], errors: "Please enter Customer ID of contact" }
+    }
+
+    if (req.body.first_name == "" || req.body.first_name == undefined || req.body.first_name == null) {
+        return { status: false, data: [], errors: "Please enter First Name" }
+    }
+    if (req.body.last_name == "" || req.body.last_name == undefined || req.body.last_name == null) {
+        return { status: false, data: [], errors: "Please enter Last Name" }
+    }
+    if (req.body.mobile_no == "" || req.body.mobile_no == undefined || req.body.mobile_no == null) {
+        return { status: false, data: [], errors: "Please enter Mobile No." }
+    }
+    
+    if(req.body.mobile_no !=null && req.body.mobile_no !=""){
+        if(req.body.mobile_no.length != 10 ){
+            return { status: false, data: [], errors: "Please enter valid Mobile No" }
+        }
+    }
+
+    
+    // console.log("req.body.email_id",req.body.email_id);
+    // console.log("req.body.mobile_no",req.body.mobile_no);
+
+    if (req.body.email_id == "" || req.body.email_id == undefined || req.body.email_id == null) {
+        return { status: false, data: [], errors: "Please enter Email ID." }
+    }
+
+    if(req.body.email_id != null && req.body.email_id != ""){
+        console.log("check valid email");
+        if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(req.body.email_id)){
+            console.log("valid email");
+        }else{
+            console.log("in vliad email");
+            return { status: false, data: [], errors: "Please enter valid Email ID" }
+
+        }
+
+    }
+    
+    if (req.body.department == "" || req.body.department == undefined || req.body.department == null) {
+        return { status: false, data: [], errors: "Please enter Department" }
+    }
+    if (req.body.function == "" || req.body.function == undefined || req.body.function == null) {
+        return { status: false, data: [], errors: "Please enter Functional Area" }
+    }
+
+    if (req.body.created_by == "" || req.body.created_by == undefined || req.body.created_by == null) {
+        return { status: false, data: [], errors: "Please enter Login ID" }
+    }
+
+    return { status: true };
+}
+
+
+module.exports.getdvrDetailscheck = async (req, res) => {
+    if (req.query.dvrid == "" || req.query.dvrid == undefined || req.query.dvrid == null) {
+        return { status: false, data: {}, errors: "Please enter DVR ID" }
+    }
+    return { status: true };
+}
+
+
+module.exports.createDvrentrycheck = async function (req, res) {
+
+    if (req.body.visit_date == "" || req.body.visit_date == undefined || req.body.visit_date == null) {
+        return { status: false, data: [], errors: "Please enter Date of visit" }
+    }
+    if (req.body.customer_name == "" || req.body.customer_name == undefined || req.body.customer_name == null) {
+    return { status: false, data: [], errors: "Please enter Customer Name" }
+
+
+    }
+        if (!containsOnlyLetters(req.body.customer_name)) {
+        return { status: false, data: [], errors: " Please Enter Valid Customer Name " }
+    }
+    if (req.body.contact_name == "" || req.body.contact_name == undefined || req.body.contact_name == null) {
+        return { status: false, data: [], errors: "Please enter Contact Name" }
+    }
+
+    if (req.body.message == "" || req.body.message == undefined || req.body.message == null) {
+        return { status: false, data: [], errors: "Please enter Meassage" }
+    }
+    if (req.body.physical_metting == "" || req.body.physical_metting == undefined || req.body.physical_metting == null) {
+        return { status: false, data: [], errors: "Please enter Designation" }
+    }
+    if (req.body.stage_id == "" || req.body.stage_id == undefined || req.body.stage_id == null) {
+        return { status: false, data: [], errors: "Please choose Status " }
+    }
+    if (req.body.created_by == "" || req.body.created_by == undefined || req.body.created_by == null) {
+        return { status: false, data: [], errors: "Please enter Login ID" }
+    }
+
+    return { status: true };
+}
+
+
+
+module.exports.updatedvrDetailscheck = async (req, res) => {
+    if (req.body.dvr_id == "" || req.body.dvr_id == undefined || req.body.dvr_id == null) {
+        return { status: false, data: [], errors: "Please enter DVR ID" }
+    }
+    if (req.body.visit_date == "" || req.body.visit_date == undefined || req.body.visit_date == null) {
+        return { status: false, data: [], errors: "Please enter Date of visit" }
+    }
+    if (req.body.customer_name == "" || req.body.customer_name == undefined || req.body.customer_name == null) {
+        return { status: false, data: [], errors: "Please enter Customer Name" }
+    }
+    if (req.body.contact_name == "" || req.body.contact_name == undefined || req.body.contact_name == null) {
+        return { status: false, data: [], errors: "Please enter Contact Name" }
+    }
+    
+    if (req.body.message == "" || req.body.message == undefined || req.body.message == null) {
+        return { status: false, data: {}, errors: "Please enter Mesasge" }
+    }
+    if (req.body.physical_metting == "" || req.body.physical_metting == undefined || req.body.physical_metting == null) {
+        return { status: false, data: {}, errors: "Please enter Physical Metting status" }
+    }
+    if (req.body.stage_id == "" || req.body.stage_id == undefined || req.body.stage_id == null) {
+        return { status: false, data: {}, errors: "Please choose Status" }
+    }
+    if (req.body.updated_by == "" || req.body.updated_by == undefined || req.body.updated_by == null) {
+        return { status: false, data: {}, errors: "Please enter Login ID for updation." }
+    }
+
+    return { status: true };
+}
+
+module.exports.signupCheck = async function (req, res) {
+
+    if (req.body.login_id == "" || req.body.login_id == undefined || req.body.login_id == null) {
+        return { status: false, data: {}, errors: "Please enter Login Id" }
+    }
+    if (req.body.customer_id == "" || req.body.customer_id == undefined || req.body.customer_id == null) {
+        return { status: false, data: {}, errors: "Please enter Customer Id" }
+    }
+
+    if (req.body.password == "" || req.body.password == undefined || req.body.password == null) {
+        return { status: false, data: {}, errors: "Please enter Password" }
+    }
+
+
+    // if (req.body.password.length != '8'){
+    //    return { status: false, data: {}, errors: "Please enter 8 digits Password" } 
+
+    // }
+    if (req.body.first_name == "" || req.body.first_name == undefined || req.body.first_name == null) {
+        return { status: false, data: {}, errors: "Please enter First Name" }
+    }
+    if (req.body.last_name == "" || req.body.last_name == undefined || req.body.last_name == null) {
+        return { status: false, data: {}, errors: "Please enter Last Name" }
+    }
+    if (req.body.email == "" || req.body.email == undefined || req.body.email == null) {
+        return { status: false, data: {}, errors: "Please enter Email" }
+    }
+
+    if (req.body.mobile_number == "" || req.body.mobile_number == undefined || req.body.mobile_number == null) {
+        return { status: false, data: {}, errors: "Please enter Mobile Number" }
+    }
+    if (req.body.mobile_number.length != '10') {
+        return { status: false, data: {}, errors: "Please Enter 10 digit Mobile Number" }
+    }
+    return { status: true };
+}
+
+module.exports.userrolemapcheck = async function (req, res) {
+
+    if (req.body.login_id == "" || req.body.login_id == undefined || req.body.login_id == null) {
+        return { status: false, data: {}, errors: "Please enter login id" }
+    }
+    if (req.body.user_role_id == "" || req.body.user_role_id == undefined || req.body.user_role_id == null) {
+        return { status: false, data: {}, errors: "Please enter user role id" }
+    }
+    return { status: true };
+}
+
+module.exports.createCustomerentrycheck = async function (req, res) {
+
+    if (req.body.customer_name == "" || req.body.customer_name == undefined || req.body.customer_name == null) {
+        return { status: false, data: {}, errors: "Please enter Valid Customer Name" }
+    }
+
+    if (!containsOnlyLetters(req.body.customer_name)) {
+        return { status: false, data: {}, errors: "Please enter Valid Customer Name" }
+    }
+
+    if (req.body.sale_person == "" || req.body.sale_person == undefined || req.body.sale_person == null) {
+        return { status: false, data: {}, errors: "Please enter Valid Sales Person Name" }
+    }
+
+    if (req.body.created_by == "" || req.body.created_by == undefined || req.body.created_by == null) {
+        return { status: false, data: {}, errors: "Please enter Login ID" }
+    }
+    return { status: true };
+}
+
+module.exports.updateContactDetailscheck = async (req, res) => {
+    var validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
+
+    if (req.body.contact_id == "" || req.body.contact_id == undefined || req.body.contact_id == null) {
+        return { status: false, data: {}, errors: "Please enter contact Id" }
+    }
+    if (req.body.customer_id == "" || req.body.customer_id == undefined || req.body.customer_id == null) {
+        return { status: false, data: {}, errors: "Please enter Customer Id" }
+    }
+    if (req.body.first_name == "" || req.body.first_name == undefined || req.body.first_name == null) {
+        return { status: false, data: {}, errors: "Please enter First Name" }
+    }
+    if (req.body.last_name == "" || req.body.last_name == undefined || req.body.last_name == null) {
+        return { status: false, data: {}, errors: "Please enter Last Name" }
+    }
+    if (req.body.mobile_number == "" || req.body.mobile_number == undefined || req.body.mobile_number == null) {
+        return { status: false, data: {}, errors: "Please enter Mobile Number" }
+    }
+    if (req.body.mobile_number.length != '10') {
+        return { status: false, data: {}, errors: "Please enter 10 digits Mobile Number" }
+
+    }
+
+    if (req.body.email_id == "" || req.body.email_id == undefined || req.body.email_id == null) {
+        console.log("req.body.email_id", req.body.email_id);
+        return { status: false, data: {}, errors: "Please enter Email Id" }
+    }
+    // console.log("req.body.email_id",req.body.email_id);
+    //console.log("check validation",req.body.email_id.match(validRegex));
+    // if(req.body.email_id.match(validRegex) == false){
+    //     return { status: false, data: {}, errors: "Please enter valid Email ID" }
+    // }
+    if (req.body.designation == "" || req.body.designation == undefined || req.body.designation == null) {
+        return { status: false, data: {}, errors: "Please enter Designation" }
+    }
+    if (req.body.department == "" || req.body.department == undefined || req.body.department == null) {
+        return { status: false, data: {}, errors: "Please enter Department" }
+    }
+    if (req.body.updated_by == "" || req.body.updated_by == undefined || req.body.updated_by == null) {
+        return { status: false, data: {}, errors: "Please enter Login ID for updation " }
+    }
+
+
+    return { status: true };
+}
+
+module.exports.updateCustomerDetailscheck = async (req, res) => {
+    if (req.body.customer_id == "" || req.body.customer_id == undefined || req.body.customer_id == null) {
+        return { status: false, data: {}, errors: "Please enter contact Id" }
+    }
+    if (req.body.customer_name == "" || req.body.customer_name == undefined || req.body.customer_name == null) {
+        return { status: false, data: {}, errors: "Please enter Customer Name" }
+    }
+    if (!containsOnlyLetters(req.body.customer_name)) {
+        return { status: false, data: {}, errors: " Please Enter Valid Customer Name ." }
+    }
+
+
+    if (req.body.updated_by == "" || req.body.updated_by == undefined || req.body.updated_by == null) {
+        return { status: false, data: {}, errors: "Please enter Login ID for updation " }
+    }
+
+    return { status: true };
+}
+
+function containsOnlyLetters(str) {
+    //return /^[A-Za-z\s]+$/.test(str);
+
+   return /^[ A-Za-z_@./#&+-]*$/.test(str);
+}

+ 35 - 0
middlewares/authorize.js

@@ -0,0 +1,35 @@
+const jwt = require("jsonwebtoken");
+
+const config = require("../configs/config.json");
+
+const verifyToken = (req, res, next) => {
+  const token =
+    req.body.token || req.query.token || req.headers["token"];
+
+  if (!token) {
+    return res.send({
+      status:'tokenfalse',
+      data:[{
+        message: "A token is required for authentication"
+
+      }],
+      error:""
+    });
+  }
+  try {
+    const decoded = jwt.verify(token, config.token_header_key);
+    req.user = decoded;
+  } catch (err) {
+    return res.send({
+      status: 'tokenfalse',
+      data:[{
+        message: "Invalid Token"
+      }],
+      error:""
+    });
+    
+  }
+  return next();
+};
+
+module.exports = verifyToken;

+ 17 - 0
middlewares/createToken.js

@@ -0,0 +1,17 @@
+const jwt = require('jsonwebtoken');
+const config = require("../configs/config.json");
+
+exports.createToken = function (login_id) {
+    return new Promise((result, reject) => {
+        const token = jwt.sign(
+            { login_id: login_id },
+            config.token_header_key,
+            {
+                expiresIn: "2h",
+            }
+        );
+        result(token);
+
+    });
+}
+ 

+ 3652 - 0
package-lock.json

@@ -0,0 +1,3652 @@
+{
+  "name": "dvr-backend",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "author": "",
+  "description": "",
+  "license": "ISC",
+  "main": "app.js",
+  "packages": {
+    "": {
+      "name": "dvr-backend",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "bcryptjs": "^2.4.3",
+        "body": "^5.1.0",
+        "cookie-parser": "^1.4.6",
+        "cors": "^2.8.5",
+        "cros": "^1.0.1",
+        "express": "^4.18.2",
+        "jsonwebtoken": "^8.5.1",
+        "mkdirp": "^1.0.4",
+        "moment": "^2.29.4",
+        "mysql": "^2.18.1",
+        "mysql2": "^2.3.3",
+        "nodemon": "^2.0.20",
+        "object-assign": "^4.1.1",
+        "parser": "^0.1.4",
+        "winston": "^3.8.2"
+      }
+    },
+    "node_modules/@colors/colors": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/@dabh/diagnostics": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+      "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+      "dependencies": {
+        "colorspace": "1.1.x",
+        "enabled": "2.0.x",
+        "kuler": "^2.0.0"
+      }
+    },
+    "node_modules/abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+    },
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ansi-escapes": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+      "dependencies": {
+        "type-fest": "^0.21.3"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/ansi-styles/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/ansi-styles/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+    },
+    "node_modules/async": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    },
+    "node_modules/bcryptjs": {
+      "version": "2.4.3",
+      "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
+    },
+    "node_modules/bignumber.js": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/body": {
+      "version": "5.1.0",
+      "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==",
+      "dependencies": {
+        "continuable-cache": "^0.3.1",
+        "error": "^7.0.0",
+        "raw-body": "~1.1.0",
+        "safe-json-parse": "~1.0.1"
+      }
+    },
+    "node_modules/body-parser": {
+      "version": "1.20.1",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+      "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.11.0",
+        "raw-body": "2.5.1",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/body-parser/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/raw-body": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+      "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/chalk": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+      "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
+    },
+    "node_modules/chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/cli-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+      "dependencies": {
+        "restore-cursor": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cli-spinners": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
+      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/cli-width": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/color": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+      "dependencies": {
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "node_modules/colorspace": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
+      "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+      "dependencies": {
+        "color": "^3.1.3",
+        "text-hex": "1.0.x"
+      }
+    },
+    "node_modules/commander": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/continuable-cache": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
+      "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA=="
+    },
+    "node_modules/cookie": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-parser": {
+      "version": "1.4.6",
+      "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
+      "dependencies": {
+        "cookie": "0.4.1",
+        "cookie-signature": "1.0.6"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+    },
+    "node_modules/cors": {
+      "version": "2.8.5",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/cros": {
+      "version": "1.0.1",
+      "integrity": "sha512-5dOkfRcvLX7JSqLY9JtuLBfmcBaqkpmyOwecp2RIbnLnXF2gyKrRiwBWgvuVyVlGzbvmrX0OPutXGex1cQg0GQ==",
+      "dependencies": {
+        "chalk": "^3.0.0",
+        "commander": "^4.1.1",
+        "inquirer": "^7.0.4",
+        "ora": "^4.0.3",
+        "uuid": "^8.3.2"
+      },
+      "bin": {
+        "cros": "bin/cli.js"
+      }
+    },
+    "node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+    },
+    "node_modules/defaults": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+      "dependencies": {
+        "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/denque": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+      "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/disect": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/disect/-/disect-1.1.1.tgz",
+      "integrity": "sha512-rr2Ym8FSAoqAJ1KfpUiQ/Io01HP0LZPHBuppbFsHozmSNf+YwrvyD5pm5tMTUApJFNwD7HeWJ5DGldSugScukA=="
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+    },
+    "node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/enabled": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+      "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/error": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
+      "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
+      "dependencies": {
+        "string-template": "~0.2.1"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/express": {
+      "version": "4.18.2",
+      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.1",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.5.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.2.0",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.11.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.18.0",
+        "serve-static": "1.15.0",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/cookie": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "dependencies": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/external-editor/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/fecha": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
+      "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
+    },
+    "node_modules/figures": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+      "dependencies": {
+        "escape-string-regexp": "^1.0.5"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+      "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "statuses": "2.0.1",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/fn.name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+      "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+    },
+    "node_modules/forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "node_modules/generate-function": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+      "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+      "dependencies": {
+        "is-property": "^1.0.2"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+      "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/inquirer": {
+      "version": "7.3.3",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+      "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+      "dependencies": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^4.1.0",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^3.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.19",
+        "mute-stream": "0.0.8",
+        "run-async": "^2.4.0",
+        "rxjs": "^6.6.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "through": "^2.3.6"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/inquirer/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-interactive": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-property": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+      "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
+    },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+    },
+    "node_modules/jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=4",
+        "npm": ">=1.4.28"
+      }
+    },
+    "node_modules/jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "dependencies": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/kuler": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+      "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+    },
+    "node_modules/log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dependencies": {
+        "chalk": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/log-symbols/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-symbols/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/logform": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz",
+      "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==",
+      "dependencies": {
+        "@colors/colors": "1.5.0",
+        "fecha": "^4.2.0",
+        "ms": "^2.1.1",
+        "safe-stable-stringify": "^2.3.1",
+        "triple-beam": "^1.3.0"
+      }
+    },
+    "node_modules/long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/moment": {
+      "version": "2.29.4",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "node_modules/mute-stream": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
+    },
+    "node_modules/mysql": {
+      "version": "2.18.1",
+      "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
+      "dependencies": {
+        "bignumber.js": "9.0.0",
+        "readable-stream": "2.3.7",
+        "safe-buffer": "5.1.2",
+        "sqlstring": "2.3.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mysql/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/mysql2": {
+      "version": "2.3.3",
+      "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
+      "dependencies": {
+        "denque": "^2.0.1",
+        "generate-function": "^2.3.1",
+        "iconv-lite": "^0.6.3",
+        "long": "^4.0.0",
+        "lru-cache": "^6.0.0",
+        "named-placeholders": "^1.1.2",
+        "seq-queue": "^0.0.5",
+        "sqlstring": "^2.3.2"
+      },
+      "engines": {
+        "node": ">= 8.0"
+      }
+    },
+    "node_modules/mysql2/node_modules/sqlstring": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
+      "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/named-placeholders": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
+      "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
+      "dependencies": {
+        "lru-cache": "^4.1.3"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/named-placeholders/node_modules/lru-cache": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+      "dependencies": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "node_modules/named-placeholders/node_modules/yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/nodemon": {
+      "version": "2.0.20",
+      "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
+      "dependencies": {
+        "chokidar": "^3.5.2",
+        "debug": "^3.2.7",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.1.2",
+        "pstree.remy": "^1.1.8",
+        "semver": "^5.7.1",
+        "simple-update-notifier": "^1.0.7",
+        "supports-color": "^5.5.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.5"
+      },
+      "bin": {
+        "nodemon": "bin/nodemon.js"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/nodemon"
+      }
+    },
+    "node_modules/nodemon/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/nodemon/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/nodemon/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/nopt": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+      "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/one-time": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+      "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+      "dependencies": {
+        "fn.name": "1.x.x"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ora": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz",
+      "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==",
+      "dependencies": {
+        "chalk": "^3.0.0",
+        "cli-cursor": "^3.1.0",
+        "cli-spinners": "^2.2.0",
+        "is-interactive": "^1.0.0",
+        "log-symbols": "^3.0.0",
+        "mute-stream": "0.0.8",
+        "strip-ansi": "^6.0.0",
+        "wcwidth": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/parser": {
+      "version": "0.1.4",
+      "integrity": "sha512-f6EM/mBtPzmIh96MpcbePfhkBOYRmLYWuOukJqMysMlvjp4s2MQSSQnFEekd9GV4JGTnDJ2uFt3Ztcqc9wCMJg==",
+      "dependencies": {
+        "tokenizer": "*"
+      },
+      "engines": {
+        "node": "0.4-0.9"
+      }
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "dependencies": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
+    },
+    "node_modules/pstree.remy": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
+    },
+    "node_modules/qs": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+      "dependencies": {
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
+      "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==",
+      "dependencies": {
+        "bytes": "1",
+        "string_decoder": "0.10"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/raw-body/node_modules/bytes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+      "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ=="
+    },
+    "node_modules/raw-body/node_modules/string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+    },
+    "node_modules/readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/readable-stream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/restore-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+      "dependencies": {
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/run-async": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/rxjs": {
+      "version": "6.6.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+      "dependencies": {
+        "tslib": "^1.9.0"
+      },
+      "engines": {
+        "npm": ">=2.0.0"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/safe-json-parse": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
+      "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A=="
+    },
+    "node_modules/safe-stable-stringify": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz",
+      "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/seq-queue": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
+      "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
+    },
+    "node_modules/serve-static": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+      "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.18.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+    },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "node_modules/simple-update-notifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+      "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+      "dependencies": {
+        "semver": "~7.0.0"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/simple-update-notifier/node_modules/semver": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+      "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/sqlstring": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
+      "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/string_decoder/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/string-template": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
+      "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw=="
+    },
+    "node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/text-hex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+      "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
+    },
+    "node_modules/through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
+    },
+    "node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/tokenizer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/tokenizer/-/tokenizer-1.1.2.tgz",
+      "integrity": "sha512-c/EYsBwEW/EX28q44UaSrJ9o5M2aI+N/xdJJ4Zl7dNq76OmWQHhmXH0T8DJQNjVYPc7NclV2CZQfyeUMfnEu/A==",
+      "dependencies": {
+        "disect": "~1.1.0"
+      },
+      "engines": {
+        "node": "0.10.x"
+      }
+    },
+    "node_modules/touch": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+      "dependencies": {
+        "nopt": "~1.0.10"
+      },
+      "bin": {
+        "nodetouch": "bin/nodetouch.js"
+      }
+    },
+    "node_modules/triple-beam": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
+      "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/type-fest": {
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/undefsafe": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+      "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+      "dependencies": {
+        "defaults": "^1.0.3"
+      }
+    },
+    "node_modules/winston": {
+      "version": "3.8.2",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz",
+      "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==",
+      "dependencies": {
+        "@colors/colors": "1.5.0",
+        "@dabh/diagnostics": "^2.0.2",
+        "async": "^3.2.3",
+        "is-stream": "^2.0.0",
+        "logform": "^2.4.0",
+        "one-time": "^1.0.0",
+        "readable-stream": "^3.4.0",
+        "safe-stable-stringify": "^2.3.1",
+        "stack-trace": "0.0.x",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.5.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/winston-transport": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz",
+      "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==",
+      "dependencies": {
+        "logform": "^2.3.2",
+        "readable-stream": "^3.6.0",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 6.4.0"
+      }
+    },
+    "node_modules/winston-transport/node_modules/readable-stream": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/winston/node_modules/readable-stream": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    }
+  },
+  "dependencies": {
+    "@colors/colors": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="
+    },
+    "@dabh/diagnostics": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+      "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+      "requires": {
+        "colorspace": "1.1.x",
+        "enabled": "2.0.x",
+        "kuler": "^2.0.0"
+      }
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+    },
+    "accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "requires": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      }
+    },
+    "ansi-escapes": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+      "requires": {
+        "type-fest": "^0.21.3"
+      }
+    },
+    "ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+    },
+    "ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "requires": {
+        "color-convert": "^2.0.1"
+      },
+      "dependencies": {
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        }
+      }
+    },
+    "anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+    },
+    "async": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
+    },
+    "balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    },
+    "bcryptjs": {
+      "version": "2.4.3",
+      "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
+    },
+    "bignumber.js": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
+    },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+    },
+    "body": {
+      "version": "5.1.0",
+      "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==",
+      "requires": {
+        "continuable-cache": "^0.3.1",
+        "error": "^7.0.0",
+        "raw-body": "~1.1.0",
+        "safe-json-parse": "~1.0.1"
+      }
+    },
+    "body-parser": {
+      "version": "1.20.1",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+      "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+      "requires": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.11.0",
+        "raw-body": "2.5.1",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.24",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+          "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "raw-body": {
+          "version": "2.5.1",
+          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+          "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+          "requires": {
+            "bytes": "3.1.2",
+            "http-errors": "2.0.0",
+            "iconv-lite": "0.4.24",
+            "unpipe": "1.0.0"
+          }
+        }
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "requires": {
+        "fill-range": "^7.0.1"
+      }
+    },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
+    "bytes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "chalk": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+      "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+      "requires": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      }
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
+    },
+    "chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "requires": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      }
+    },
+    "cli-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+      "requires": {
+        "restore-cursor": "^3.1.0"
+      }
+    },
+    "cli-spinners": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
+      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw=="
+    },
+    "cli-width": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw=="
+    },
+    "clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="
+    },
+    "color": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+      "requires": {
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "colorspace": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
+      "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+      "requires": {
+        "color": "^3.1.3",
+        "text-hex": "1.0.x"
+      }
+    },
+    "commander": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+    },
+    "content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "requires": {
+        "safe-buffer": "5.2.1"
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+    },
+    "continuable-cache": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
+      "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA=="
+    },
+    "cookie": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
+    },
+    "cookie-parser": {
+      "version": "1.4.6",
+      "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
+      "requires": {
+        "cookie": "0.4.1",
+        "cookie-signature": "1.0.6"
+      }
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+    },
+    "core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+    },
+    "cors": {
+      "version": "2.8.5",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "requires": {
+        "object-assign": "^4",
+        "vary": "^1"
+      }
+    },
+    "cros": {
+      "version": "1.0.1",
+      "integrity": "sha512-5dOkfRcvLX7JSqLY9JtuLBfmcBaqkpmyOwecp2RIbnLnXF2gyKrRiwBWgvuVyVlGzbvmrX0OPutXGex1cQg0GQ==",
+      "requires": {
+        "chalk": "^3.0.0",
+        "commander": "^4.1.1",
+        "inquirer": "^7.0.4",
+        "ora": "^4.0.3",
+        "uuid": "^8.3.2"
+      }
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "requires": {
+        "ms": "2.0.0"
+      },
+      "dependencies": {
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+        }
+      }
+    },
+    "defaults": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+      "requires": {
+        "clone": "^1.0.2"
+      }
+    },
+    "denque": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+      "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="
+    },
+    "depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+    },
+    "destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
+    },
+    "disect": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/disect/-/disect-1.1.1.tgz",
+      "integrity": "sha512-rr2Ym8FSAoqAJ1KfpUiQ/Io01HP0LZPHBuppbFsHozmSNf+YwrvyD5pm5tMTUApJFNwD7HeWJ5DGldSugScukA=="
+    },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "enabled": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+      "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+    },
+    "error": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
+      "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
+      "requires": {
+        "string-template": "~0.2.1"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
+    },
+    "express": {
+      "version": "4.18.2",
+      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "requires": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.1",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.5.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.2.0",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.11.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.18.0",
+        "serve-static": "1.15.0",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "cookie": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+          "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.24",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+          "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        }
+      }
+    },
+    "fecha": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
+      "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
+    },
+    "figures": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "requires": {
+        "to-regex-range": "^5.0.1"
+      }
+    },
+    "finalhandler": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+      "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "statuses": "2.0.1",
+        "unpipe": "~1.0.0"
+      }
+    },
+    "fn.name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+      "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+    },
+    "forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "generate-function": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+      "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+      "requires": {
+        "is-property": "^1.0.2"
+      }
+    },
+    "get-intrinsic": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+      "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.3"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+    },
+    "has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+    },
+    "http-errors": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "requires": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      }
+    },
+    "ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "inquirer": {
+      "version": "7.3.3",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+      "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+      "requires": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^4.1.0",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^3.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.19",
+        "mute-stream": "0.0.8",
+        "run-async": "^2.4.0",
+        "rxjs": "^6.6.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        }
+      }
+    },
+    "ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
+    },
+    "is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+    },
+    "is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+    },
+    "is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-interactive": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
+    },
+    "is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+    },
+    "is-property": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+      "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
+    },
+    "is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+    },
+    "jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "requires": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      }
+    },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "kuler": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+      "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
+    },
+    "lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+    },
+    "log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "requires": {
+        "chalk": "^2.4.2"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "logform": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz",
+      "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==",
+      "requires": {
+        "@colors/colors": "1.5.0",
+        "fecha": "^4.2.0",
+        "ms": "^2.1.1",
+        "safe-stable-stringify": "^2.3.1",
+        "triple-beam": "^1.3.0"
+      }
+    },
+    "long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "requires": {
+        "yallist": "^4.0.0"
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
+    },
+    "mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+    },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
+    },
+    "minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
+    },
+    "moment": {
+      "version": "2.29.4",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+    },
+    "ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "mute-stream": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
+    },
+    "mysql": {
+      "version": "2.18.1",
+      "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
+      "requires": {
+        "bignumber.js": "9.0.0",
+        "readable-stream": "2.3.7",
+        "safe-buffer": "5.1.2",
+        "sqlstring": "2.3.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        }
+      }
+    },
+    "mysql2": {
+      "version": "2.3.3",
+      "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
+      "requires": {
+        "denque": "^2.0.1",
+        "generate-function": "^2.3.1",
+        "iconv-lite": "^0.6.3",
+        "long": "^4.0.0",
+        "lru-cache": "^6.0.0",
+        "named-placeholders": "^1.1.2",
+        "seq-queue": "^0.0.5",
+        "sqlstring": "^2.3.2"
+      },
+      "dependencies": {
+        "sqlstring": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
+          "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="
+        }
+      }
+    },
+    "named-placeholders": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
+      "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
+      "requires": {
+        "lru-cache": "^4.1.3"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+        }
+      }
+    },
+    "negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
+    },
+    "nodemon": {
+      "version": "2.0.20",
+      "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
+      "requires": {
+        "chokidar": "^3.5.2",
+        "debug": "^3.2.7",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.1.2",
+        "pstree.remy": "^1.1.8",
+        "semver": "^5.7.1",
+        "simple-update-notifier": "^1.0.7",
+        "supports-color": "^5.5.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.5"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.7",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "nopt": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+      "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+      "requires": {
+        "abbrev": "1"
+      }
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+    },
+    "object-inspect": {
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
+    },
+    "on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "one-time": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+      "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+      "requires": {
+        "fn.name": "1.x.x"
+      }
+    },
+    "onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "requires": {
+        "mimic-fn": "^2.1.0"
+      }
+    },
+    "ora": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz",
+      "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==",
+      "requires": {
+        "chalk": "^3.0.0",
+        "cli-cursor": "^3.1.0",
+        "cli-spinners": "^2.2.0",
+        "is-interactive": "^1.0.0",
+        "log-symbols": "^3.0.0",
+        "mute-stream": "0.0.8",
+        "strip-ansi": "^6.0.0",
+        "wcwidth": "^1.0.1"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
+    },
+    "parser": {
+      "version": "0.1.4",
+      "integrity": "sha512-f6EM/mBtPzmIh96MpcbePfhkBOYRmLYWuOukJqMysMlvjp4s2MQSSQnFEekd9GV4JGTnDJ2uFt3Ztcqc9wCMJg==",
+      "requires": {
+        "tokenizer": "*"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+    },
+    "picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+    },
+    "proxy-addr": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "requires": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
+    },
+    "pstree.remy": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
+    },
+    "qs": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+      "requires": {
+        "side-channel": "^1.0.4"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+    },
+    "raw-body": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
+      "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==",
+      "requires": {
+        "bytes": "1",
+        "string_decoder": "0.10"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+          "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ=="
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        }
+      }
+    },
+    "readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "restore-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+      "requires": {
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "run-async": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
+    },
+    "rxjs": {
+      "version": "6.6.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+    },
+    "safe-json-parse": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
+      "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A=="
+    },
+    "safe-stable-stringify": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz",
+      "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA=="
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+    },
+    "send": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      }
+    },
+    "seq-queue": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
+      "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
+    },
+    "serve-static": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+      "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.18.0"
+      }
+    },
+    "setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+    },
+    "side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "requires": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      }
+    },
+    "signal-exit": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+    },
+    "simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "requires": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "simple-update-notifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+      "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+      "requires": {
+        "semver": "~7.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+          "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A=="
+        }
+      }
+    },
+    "sqlstring": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
+      "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ=="
+    },
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="
+    },
+    "statuses": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
+    },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        }
+      }
+    },
+    "string-template": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
+      "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw=="
+    },
+    "string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "requires": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      }
+    },
+    "strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "requires": {
+        "ansi-regex": "^5.0.1"
+      }
+    },
+    "supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "requires": {
+        "has-flag": "^4.0.0"
+      }
+    },
+    "text-hex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+      "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "requires": {
+        "os-tmpdir": "~1.0.2"
+      }
+    },
+    "to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "requires": {
+        "is-number": "^7.0.0"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+    },
+    "tokenizer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/tokenizer/-/tokenizer-1.1.2.tgz",
+      "integrity": "sha512-c/EYsBwEW/EX28q44UaSrJ9o5M2aI+N/xdJJ4Zl7dNq76OmWQHhmXH0T8DJQNjVYPc7NclV2CZQfyeUMfnEu/A==",
+      "requires": {
+        "disect": "~1.1.0"
+      }
+    },
+    "touch": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+      "requires": {
+        "nopt": "~1.0.10"
+      }
+    },
+    "triple-beam": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
+      "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
+    },
+    "tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "type-fest": {
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
+    },
+    "type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      }
+    },
+    "undefsafe": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+      "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
+    },
+    "uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
+    },
+    "wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+      "requires": {
+        "defaults": "^1.0.3"
+      }
+    },
+    "winston": {
+      "version": "3.8.2",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz",
+      "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==",
+      "requires": {
+        "@colors/colors": "1.5.0",
+        "@dabh/diagnostics": "^2.0.2",
+        "async": "^3.2.3",
+        "is-stream": "^2.0.0",
+        "logform": "^2.4.0",
+        "one-time": "^1.0.0",
+        "readable-stream": "^3.4.0",
+        "safe-stable-stringify": "^2.3.1",
+        "stack-trace": "0.0.x",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.5.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "winston-transport": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz",
+      "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==",
+      "requires": {
+        "logform": "^2.3.2",
+        "readable-stream": "^3.6.0",
+        "triple-beam": "^1.3.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    }
+  },
+  "scripts": {
+    "start": "node ./app.js",
+    "start:dev": "nodemon ./app.js"
+  }
+}

+ 29 - 0
package.json

@@ -0,0 +1,29 @@
+{
+  "name": "dvr-backend",
+  "version": "1.0.0",
+  "description": "",
+  "main": "app.js",
+  "scripts": {
+    "start": "nodemon app.js",
+    "start:dev": "node ./app.js"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "bcryptjs": "^2.4.3",
+    "body": "^5.1.0",
+    "cookie-parser": "^1.4.6",
+    "cors": "^2.8.5",
+    "cros": "^1.0.1",
+    "express": "^4.18.2",
+    "jsonwebtoken": "^8.5.1",
+    "mkdirp": "^1.0.4",
+    "moment": "^2.29.4",
+    "mysql": "^2.18.1",
+    "mysql2": "^2.3.3",
+    "nodemon": "^2.0.20",
+    "object-assign": "^4.1.1",
+    "parser": "^0.1.4",
+    "winston": "^3.8.2"
+  }
+}

+ 46 - 0
routes/route.js

@@ -0,0 +1,46 @@
+const express = require('express');
+const router = express.Router();
+const bodyParser = require('body-parser');
+const loginController = require("../controllers/loginController");
+const dvrController =require("../controllers/dvrReportController");
+const auth = require("../middlewares/authorize");
+
+
+router.use(bodyParser.urlencoded({ extended: true }))
+router.use(bodyParser.json());
+
+router.post("/signupuser", loginController.signupuser);
+router.post("/loginuser", loginController.loginUser);
+router.get("/getselectionData",auth,dvrController.getselectionData);
+
+
+router.post("/createContactEntry",auth,dvrController.createContactEntry);
+
+
+router.get("/getdvrdetails",auth,dvrController.getdvrDetails);
+router.get("/getdashboarddetails",auth,dvrController.getdashboarddetails);
+
+router.post("/createDvrEntry",auth,dvrController.createDvrEntry);
+router.put("/updateDvrEntry",auth,dvrController.updatedvrDetails);
+
+router.post("/userrolemap",auth ,loginController.userrolemap);
+
+router.post("/createCustomerEntry",auth,dvrController.createCustomerentry);
+
+router.put("/updateContactDetails",auth,dvrController.updateContactDetails);
+router.put("/updateCustomerDetails",auth,dvrController.updateCustomerDetails);
+router.get("/getlastestdvr",auth,dvrController.getlastestdvr);
+
+router.get("/getcontactdetails",auth,dvrController.getcontactDetails);
+
+router.get("/getsalepersonlist",auth,dvrController.getsalePersonList);
+
+router.get("/getcustcontactdetails",auth,dvrController.getCustcontactDetails);
+router.post("/createUpdateCustomerentry",auth,dvrController.createUpdateCustomerentry);
+
+router.post("/deletedvrEntry",auth,dvrController.deletedvrEntry);
+
+
+
+
+module.exports = router;

+ 58 - 0
services/dbconnection.js

@@ -0,0 +1,58 @@
+const mysql2 = require('mysql2');
+const db = require('../configs/config.json')
+const pool = mysql2.createPool(
+    {
+        connectionLimit: 20,
+        host: db.database.host,
+        user: db.database.user,
+        password: db.database.password,
+        database: db.database.database,
+        port:db.database.port
+
+    }
+);
+
+exports.executequery = function (query) {
+    return new Promise((result, reject) => {
+        // //console.log(pool);
+        // get the connection for connection pool
+        pool.getConnection((error, connection) => {
+            // if error during getting connection
+            if (error) {
+                //console.log("Connection Error -->>", error);
+                reject(error)
+            } else {
+                //console.log("db connected");
+                connection.query(query, function (err, rows, fields) {
+                    connection.release();
+                    if (err) {
+                        result(err);
+                    };
+                    result(rows);
+                });
+            }
+        });
+    });
+}
+
+
+exports.executevaluesquery = function (query, values) {
+    return new Promise((result, reject) => {
+        // get the connection for connection pool
+        pool.getConnection((error, connection) => {
+            if (error) {
+                //console.log("Connection Error -->>", error);
+                reject(error)
+            } else {
+                connection.query(query, values, function (err, rows, fields) {
+                    //release Conncetion
+                    connection.release();
+                    if (err) {
+                        reject(err);
+                    };
+                    result(rows);
+                });
+            }
+        });
+    });
+}

+ 4 - 0
sql query/sqlquery.sql

@@ -0,0 +1,4 @@
+
+alter table contact_master add stage_id int;
+
+alter table dvr_report add login_id BIGINT;

+ 27 - 0
undefined/logs.log

@@ -0,0 +1,27 @@
+{
+  '0': {
+    user_id: 7,
+    login_id: 'deepika.kaushik@mindcraft.co.in',
+    first_name: 'Deepika',
+    last_name: 'Kaushik',
+    last_login_date: 2024-08-30T16:29:00.000Z,
+    password: 'msadmin@123'
+  },
+  level: 'info',
+  message: 'log of login api search login user query result',
+  label: 'winston custom format',
+  timestamp: 'Aug-31-2024 00:56:34'
+}
+{
+  fieldCount: 0,
+  affectedRows: 1,
+  insertId: 0,
+  info: 'Rows matched: 1  Changed: 1  Warnings: 0',
+  serverStatus: 34,
+  warningStatus: 0,
+  changedRows: 1,
+  level: 'info',
+  message: 'log of login api update user last_login_date query result',
+  label: 'winston custom format',
+  timestamp: 'Aug-31-2024 00:56:34'
+}

+ 31 - 0
utils/logger.js

@@ -0,0 +1,31 @@
+const { format, createLogger, transports } = require("winston");
+const { combine, timestamp, label, printf, prettyPrint } = format;
+const CATEGORY = "winston custom format";
+const config = require("../configs/config.json")
+
+const logger = createLogger({
+  level: "debug",
+  format: combine(
+    label({ label: CATEGORY }),
+    timestamp({
+      format: "MMM-DD-YYYY HH:mm:ss",
+    }),
+    prettyPrint()
+  ),
+//   transports: [
+//     new transports.Console()
+// ],
+transports: [
+    //new transports:
+    new transports.File({
+      filename: config.logfolderpath+"/logs.log",
+    }),
+  ],
+});
+
+module.exports = logger;
+
+
+
+
+