diff --git a/.gitignore b/.gitignore index 1f44e33e709e253e0786eb34dd2414a976e54215..fa70f3954fbda74bfca6d7b78af746b23b4a7d18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules dynare_m +dynare_m_old +dynare.db diff --git a/app.js b/app.js index b56d788dfb67e8597eb7559f9c21dfb2dfe68034..ef153fa3d6026a4da0d86796b87630390bda6437 100644 --- a/app.js +++ b/app.js @@ -79,6 +79,10 @@ const child = fork(program, parameters, options); // ); // ipc.server.start(); +var initprogressbar=0; +var progressbarcount=0; + + global.mysocket; ipc.config.id = 'appIPC'; ipc.config.retry = 1500; @@ -87,6 +91,13 @@ ipc.serve(() => ipc.server.on('rundynarematlab', (data, socket) => { global.mysocket=socket; console.log('received ipc message from router'); console.log(data) + + if (data=='estimation') + { + initprogressbar=1; + progressbarcount=0; + } + mymessage={'messageid': 'rundynarematlab','messagetype': data}; child.send(mymessage); }) @@ -126,12 +137,43 @@ child.on('message', message => { finishperfect(); } + if (message.message==3){ + console.log('-=estimation computation completed=-'); + finishestimation(); + } + } if (message.messageid=='stdoutmessage'){ - console.log("stdoutmessage"); - console.log(`${message.message}`); - sockIO.emit('matlabmessagetoconsole', message.message); + // console.log("stdoutmessage"); + // console.log(`${message.message}`); + // console.log(message.message); + // console.log(message.messagetype); + + if (message.messagetype=='progressbar'){ + if (initprogressbar==1) + { + initprogressbar=0; + sockIO.emit('matlabmessagetoconsole_progressbar_init', message.message); + console.log('matlabmessagetoconsole_progressbar_init sent'); + } + else { + + progressbarcount=progressbarcount+1; + + if (progressbarcount%50==0){ + sockIO.emit('matlabmessagetoconsole_progressbar', message.message); + // console.log('matlabmessagetoconsole_progressbar'); + } + + + } + + } + else{ + console.log(message.message); + sockIO.emit('matlabmessagetoconsole', message.message); + } messageprocess=1; } @@ -153,6 +195,23 @@ initdb(); // }); +async function finishestimation() { + + // loading JSON output from Matlab + try { + estmatlabdata = await loadjsonfile('estimout.JSON'); + } catch (error) { + return console.log('Unable to open estimout.JSON to process:' + error); + } + + sockIO.emit('estimationfinish', estmatlabdata); + + console.log(estmatlabdata); + + return false; + +} + async function finishstochastic() { // loading JSON output from Matlab diff --git a/appModules.js b/appModules.js index 05a9b1047adcb282c7ddf0545ace3c4e6bdab4ad..a9162a4f95e1e51c44c6235ab3b386649b09d914 100644 --- a/appModules.js +++ b/appModules.js @@ -48,22 +48,21 @@ module.exports = { var mymodel; console.log(dbpath) - + let db = new sqlite3.Database(dbpath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { if (err) { console.log('problem here') console.error(err.message); return console.log(err.message); - } - else{ + } else { console.log('Connected to the dynare database.'); } }); - - - + + + let sql = `SELECT COUNT(*) as mycount FROM sqlite_master WHERE type='table' AND name='dynaremodel';`; - + db.get(sql, [], (err, row) => { if (err) { return console.error(err.message); @@ -74,14 +73,14 @@ module.exports = { timestamp = new Date().toISOString().slice(0, 19).replace('T', ' '); db.serialize(() => { // Queries scheduled here will be serialized. - db.run(`CREATE TABLE dynaremodel ( id INTEGER NOT NULL, modelhash VARCHAR(100) NOT NULL, modelname VARCHAR(100) NOT NULL, modelcode TEXT, modelextrassinfo TEXT, modelextrasstype INTEGER, modelcreatedon DATETIME NOT NULL, modelupdatedon DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE (modelhash) );`,[], function(err) { + db.run(`CREATE TABLE dynaremodel ( id INTEGER NOT NULL, modelhash VARCHAR(100) NOT NULL, modelname VARCHAR(100) NOT NULL, modelcode TEXT, modelextrassinfo TEXT, modelextrasstype INTEGER, modelcreatedon DATETIME NOT NULL, modelupdatedon DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE (modelhash) );`, [], function (err) { if (err) { return console.log(err.message); } // get the last insert id console.log(`dynaremodel created`); }); - db.run(`INSERT INTO dynaremodel(modelhash,modelname,modelcode,modelcreatedon,modelupdatedon) VALUES(?,?,?,?,?)`, [modelhashuuid, modelhashuuid, '%Enter model here', timestamp, timestamp], function(err) { + db.run(`INSERT INTO dynaremodel(modelhash,modelname,modelcode,modelcreatedon,modelupdatedon) VALUES(?,?,?,?,?)`, [modelhashuuid, modelhashuuid, '%Enter model here', timestamp, timestamp], function (err) { if (err) { return console.log(err.message); } @@ -96,14 +95,14 @@ module.exports = { // // createNewModel(mymodel); // } // }); - + db.close((err) => { if (err) { return console.error(err.message); } }); }); - + } // else { // //there is a table in the database, we get the latest model @@ -123,14 +122,14 @@ module.exports = { // } // }); // }); - + // } - - + + }); - - - + + + return; }, @@ -191,7 +190,7 @@ module.exports = { } catch (error) { return reject(new Error('Unable to close database in getmodelfromdb: ' + error)); } - + // returning promise if (('modelhash' in dynaremodel)) { console.log('Model was found in database.'); @@ -289,7 +288,7 @@ module.exports = { // returning promise if (('modelhash' in dynaremodel)) { - console.log('Model updated and retrived successfully in database.'); + console.log('Model updated and retrieved successfully in database.'); return resolve(dynaremodel) } else { return reject(new Error('modelhash was not found in dynaremodel in savetodb: ' + error)); @@ -409,13 +408,13 @@ module.exports = { }; // --- - modelhash=short.generate(); + modelhash = short.generate(); // updating database async let sql1 = `INSERT INTO dynaremodel(modelhash,modelname,modelcode,modelcreatedon,modelupdatedon) VALUES(?,?,?,?,?);`; timestamp = new Date().toISOString().slice(0, 19).replace('T', ' '); try { - await db.runAsync(sql1, [modelhash,modelname, '%Enter model here', timestamp,timestamp]); + await db.runAsync(sql1, [modelhash, modelname, '%Enter model here', timestamp, timestamp]); } catch (error) { return reject(new Error('Unable to insert new model in newmodelindb: ' + error)); } @@ -437,7 +436,7 @@ module.exports = { // returning promise if (('modelhash' in dynaremodel)) { - console.log('New model created and retrived successfully in database.'); + console.log('New model created and retrieved successfully in database.'); return resolve(dynaremodel) } else { return reject(new Error('modelhash was not found in dynaremodel in newmodelindb: ' + error)); @@ -447,10 +446,6 @@ module.exports = { }, - - - - basedir: function (myfilename) { //retrives path to the console return (path.resolve(__dirname, './assets/modfiles/' + myfilename)); @@ -480,6 +475,17 @@ module.exports = { }); }, + movenewdatafile: function (myfilename, myfiletype, myfilepath) { + //moves an uploaded data file from its temporary directory to the work folder + return new Promise(function (resolve, reject) { + var filePath = path.resolve(__dirname, './assets/modfiles/' + myfilename + '_datafile.' + myfiletype); + fs.rename(myfilepath, filePath, function (err) { + if (err) return reject(new Error('Unable to move datafile to work folder: ' + err)); + return resolve(); + }); + }); + }, + loadjsonfile: function (myfilename) { return new Promise(function (resolve, reject) { @@ -517,7 +523,7 @@ module.exports = { removeoldfile: function (myfilename) { return new Promise(function (resolve, reject) { - console.log("");//leave this it helps with a weird bug + console.log(""); //leave this it helps with a weird bug var filePath = path.resolve(__dirname, './assets/modfiles/' + myfilename); fs.stat(filePath, function (err, stats) { @@ -571,7 +577,7 @@ module.exports = { } if (pptype == 2) { // cwd is important here - child = spawn(exePath, [myfilename], { + child = spawn(exePath, [myfilename, 'console'], { cwd: workPath }); } @@ -598,7 +604,8 @@ module.exports = { if (code == 0) { return resolve(dynarestdout); } else { - return reject(new Error('dynare_m did not exit with code 0 in preprocess: ' + dynarestdout)); + //this will return the error output of the preprocessor and replace the local modfile path with just 'modfile'. The RegExp is used to replace all occurences + return reject(new Error(dynarestdout.replace(new RegExp(filePath, 'g'), 'modfile') + 'Dynare preprocessor did not exit with code 0 in preprocess.\n\n')); } }); }); @@ -621,7 +628,7 @@ module.exports = { }); } - console.log(modeljson) + // console.log(modeljson) // removing old files try { @@ -660,7 +667,7 @@ module.exports = { }); } - + // preparing temp.mod file content @@ -789,6 +796,146 @@ module.exports = { } } + + console.log('in preparejsonfiles before estimation writing'); + + + + if (runtype == 3) { + //for estimation we don't write a json file but write everything on the mod file + + //writing observables + if ('obsdescription' in jsonindata) { + modfilecontent += 'varobs '; + Object.keys(jsonindata['obsdescription']).forEach((key, index) => { + modfilecontent += modeljson['endogenous'][parseInt(jsonindata['obsdescription'][key]['obsindex'], 10)]['longName'] + ' '; + }); + modfilecontent += ';\n\n'; + } + + //writing estimated params + + var priorname = ['dummy', 'dummy', 'beta_pdf', 'gamma_pdf', 'normal_pdf', 'uniform_pdf', 'inv_gamma_pdf', 'inv_gamma1_pdf', 'inv_gamma2_pdf', 'weibull_pdf']; + + if ('pardescription' in jsonindata) { + + // console.log(jsonindata['pardescription']) + + modfilecontent += 'estimated_params;\n'; + Object.keys(jsonindata['pardescription']).forEach((key, index) => { + + + if (jsonindata['pardescription'][key]['parshockindex'] > 999) { + if (jsonindata['pardescription'][key]['parassoshockindex'] > 0) { + modfilecontent += "corr " + modeljson['exogenous'][parseInt(jsonindata['pardescription'][key]['parshockindex'], 10) - 1000]['longName'] + ',' + modeljson['exogenous'][parseInt(jsonindata['pardescription'][key]['parassoshockindex'], 10) - 1000]['longName'] + ', '; + } else { + modfilecontent += "stderr " + modeljson['exogenous'][parseInt(jsonindata['pardescription'][key]['parshockindex'], 10)-1000]['longName'] + ', '; + } + } else { + modfilecontent += modeljson['parameters'][parseInt(jsonindata['pardescription'][key]['parshockindex'], 10)]['longName'] + ', '; + } + + if (!(jsonindata['pardescription'][key]['parinivalue'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parinivalue'] + ', '; + } else { + modfilecontent += 'NaN,'; + } + + if (!(jsonindata['pardescription'][key]['parLbound'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parLbound'] + ', '; + } else { + modfilecontent += 'NaN,'; + } + + if (!(jsonindata['pardescription'][key]['parUbound'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parUbound'] + ', '; + } else { + modfilecontent += 'NaN'; + } + + if (jsonindata['pardescription'][key]['parprior'] > 1) { + modfilecontent +=','+ priorname[parseInt(jsonindata['pardescription'][key]['parprior'], 10)] + ', '; + + + if (!(jsonindata['pardescription'][key]['parpriormean'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parpriormean'] + ', '; + } + + if (!(jsonindata['pardescription'][key]['parpriorstderr'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parpriorstderr'] + ', '; + } + + if (!(jsonindata['pardescription'][key]['parprior3par'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parprior3par'] + ', '; + } else { + modfilecontent += 'NaN,'; + } + + if (!(jsonindata['pardescription'][key]['parprior4par'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parprior4par'] + ', '; + } else { + modfilecontent += 'NaN,'; + } + + + if (!(jsonindata['pardescription'][key]['parpriorscale'] === null)) { + modfilecontent += jsonindata['pardescription'][key]['parpriorscale'] + ', '; + } + else{ + modfilecontent += 'NaN'; + } + + } + + modfilecontent += ';\n'; + + // modfilecontent += modeljson['endogenous'][parseInt(jsonindata['obsdescription'][key]['obsindex'], 10)]['longName']+ ' '; + }); + modfilecontent += 'end;\n\n'; + } + + //writing estimation command + + console.log(jsonindata['nobs']) + console.log(jsonindata['mhreplic']) + console.log(jsonindata['mhnblocks']) + console.log(jsonindata['mhjscale']) + + modfilecontent +="estimation(datafile='"+modelhash + "_datafile."+jsonindata['datafiletype']+"'"; + + //put all the estimation options here + if (!(jsonindata['nobs'] === null)) { + modfilecontent +=',nobs='+parseInt(jsonindata['nobs'], 10); + } + + if (!(jsonindata['mhreplic'] === null)) { + modfilecontent +=',mh_replic='+parseInt(jsonindata['mhreplic'], 10); + } + + if (!(jsonindata['mhnblocks'] === null)) { + modfilecontent +=',mh_nblocks='+parseInt(jsonindata['mhnblocks'], 10); + } + + if (!(jsonindata['mhjscale'] === null)) { + modfilecontent +=',mh_jscale='+parseInt(jsonindata['mhjscale'], 10); + } + + + //end of options close estimation command + modfilecontent +=');' + + + + + + + + + + } + + console.log('in preparejsonfiles AFTER estimation writing'); + // writing the temp.mod file try { await module.exports.createnewfile('temp.mod', modfilecontent); @@ -867,6 +1014,36 @@ module.exports = { } } + // if (runtype == 3) { + // //writes JSON file for estimation + // try { + // await module.exports.removeoldfile('estimout.JSON'); + // } catch (error) { + // return reject({ + // 'status': 100, + // 'message': error.toString() + // }); + // } + // try { + // await module.exports.removeoldfile('estimin.JSON'); + // } catch (error) { + // return reject({ + // 'status': 100, + // 'message': error.toString() + // }); + // } + // try { + // await module.exports.createnewfile('estimin.JSON', JSON.stringify(jsonindata)); + // } catch (error) { + // return reject({ + // 'status': 100, + // 'message': 'Unable to create estimin.JSON in preparejsonfile\n' + error + // }); + // } + // } + + + return resolve(); }); //end of promise function } diff --git a/assets/dynareapp.JSON b/assets/dynareapp.JSON index f407dcd22b20d369212ce0b06a7160b2c069e5ba..8678ec488652b612fb1ec601d849a7039c89fddc 100644 --- a/assets/dynareapp.JSON +++ b/assets/dynareapp.JSON @@ -1 +1 @@ -{"matlabpath":"/Applications/MATLAB_R2018a.app","dynarepath":"/Applications/Dynare/20180602"} \ No newline at end of file +{"matlabpath":"/Applications/MATLAB_R2018a.app","dynarepath":"/Applications/Dynare/4.6.2"} \ No newline at end of file diff --git a/assets/modfiles/di_estimation.m b/assets/modfiles/di_estimation.m new file mode 100644 index 0000000000000000000000000000000000000000..86c7f2bf69405fc0e88de566e0cb890405bc87fe --- /dev/null +++ b/assets/modfiles/di_estimation.m @@ -0,0 +1,109 @@ +function di_stochastic_simulations() + + global M_ options_ oo_ dataset_ estim_params_ + + + disp('di_estimation performing Matlab tasks'); + + + data2json=struct(); + + data2json.exo_names=char(M_.exo_names); + data2json.param_names=char(M_.param_names); + data2json.exo_nbr=M_.exo_nbr; + data2json.param_nbr=M_.param_nbr; + + %Smoothed shocks + if isfield(oo_,'SmoothedShocks')==1 + data2json.SmoothedShocks=oo_.SmoothedShocks; + end + + %Data + data2json.obs_nbr=length(dataset_.name); + data2json.obs_names=char(dataset_.name); + data2json.obs_data=dataset_.data; + + data2json.obs_data={}; + for nobs = 1:length(dataset_.name) + data2json.obs_data.(strtrim(char(dataset_.name(nobs,:))))=dataset_.data(:,nobs); + end + + %Smoothed observables + if isfield(oo_,'SmoothedVariables')==1 + data2json.SmoothedObs={}; + for nobs = 1:length(dataset_.name) + data2json.SmoothedObs.(strtrim(char(dataset_.name(nobs,:))))=oo_.SmoothedVariables.(strtrim(char(dataset_.name(nobs,:)))); + end + end + + if isfield(oo_,'mle_mode')==1 + %this is produced only with ML estim + data2json.estimtypeflag=0; %this will indicate ML estimation + + % if isfield(oo_.mle_mode,'parameters')==1 + % data2json.mle_mode_params=oo_.mle_mode.parameters; + % data2json.mle_std_params=oo_.mle_std_at_mode.parameters; + % end + + % if isfield(oo_.mle_mode,'shocks_std')==1 + % data2json.mle_mode_shocks_std=oo_.mle_mode.shocks_std; + % data2json.mle_std_shocks_std=oo_.mle_std_at_mode.shocks_std; + % end + + if isfield(oo_,'mle_mode')==1 + data2json.mle_mode=oo_.mle_mode; + end + + if isfield(oo_,'mle_std_at_mode')==1 + data2json.mle_std_at_mode=oo_.mle_std_at_mode; + end + + else + data2json.estimtypeflag=1; %this will indicate Bayesian estimation + + %prior info + + + + if isfield(estim_params_,'param_vals')==1 + if isempty(estim_params_.param_vals)==0 + data2json.param_vals=estim_params_.param_vals; + end + end + + if isfield(estim_params_,'var_exo')==1 + if isempty(estim_params_.var_exo)==0 + data2json.var_exo=estim_params_.var_exo; + end + end + + if isfield(estim_params_,'corrx')==1 + if isempty(estim_params_.corrx)==0 + data2json.corrx=estim_params_.corrx; + end + end + + %prior density + if isfield(oo_,'prior_density')==1 + data2json.prior_density=oo_.prior_density; + end + + %posterior + if isfield(oo_,'posterior_density')==1 + data2json.posterior_density=oo_.posterior_density; + end + + if isfield(oo_,'posterior_mode')==1 + data2json.posterior_mode=oo_.posterior_mode; + data2json.posterior_std=oo_.posterior_std_at_mode; + data2json.posterior_mean=oo_.posterior_mean; + data2json.posterior_hpdinf=oo_.posterior_hpdinf; + data2json.posterior_hpdsup=oo_.posterior_hpdsup; + end + + end + + + savejson('',data2json,'estimout.JSON'); + +return; diff --git a/assets/modfiles/di_stochastic_simulations.m b/assets/modfiles/di_stochastic_simulations.m index d59a7e77769028230ba13a05c19aa1a336f84654..8cb40c2e7698beee68575473e2b56b389f862757 100644 --- a/assets/modfiles/di_stochastic_simulations.m +++ b/assets/modfiles/di_stochastic_simulations.m @@ -43,7 +43,7 @@ function di_stochastic_simulations() % options_.k_order_solver = 3; % end var_list_ = char(); - info = stoch_simul(var_list_); + [info, oo_, options_, M_] = stoch_simul(M_, options_, oo_, var_list_);%stoch_simul(var_list_); irfnames=fieldnames(oo_.irfs); for jj = 1:numel(fieldnames(oo_.irfs)) diff --git a/background.js b/background.js index 99b45734b5f40d95e749edc724d5c855da777ee4..bb4bcd0407646633b9b19fc35706736e7533dfab 100644 --- a/background.js +++ b/background.js @@ -26,7 +26,7 @@ async function main() { //loading matlab var exePath = path.resolve(__dirname, pathholder.matlabpath + '/bin/matlab'); - const child = spawn(exePath, ['-nosplash'], { + const child = spawn(exePath, ['-nosplash -nodisplay'], { shell: true }); @@ -63,6 +63,14 @@ async function main() { }; } + if (origincalltype == 3) { + //this is the return from estimation computation + mymessage = { + 'messageid': 'matlabready', + 'message': 3 + }; + } + // process.send('matlabready', origincalltype); process.send(mymessage); // } @@ -70,11 +78,28 @@ async function main() { // origincalltype += 1; // } } else { - // process.send('stdoutmessage', data) - mymessage = { - 'messageid': 'stdoutmessage', - 'message': `${data}` - }; + + + if (data[0] == 8){ + //capturing RW Metropolis-Hastings (1/2) Current acceptance ratio wrong char + data=data.slice(69).toString(); + data=data+'\n'; + mymessage = { + 'messageid': 'stdoutmessage', + 'messagetype': 'progressbar', + 'message': data //'message': `${data}` + }; + } + else{ + data=data.toString(); + mymessage = { + 'messageid': 'stdoutmessage', + 'messagetype': 'normal', + 'message': data //'message': `${data}` + }; + } + + process.send(mymessage); } }); @@ -98,13 +123,19 @@ async function main() { if (pmessage.messagetype=='stochastic'){ origincalltype = 1; - child.stdin.write('run temp.m;run di_stochastic_simulations.m;\n'); + child.stdin.write('run temp.driver.m;run di_stochastic_simulations.m;\n'); child.stdin.on('drain', () => {}); } if (pmessage.messagetype=='perfect'){ origincalltype = 2; - child.stdin.write('run temp.m;run di_perfect_foresight.m;\n'); + child.stdin.write('run temp.driver.m;run di_perfect_foresight.m;\n'); + child.stdin.on('drain', () => {}); + } + + if (pmessage.messagetype=='estimation'){ + origincalltype = 3; + child.stdin.write('run temp.driver.m;run di_estimation.m;\n'); child.stdin.on('drain', () => {}); } diff --git a/middleware/runprocesses.js b/middleware/runprocesses.js index e0e077684f56f40d27f261b0fa0d2dc3438cec18..1e48ae18dacfd78d6be6197dd18df8d0751412e4 100644 --- a/middleware/runprocesses.js +++ b/middleware/runprocesses.js @@ -5,6 +5,8 @@ const preprocess = require('../appModules').preprocess; const loadjsonfile = require('../appModules').loadjsonfile; const checkfileexist = require('../appModules').checkfileexist; const preparejsonfiles = require('../appModules').preparejsonfiles; +const path = require('path'); +var fs = require('fs'); const ipc = require('node-ipc'); @@ -67,7 +69,8 @@ module.exports = { var dynarestdout = ''; var preprocok = 1; try { - dynarestdout += await preprocess(dynaremodel['modelhash'] + '_ini.mod', 3); + // dynarestdout += await preprocess(dynaremodel['modelhash'] + '_ini.mod', 3);//does not work for some reason... + dynarestdout += await preprocess(dynaremodel['modelhash'] + '_ini.mod', 1); } catch (error) { dynarestdout += error.toString(); preprocok = 0; @@ -163,6 +166,44 @@ module.exports = { }); } + //starting with Dynare 4.6 the JSON file is created in a subfolder and it is called 'modfile.json' + //for simplicity we move it out of there and delete the folder + + new Promise(function (resolve, reject) { + var oldfilepath = path.resolve(__dirname, '../assets/modfiles/' + dynaremodel['modelhash'] + '_ini/model/json/modfile.json'); + console.log(oldfilepath) + var newfilePath = path.resolve(__dirname, '../assets/modfiles/' + dynaremodel['modelhash'] + '_ini.json'); + console.log(newfilePath) + fs.rename(oldfilepath, newfilePath, function (err) { + if (err) return reject(new Error('Unable to move model JSON to work folder: ' + err)); + return resolve(); + }); + }); + + + + new Promise(function (resolve, reject) { + var oldfilepath = path.resolve(__dirname, '../assets/modfiles/' + dynaremodel['modelhash'] + '_ini/model/json/steady_state_model.json'); + var newfilePath = path.resolve(__dirname, '../assets/modfiles/' + dynaremodel['modelhash'] + '_ini_steady_state_model.json'); + fs.rename(oldfilepath, newfilePath, function (err) { + if (err) return reject(new Error('Unable to move steady_state_model JSON to work folder: ' + err)); + return resolve(); + }); + }); + + //careful the following rmdir function requires node version 12 or higher + new Promise(function (resolve, reject) { + var oldfilepath = path.resolve(__dirname, '../assets/modfiles/' + dynaremodel['modelhash'] + '_ini/'); + fs.rmdir(oldfilepath, { + recursive: true + }, function (err) { + if (err) return reject(new Error('Unable to remove directory: ' + err)); + return resolve(); + }); + }); + + + // loading JSON created by dynare preprocessor try { var dynaremodeljson = await loadjsonfile(dynaremodel['modelhash'] + '_ini.json'); @@ -173,7 +214,7 @@ module.exports = { 'message': 'Unable to open file ' + basedir(dynaremodel['modelhash'] + '_ini.json') }); } - console.log(dynaremodeljson); + // console.log(dynaremodeljson); // showconsolealert(dynarestdout); if (dynaremodeljson['exogenous'] == null || dynaremodeljson['exogenous'].length < 1) { @@ -221,62 +262,72 @@ module.exports = { }); //end of main promise }, - runstochasticnode: (stosimval) => { + runestimationnode: (estimval) => { return new Promise(async function (resolve, reject) { - - console.log('inside runstochasticnode'); - - var modelhash = stosimval['modelhash']; + var modelhash = estimval['modelhash']; // preparing only the standardized JSON in data - var stochsimindata = { - 'taylororder': stosimval['taylororder'], - 'irfperiods': stosimval['irfperiods'], - 'stochasticshocksdescription': stosimval['stochasticshocksdescription'] + var estimindata = { + 'nobs': estimval['parnobs'], + 'mhreplic': estimval['parmhreplic'], + 'mhnblocks': estimval['parmhnblocks'], + 'mhjscale': estimval['parmhjscale'], + 'obsdescription': estimval['obsdescription'], + 'pardescription': estimval['pardescription'], + 'datafiletype': estimval['datafiletype'] }; try { - await preparejsonfiles(modelhash, 2, stosimval, stochsimindata); + await preparejsonfiles(modelhash, 3, estimval, estimindata); } catch (error) { return reject(error); } - // const reply = ipc.sendSync('performMatlab', 111); - // cl(reply); - - console.log('before IPC') - ipc.config.id = 'routerIPC'; ipc.config.retry = 1500; - // ipc.config.silent = true; - ipc.connectTo('appIPC', () => { ipc.of.appIPC.on('connect', () => { - ipc.of.appIPC.emit('rundynarematlab', "stochastic"); + ipc.of.appIPC.emit('rundynarematlab', "estimation"); ipc.disconnect('appIPC'); }); - - // ipc.of.appIPC.on('message', (data) => { - // console.log('back in runstochastic') - // console.log(data); - // }); - }); + return resolve('Done runstochasticnode !'); + }); //end of main promise + }, + runstochasticnode: (stosimval) => { - // this code will get the local user directory (do not erase until used) - // console.log(app.getPath('userData')); + return new Promise(async function (resolve, reject) { + var modelhash = stosimval['modelhash']; + // preparing only the standardized JSON in data + var stochsimindata = { + 'taylororder': stosimval['taylororder'], + 'irfperiods': stosimval['irfperiods'], + 'stochasticshocksdescription': stosimval['stochasticshocksdescription'] + }; + try { + await preparejsonfiles(modelhash, 2, stosimval, stochsimindata); + } catch (error) { + return reject(error); + } + ipc.config.id = 'routerIPC'; + ipc.config.retry = 1500; + ipc.connectTo('appIPC', () => { + ipc.of.appIPC.on('connect', () => { + ipc.of.appIPC.emit('rundynarematlab', "stochastic"); + ipc.disconnect('appIPC'); + }); + }); - // console.log('runstochasticnode last'); return resolve('Done runstochasticnode !'); @@ -285,14 +336,10 @@ module.exports = { }, - runperfectnode: (perfectval) => { return new Promise(async function (resolve, reject) { - - console.log('inside runperfectnode'); - var modelhash = perfectval['modelhash']; // preparing only the standardized JSON in data var perfectindata = { @@ -314,41 +361,18 @@ module.exports = { return reject(error); } - // const reply = ipc.sendSync('performMatlab', 111); - // cl(reply); - console.log('before IPC') ipc.config.id = 'routerIPC'; ipc.config.retry = 1500; - // ipc.config.silent = true; - ipc.connectTo('appIPC', () => { ipc.of.appIPC.on('connect', () => { ipc.of.appIPC.emit('rundynarematlab', "perfect"); ipc.disconnect('appIPC'); }); - // ipc.of.appIPC.on('message', (data) => { - // console.log('back in runstochastic') - // console.log(data); - // }); - }); - - - - - - - // this code will get the local user directory (do not erase until used) - // console.log(app.getPath('userData')); - - - - - // console.log('runstochasticnode last'); return resolve('Done runperfectnode !'); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..ec75b81c51e7538c9e2fc76cf7e46f06a50f03f4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2326 @@ +{ + "name": "webapp", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/babel-types": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", + "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==" + }, + "@types/babylon": { + "version": "6.16.5", + "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz", + "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==", + "requires": { + "@types/babel-types": "*" + } + }, + "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.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "^4.0.4" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "optional": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "optional": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "optional": true + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "optional": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "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" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "requires": { + "commander": "2.8.x", + "source-map": "0.4.x" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constantinople": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", + "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", + "requires": { + "@types/babel-types": "^7.0.0", + "@types/babylon": "^6.16.2", + "babel-types": "^6.26.0", + "babylon": "^6.18.0" + } + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "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==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-parser": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz", + "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==", + "requires": { + "cookie": "0.4.0", + "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": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "csrf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz", + "integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==", + "requires": { + "rndm": "1.2.0", + "tsscmp": "1.0.6", + "uid-safe": "2.1.5" + } + }, + "csurf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz", + "integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "csrf": "3.1.0", + "http-errors": "~1.7.3" + }, + "dependencies": { + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "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" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "easy-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", + "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "engine.io": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", + "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "engine.io-client": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", + "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-pubsub": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", + "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==" + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + } + } + }, + "express-formidable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-formidable/-/express-formidable-1.2.0.tgz", + "integrity": "sha512-w1vXjF3gb50UKTNkFaW8/4rqY4dUrKfZ1sAZzwAF9YxCAgj/29QZsycf71di0GkskrZOAkubk9pvGYfxyAMYiw==", + "requires": { + "formidable": "^1.0.17" + } + }, + "express-handlebars": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-4.0.4.tgz", + "integrity": "sha512-WxbQorVc7V9ORzp9YpG3fLAzrfIrKcScSezuFxTZRFJSx/P2f7QJ9ZyADV8cyPuomyzUxAJnw6t8dnriLfBNvg==", + "requires": { + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "handlebars": "^4.7.6", + "object.assign": "^4.1.0", + "promise": "^8.1.0" + }, + "dependencies": { + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "requires": { + "asap": "~2.0.6" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "optional": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "optional": true + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "uglify-js": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz", + "integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==", + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "optional": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "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-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", + "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", + "requires": { + "acorn": "~4.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "optional": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "optional": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, + "js-message": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", + "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=" + }, + "js-queue": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz", + "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", + "requires": { + "easy-stack": "^1.0.0" + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "optional": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "needle": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", + "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "node-addon-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", + "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "optional": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + } + }, + "node-ipc": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz", + "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==", + "requires": { + "event-pubsub": "4.3.0", + "js-message": "1.0.5", + "js-queue": "2.0.0" + } + }, + "node-pre-gyp": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", + "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "optional": true, + "requires": { + "abbrev": "1" + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, + "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==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "optional": true + }, + "pug": { + "version": "2.0.0-beta11", + "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-beta11.tgz", + "integrity": "sha1-Favmr1AEx+LPRhPksnRlyVRrXwE=", + "requires": { + "pug-code-gen": "^1.1.1", + "pug-filters": "^2.1.1", + "pug-lexer": "^3.0.0", + "pug-linker": "^2.0.2", + "pug-load": "^2.0.5", + "pug-parser": "^2.0.2", + "pug-runtime": "^2.0.3", + "pug-strip-comments": "^1.0.2" + } + }, + "pug-attrs": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", + "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", + "requires": { + "constantinople": "^3.0.1", + "js-stringify": "^1.0.1", + "pug-runtime": "^2.0.5" + } + }, + "pug-code-gen": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-1.1.1.tgz", + "integrity": "sha1-HPcnRO8qA56uajNAyqoRBYcSWOg=", + "requires": { + "constantinople": "^3.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.1", + "pug-attrs": "^2.0.2", + "pug-error": "^1.3.2", + "pug-runtime": "^2.0.3", + "void-elements": "^2.0.1", + "with": "^5.0.0" + } + }, + "pug-error": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", + "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==" + }, + "pug-filters": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-2.1.5.tgz", + "integrity": "sha512-xkw71KtrC4sxleKiq+cUlQzsiLn8pM5+vCgkChW2E6oNOzaqTSIBKIQ5cl4oheuDzvJYCTSYzRaVinMUrV4YLQ==", + "requires": { + "clean-css": "^3.3.0", + "constantinople": "^3.0.1", + "jstransformer": "1.0.0", + "pug-error": "^1.3.2", + "pug-walk": "^1.1.5", + "resolve": "^1.1.6", + "uglify-js": "^2.6.1" + } + }, + "pug-lexer": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-3.1.0.tgz", + "integrity": "sha1-/QhzdtSmdbT1n4/vQiiDQ06VgaI=", + "requires": { + "character-parser": "^2.1.1", + "is-expression": "^3.0.0", + "pug-error": "^1.3.2" + } + }, + "pug-linker": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-2.0.3.tgz", + "integrity": "sha1-szH/olc33eacEntWwQ/xf652bco=", + "requires": { + "pug-error": "^1.3.2", + "pug-walk": "^1.1.2" + } + }, + "pug-load": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", + "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", + "requires": { + "object-assign": "^4.1.0", + "pug-walk": "^1.1.8" + } + }, + "pug-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-2.0.2.tgz", + "integrity": "sha1-U6aAz9BQOdywwn0CkJS8SnkmibA=", + "requires": { + "pug-error": "^1.3.2", + "token-stream": "0.0.1" + } + }, + "pug-runtime": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", + "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==" + }, + "pug-strip-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", + "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", + "requires": { + "pug-error": "^1.3.3" + } + }, + "pug-walk": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", + "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "optional": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, + "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": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "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" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "rndm": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", + "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=" + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "short-uuid": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-3.1.1.tgz", + "integrity": "sha512-7dI69xtJYpTIbg44R6JSgrbDtZFuZ9vAwwmnF/L0PinykbFrhQ7V8omKsQcVw1TP0nYJ7uQp1PN6/aVMkzQFGQ==", + "requires": { + "any-base": "^1.1.0", + "uuid": "^3.3.2" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", + "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + }, + "sqlite3": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.0.tgz", + "integrity": "sha512-rjvqHFUaSGnzxDy2AHCwhHy6Zp6MNJzCPGYju4kD8yi6bze4d1/zMTg6C7JI49b7/EM7jKMTvyfN/4ylBKdwfw==", + "requires": { + "node-addon-api": "2.0.0", + "node-gyp": "3.x", + "node-pre-gyp": "^0.11.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "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" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "optional": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "token-stream": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", + "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "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" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "optional": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "with": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", + "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", + "requires": { + "acorn": "^3.1.0", + "acorn-globals": "^3.0.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + } + } +} diff --git a/package.json b/package.json index 7bc3de54e07bd648a0f5d2fed8598f5dc746182c..6c7b5c285f862e6f6aa2b91150d90dd289c99972 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "csurf": "^1.11.0", "debug": "~2.6.9", "express": "~4.16.1", + "express-formidable": "^1.2.0", "express-handlebars": "^4.0.4", "http-errors": "~1.6.3", "morgan": "~1.9.1", diff --git a/public/static/css/dynareinterface.css b/public/static/css/dynareinterface.css index 6608639232ccf5c8b6cb7638819510c28805024e..b9624c6dc18d93b87f38dacbc670d0ca90966bac 100644 --- a/public/static/css/dynareinterface.css +++ b/public/static/css/dynareinterface.css @@ -104,6 +104,8 @@ body { padding-top: 70px; } } + + @@ -252,3 +254,83 @@ html { body, input { font: menu; // #A } + + +/* CSS tool tips */ + +.tooltipcss { + position: relative; + display: inline-block; + font-size:110% +} + +.tooltipcss .tooltiptextcss { + visibility: hidden; + width: 3000%; + background-color: #F5F5F5; + color: #808080; + text-align: justify; + border-radius: 6px; + padding: 10px; + /* Position the tooltip */ + position: absolute; + z-index: 1; + top: -5px; + right: 105%; +} + +/* .tooltipcss .tooltiptextcss::after { + content: ""; + position: absolute; + bottom: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent black transparent; +} */ + +.tooltipcss:hover .tooltiptextcss { + visibility: visible; +} + + +.tooltipcsshead { + position: relative; + display: inline-block; + font-size:70% +} + +.tooltipcsshead .tooltiptextcsshead { + visibility: hidden; + width: 3000%; + background-color: #F5F5F5; + color: #808080; + text-align: justify; + border-radius: 6px; + padding: 10px; + /* Position the tooltip */ + position: absolute; + z-index: 1; + top: -5px; + left: 105%; +} + + +.tooltipcsshead:hover .tooltiptextcsshead { + visibility: visible; +} + +#myProgress { + width: 100%; + background-color: #ddd; +} + +#myBar { + width: 0%; + height: 30px; + background-color: #5aa8f1; + text-align: center; + line-height: 30px; + color: white; +} diff --git a/public/static/js/dynareinterface.js b/public/static/js/dynareinterface.js index da20ca577466bc3734583ce7ddf4dcb6481055d0..c88914809274427c9956a3442e9127d22f51c370 100644 --- a/public/static/js/dynareinterface.js +++ b/public/static/js/dynareinterface.js @@ -40,6 +40,11 @@ function download(filename, text) { document.body.removeChild(element); } +function scrolltextarea(){ + var textarea = document.getElementById('preprocessorout'); + textarea.scrollTop = textarea.scrollHeight; +} + function showconsolealert(content, showflag) { //writes to the console let newcontent = $("textarea#preprocessorout").val() + content; @@ -279,6 +284,7 @@ $('#runcode').click(function () { } else if (resp.status == 100) { console.log("100") showconsolealert(resp.message, 1); + scrolltextarea(); console.log('console error'); return false; } @@ -306,5 +312,50 @@ $('#runcode').click(function () { $(function () { socket.on('matlabmessagetoconsole', function(msg){ showconsolealert(`${msg}`,0); + scrolltextarea(); + }); +}); + +var numberPattern = /\d+/g; +// var modalupdatecount; + +$(function () { + //initializes the MH progress bar + socket.on('matlabmessagetoconsole_progressbar_init', function(msg){ + + $('#MHmodal').modal({backdrop: 'static', keyboard: false}) ; + $('#MHmodal').modal('show'); + // modalupdatecount=0; + // console.log('matlabmessagetoconsole_progressbar_init received'); + // document.getElementById("MHloop").innerHTML="1"; + }); +}); + +$(function () { + //updates the MH progress bar + socket.on('matlabmessagetoconsole_progressbar', function(msg){ + // console.log('matlabmessagetoconsole_progressbar received'); + + // modalupdatecount++; + // if (modalupdatecount%10==0){ + // $('#MHmodal').modal('show'); + // } + + var mynumarray=msg.match(numberPattern); + document.getElementById("MHloop").innerHTML=mynumarray[0]; + document.getElementById("MHloopover").innerHTML=mynumarray[1]; + document.getElementById("MHCAR").innerHTML=mynumarray[2].toString()+'.'+mynumarray[3].toString(); + + var elem = document.getElementById("myBar"); + var width = mynumarray[4]; + + if (width >= 100) { + i = 0; + } else { + // width++; + elem.style.width = width + "%"; + elem.innerHTML = width + "%"; + } + }); }); diff --git a/public/static/js/estimation.js b/public/static/js/estimation.js new file mode 100644 index 0000000000000000000000000000000000000000..5df233ac565c556d6e08220937a4f2c57d9b4d29 --- /dev/null +++ b/public/static/js/estimation.js @@ -0,0 +1,1629 @@ + +var estmatlabdata; + +$('#setestimation').click(function () { + + // let basedir = path.resolve(__dirname, './assets/modfiles/'); + + let modelname = $('#codename').val(); + if (modelname == null || modelname == "") { + $.alert({ + title: 'Project name is empty.', + content: 'Please choose a name for this project...', + }); + return false; + } + + let modelcode = { + 'modelcode': window.editor_dynare.getValue(), + 'modelhash': $('#codehash').val(), + 'modelname': $('#codename').val(), + 'accesstype': 'setestimation' + }; + + $.ajax({ + url: $(editorform).attr('action'), + headers: { + 'x-csrf-token': $('#_csrf').val() + }, + type: "POST", + data: modelcode, + success: function (resp) { + + console.log('returned') + + if (resp.status == 200) { + console.log("200") + return popthis('Error', resp.message); + } else if (resp.status == 100) { + console.log("100") + showconsolealert(resp.message, 1); + scrolltextarea(); + console.log('console error'); + return false; + } + + showconsolealert(resp.message, 1); + scrolltextarea(); + + var currentdate = new Date(); + $('#classlist-form-messages').text('Last saved at: ' + currentdate); + + + dynaremodel = resp.modeljson; + + // if a steady state has not been provided if ask extra info on that + // steady-state compute table + document.getElementById("estinittable").innerHTML = ""; + if (resp.status == 201) { + var extrassinfo = ""; + var extrasshelp = ""; + if (resp.extrassinfo !== null) { + extrassinfo = resp.extrassinfo; + extrasshelp = " (the last known steady-state info have been loaded below)" + } + var extrasstype = ""; + if (resp.extrasstype == 1) { + extrasstype = 'checked'; + } + + sscomputeeendo = ` + <h4>Steady state</h4> + <p style="color:#3399CC">You did not provide any way to compute the steady-state. Please specify a way to compute the steady-state` + extrasshelp + `.</p> + <div class="form-group no-margin"> <textarea class="form-control" id="estSSblock" name="estSSblock" placeholder="Steady-state equations;" rows="7">` + extrassinfo + `</textarea> </div> + <div class="form-group no-margin"><label><input type="checkbox" name="estissteadystateblock" id="estissteadystateblock"` + extrasstype + `/> Check if the above will compute the exact steady-state (will be interpreted as a <span style="font-style: italic;">steady_state_model</span> block). Leave unchecked if the above should be used as a starting point to compute the steady-state (will be interpreted as an <span style="font-style: italic;">initval</span> block).</label></div> + <input id="estmodelsteadystatestatus" name="estmodelsteadystatestatus" value="99" type="hidden"> + `; + } else if (resp.status == 2) { + sscomputeeendo = ` + <input id="estmodelsteadystatestatus" name="estmodelsteadystatestatus" value="55" type="hidden"> + `; + } else { + sscomputeeendo = ` + <input id="estmodelsteadystatestatus" name="estmodelsteadystatestatus" value="0" type="hidden"> + `; + } + document.getElementById("estinittable").innerHTML = sscomputeeendo; + document.getElementById("estmodel_endonum").value = (dynaremodel.endogenous).length; + document.getElementById("estmodel_exonum").value = (dynaremodel.exogenous).length; + document.getElementById("estmodel_paramnum").value = (dynaremodel.exogenous).length + (dynaremodel.parameters).length; + $('#estimModal').modal('show'); + + + }, + error: function () { + console.log('there was a problem checking the fields'); + } + }); + return false; + +}); + + +var estobsnum = []; +var estparnum = []; +for (i = 0; i < 1000; i++) { + estobsnum[i] = 0; + estparnum[i] = 0; +} + + +$('#estaddobs').click(function () { + var estobsrowindex; + var estobsxcond = 0; + var estobsiter = 0; + + while (estobsxcond == 0) { + if (estobsnum[estobsiter] == 0) { + estobsxcond = 1; + estobsrowindex = estobsiter; + estobsnum[estobsiter] = 1; + } + estobsiter = estobsiter + 1; + } + estobsexpectedshockstable = ''; + estobsexpectedshockstable += '<tr><td><select id="estobsvarname' + estobsrowindex + '" class="form-control input-sm" name="estobsvarname">'; + for (x in dynaremodel.endogenous) { + estobsexpectedshockstable += '<option value="' + x + '">' + dynaremodel.endogenous[x]["longName"] + '</option>'; + } + estobsexpectedshockstable += "</select></td>"; + + + estobsexpectedshockstable += '<td><input type="button" value="X" onclick="estobsSomeDeleteRowFunction(this,' + estobsrowindex + ')" class="form-control no-border input-sm btn-default btn-xs" name="estobsremoveshock' + estobsrowindex + '" id="estobsremoveshock' + estobsrowindex + '"></td></tr>'; + $('#estobstable tbody').append(estobsexpectedshockstable); + return false; +}); + +function estobsSomeDeleteRowFunction(o, estobsrowindex) { + var p = o.parentNode.parentNode; + p.parentNode.removeChild(p); + estobsnum[estobsrowindex] = 0; +} + + + + +$('#estaddparam').click(function () { + var estparrowindex; + var estparxcond = 0; + var estpariter = 0; + var exovarcounter = 999; + while (estparxcond == 0) { + if (estparnum[estpariter] == 0) { + estparxcond = 1; + estparrowindex = estpariter; + estparnum[estpariter] = 1; + } + estpariter = estpariter + 1; + } + estparexpectedshockstable = ''; + estparexpectedshockstable += '<tr><td><select id="estparname' + estparrowindex + '" class="form-control input-sm" name="estparname" onchange="enableestvarcorr(' + estparrowindex + ')">'; + estparexpectedshockstable += '<option disabled>Parameters</option>'; + for (x in dynaremodel.parameters) { + estparexpectedshockstable += '<option value="' + x + '">' + dynaremodel.parameters[x]["longName"] + '</option>'; + } + + estparexpectedshockstable += '<option disabled>Exo variables</option>'; + for (x in dynaremodel.exogenous) { + exovarcounter++; + estparexpectedshockstable += '<option value="' + exovarcounter + '">' + dynaremodel.exogenous[x]["longName"] + '</option>'; + } + estparexpectedshockstable += "</select></td>"; + + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparvalue' + estparrowindex + '" id="estparvalue' + estparrowindex + '" placeholder="Value"></td>'; + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparLbound' + estparrowindex + '" id="estparLbound' + estparrowindex + '" placeholder="L. Bound"></td>'; + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparUbound' + estparrowindex + '" id="estparUbound' + estparrowindex + '" placeholder="U. Bound"></td>'; + + estparexpectedshockstable += '<td><select id="estparprior' + estparrowindex + '" class="form-control input-sm" name="estparprior' + estparrowindex + '" onchange="enablebayesian(' + estparrowindex + ')"><option value="1" selected="selected">N/A</option><option value="2">beta_pdf</option><option value="3">gamma_pdf</option><option value="4">normal_pdf</option><option value="5">uniform_pdf</option><option value="6">inv_gamma_pdf</option><option value="7">inv_gamma1_pdf</option><option value="8">inv_gamma2_pdf</option><option value="9">weibull_pdf</option></td>'; + + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparpriormean' + estparrowindex + '" id="estparpriormean' + estparrowindex + '" placeholder="Prior mean" disabled></td>'; + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparpriorstderr' + estparrowindex + '" id="estparpriorstderr' + estparrowindex + '" placeholder="Prior Std. Err" disabled></td>'; + + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparprior3par' + estparrowindex + '" id="estparprior3par' + estparrowindex + '" placeholder="Prior 3rd param" disabled></td>'; + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparprior4par' + estparrowindex + '" id="estparprior4par' + estparrowindex + '" placeholder="Prior 4th param" disabled></td>'; + estparexpectedshockstable += '<td><input type="text" class="form-control no-border input-sm" name="estparpriorscale' + estparrowindex + '" id="estparpriorscale' + estparrowindex + '" placeholder="Scale" disabled></td>'; + + exovarcounter = 999; + estparexpectedshockstable += '<td><select id="estparcorrvar' + estparrowindex + '" class="form-control input-sm" name="estparcorrvar' + estparrowindex + '" disabled>'; + estparexpectedshockstable += '<option value="0">N/A</option>'; + for (x in dynaremodel.exogenous) { + exovarcounter++; + estparexpectedshockstable += '<option value="' + exovarcounter + '">' + dynaremodel.exogenous[x]["longName"] + '</option>'; + } + estparexpectedshockstable += "</select></td>"; + estparexpectedshockstable += '<td><input type="button" value="X" onclick="estparSomeDeleteRowFunction(this,' + estparrowindex + ')" class="form-control no-border input-sm" name="estparremoveshock' + estparrowindex + '" id="estparremoveshock' + estparrowindex + '"></td></tr>'; + $('#estpartable tbody').append(estparexpectedshockstable); + return false; +}); + +function estparSomeDeleteRowFunction(o, estparrowindex) { + var p = o.parentNode.parentNode; + p.parentNode.removeChild(p); + estparnum[estparrowindex] = 0; +} + +function enablebayesian(shockindex) { + var selectedvalue = $("#estparprior" + shockindex).val(); + if (selectedvalue < 2) { + $("#estparpriormean" + shockindex).attr('disabled', 'disabled'); + $("#estparpriorstderr" + shockindex).attr('disabled', 'disabled'); + $("#estparprior3par" + shockindex).attr('disabled', 'disabled'); + $("#estparprior4par" + shockindex).attr('disabled', 'disabled'); + $("#estparpriorscale" + shockindex).attr('disabled', 'disabled'); + } else { + $("#estparpriormean" + shockindex).removeAttr('disabled'); + $("#estparpriorstderr" + shockindex).removeAttr('disabled'); + $("#estparprior3par" + shockindex).removeAttr('disabled'); + $("#estparprior4par" + shockindex).removeAttr('disabled'); + $("#estparpriorscale" + shockindex).removeAttr('disabled'); + } +} + +function enableestvarcorr(shockindex) { + var selectedvalue = $("#estparname" + shockindex).val(); + if (selectedvalue < 1000) { + $("#estparcorrvar" + shockindex).val('0'); + $("#estparcorrvar" + shockindex).attr('disabled', 'disabled'); + } else { + $("#estparcorrvar" + shockindex).removeAttr('disabled'); + } +} + + +$('#runestimation').click(async function () { + + + var estendonum = $('#estmodel_endonum').val(); + var estparamnum = $('#estmodel_paramnum').val(); + + // var datafilepath = $('#estfile'); + var datafilepath = document.getElementById("estfile"); + var estssstatus = $('#estmodelsteadystatestatus').val(); + var estssdescription = []; + + + + + //checking input file and extension + if (datafilepath.files.length == 0) { + $('.nav-tabs a[href="#estimsetuptable"]').tab('show'); + popthis('Setup error.', 'You did not provide a data file. This action is mandatory.'); + return (0); + } else { + var filename = datafilepath.files[0].name; + extension = filename.split('.').pop(); + var allowedextensions = ['m', 'mat', 'xls', 'xlsx', 'csv']; + var extcheck = 0; + allowedextensions.forEach(function (myextension) { + if (extension == myextension) { + extcheck = 1; + } + }); + if (extcheck == 0) { + $('.nav-tabs a[href="#estimsetuptable"]').tab('show'); + popthis('Setup error.', 'The file you provided does not seem to be of the correct type. Please provide a file with one of the following extensions:.m, .mat, .xls, .xlsx, .csv.'); + return (0); + } + } + + + // steady-state info check + if (estssstatus == 99) { + estsstext = $('#estSSblock').val(); + if (estsstext.length == 0) { + $('.nav-tabs a[href="#estimsetuptable"]').tab('show'); + popthis('Setup error.', 'Please provide a way to compute the steady-state.'); + return (0); + } + if ($('#estissteadystateblock').is(":checked") == true) { + var estsstype = 1; + } else { + var estsstype = 2; + } + estssdescription.push({ + 'sstext': estsstext, + 'sstype': parseInt(estsstype, 10) + }); + } + + + + // Observations table check + + //observables + var obsglobalvaluescount = 0; + var obsattributeflag = []; + for (i = 0; i < estendonum; i++) { + obsattributeflag[i] = 0; + } + var obsindex; + var obsdescription = []; + + var obsrowCount = $('#estobstable tr').length - 1; // careful this counts the th row as a row, thus the -1 + + if (obsrowCount > 0) { + // there are shocks in the table + obsglobalvaluescount = 1; + + var obsxcond = 0; + var obsiter = 0; + var obscountshocks = 0; + + while (obsxcond == 0) { + // we iterate over global estobsnum that kept track of observable indexes in any order they were entered + if (estobsnum[obsiter] == 1) { + // if estobsnum identifies a valid row in the table, we start further checks + obscountshocks = obscountshocks + 1; + + // We fetch shock infos + obsindex = $('#estobsvarname' + obsiter.toString()).val(); + + + //we check if the same observable has already been declared + if (obsattributeflag[obsindex] > 0) { + $('.nav-tabs a[href="#estimsetuptable"]').tab('show'); + popthis('Setup error.', 'The observable variable on row ' + obscountshocks + ', has already been declared. Please enter each observable only once.'); + return (0); + } else { + obsattributeflag[obsindex] = 1; + } + + + + obsdescription.push({ + 'obsindex': parseInt(obsindex, 10) + }); + + //we count the number of this specific shock + // shocksflag[shockindex] = shocksflag[shockindex] + 1; + } + if (obscountshocks == obsrowCount) { + obsxcond = 1; + } + obsiter = obsiter + 1; + } + } + + + // estimated params table check + + var parglobalvaluescount = 0; + var parattributeflag = []; + for (i = 0; i < estparamnum; i++) { + parattributeflag[i] = 0; + } + var parindex; + var pardescription = []; + + var parpairs = []; + + var parrowCount = $('#estpartable tr').length - 1; // careful this counts the th row as a row, thus the -1 + + if (parrowCount > 0) { + // there are parameters in the table + parglobalvaluescount = 1; + + var parxcond = 0; + var pariter = 0; + var parcountshocks = 0; + + console.log("parcountshocks"); + console.log(parcountshocks); + + var bayesiancount = 0; + var mlcount = 0; + + while (parxcond == 0) { + // we iterate over global estparnum that kept track of shock indexes in any order they were entered + if (estparnum[pariter] == 1) { + // if estparnum identifies a valid row in the table, we start further checks + parcountshocks = parcountshocks + 1; + + //we find the true row number of the current checked line in the table + var partablerow = $('#estparname' + pariter.toString()).closest('tr'); + var partablerowindex = partablerow.index() + 1; + + + // We fetch parameter infos + parshockindex = $('#estparname' + pariter.toString()).val(); + console.log('parshockindex'); + console.log(parshockindex); + + parinivalue = $('#estparvalue' + pariter.toString()).val(); + parLbound = $('#estparLbound' + pariter.toString()).val(); + parUbound = $('#estparUbound' + pariter.toString()).val(); + parprior = $('#estparprior' + pariter.toString()).val(); + parpriormean = $('#estparpriormean' + pariter.toString()).val(); + parpriorstderr = $('#estparpriorstderr' + pariter.toString()).val(); + parprior3par = $('#estparprior3par' + pariter.toString()).val(); + parprior4par = $('#estparprior4par' + pariter.toString()).val(); + parpriorscale = $('#estparpriorscale' + pariter.toString()).val(); + // parcorrattributevalue = $("#estparcorrvar" + pariter.toString()).val(); + + parinivalue = parinivalue.trim(); + parLbound = parLbound.trim(); + parUbound = parUbound.trim(); + parpriormean = parpriormean.trim(); + parpriorstderr = parpriorstderr.trim(); + parprior3par = parprior3par.trim(); + parprior4par = parprior4par.trim(); + parpriorscale = parpriorscale.trim(); + + // parassoshockindex = -10; + parassoshockindex = $('#estparcorrvar' + pariter.toString()).val(); + + console.log("parassoshockindex") + console.log(parassoshockindex) + + if (parshockindex > 999) { + //we first validate the case of an exogenous variable been selected (and correlation issues) + + + if (parassoshockindex > 0) { //if correlation has been selected + + if (parshockindex == parassoshockindex) { + $('.nav-tabs a[href="#estimparams"]').tab('show'); + popthis('Variables error.', 'On row ' + partablerowindex + ', the correlation should be specified for separate variables.'); + return (0); + } + + // we verify if correlation has already been specified for any two same shocks + if (Number(parassoshockindex) > Number(parshockindex)) { + if (parpairs.indexOf(parshockindex + '-' + parassoshockindex) == -1) { + parpairs.push(parshockindex + '-' + parassoshockindex); + } else { + popthis('Variables error.', 'On row ' + partablerowindex + ', this covariance/correlation has already been specified between these variables.'); + return (0); + } + } else { + if (parpairs.indexOf(parassoshockindex + '-' + parshockindex) == -1) { + parpairs.push(parassoshockindex + '-' + parshockindex); + } else { + popthis('Variables error.', 'On row ' + partablerowindex + ', this covariance/correlation has already been specified between these variables.'); + return (0); + } + } + + } + + } + + //Standard check for all parameters/variables + + + + //Check if parameter declared twice + if (parassoshockindex < 1000) { + if (parattributeflag[parshockindex] > 0) { + popthis('Pameters error.', 'On row ' + partablerowindex + ', You have already specified attributes for this parameter/variable. Please add only one row per parameter/variable.'); + return (0); + } else { + parattributeflag[parshockindex] = 1; + } + } + + //} + + var parvalueflag = 0; + + // we validate the shock value + if (!(parinivalue == null || parinivalue == "")) { + if (!(IsNumeric(parinivalue))) { + if (!(parinivalue.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The parameter value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } else { + parvalueflag = 1; + } + + } else { + parvalueflag = 1; + } + } + + // we validate the shock prior mean + if (parprior > 1) { + bayesiancount += 1; + if (!(parpriormean == null || parpriormean == "")) { + if (!(IsNumeric(parpriormean))) { + if (!(parpriormean.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The parameter prior mean on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } else { + parvalueflag = 1; + } + } else { + parvalueflag = 1; + } + } + + if (!(parpriorstderr == null || parpriorstderr == "")) { + if (!(IsNumeric(parpriorstderr))) { + if (!(parpriorstderr.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The prior stdErr value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } else { + popthis('Parameter error.', 'You did not specify a prior stdErr for parameter on row ' + partablerowindex + '. This information is mandatory if you specified a prior shape.'); + return (0); + } + + if (!(parprior3par == null || parprior3par == "")) { + if (!(IsNumeric(parprior3par))) { + if (!(parprior3par.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The prior 3rd param value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } + + if (!(parprior4par == null || parprior4par == "")) { + if (!(IsNumeric(parprior4par))) { + if (!(parprior4par.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The prior 4rd param value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } + + if (!(parpriorscale == null || parpriorscale == "")) { + if (!(IsNumeric(parpriorscale))) { + if (!(parpriorscale.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The prior scale value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } + } else { + mlcount += 1; + } + + + if (parvalueflag == 0) { + popthis('Parameter error.', 'You did not specify a value or a prior mean for parameter on row ' + partablerowindex + '. One of these information is mandatory.'); + return (0); + } + + + if (!(parLbound == null || parLbound == "")) { + if (!(IsNumeric(parLbound))) { + if (!(parLbound.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The lower bound value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } + + if (!(parUbound == null || parUbound == "")) { + if (!(IsNumeric(parUbound))) { + if (!(parUbound.toLowerCase() == "inf")) { + popthis('Parameter error.', 'The upper bound value on row ' + partablerowindex + ' is not a number or inf.'); + return (0); + } + } + } + + console.log('bayesiancount'); + console.log(bayesiancount); + console.log(mlcount); + + if ((bayesiancount > 0) && (mlcount > 0)) { + popthis('Parameter error.', 'Estimation must be either fully ML or fully Bayesian. Please declare only variables/parameters with priors or only variables/parameters without priors.'); + return (0); + + + } + + + + + pardescription.push({ + 'parshockindex': parseInt(parshockindex, 10), + 'parinivalue': (parinivalue.toLowerCase()=='inf') ? (parinivalue.toLowerCase()):(parseFloat(parinivalue, 10)), + 'parLbound': (parLbound.toLowerCase()=='inf') ? (parLbound.toLowerCase()):(parseFloat(parLbound, 10)), + 'parUbound': (parUbound.toLowerCase()=='inf') ? (parUbound.toLowerCase()):(parseFloat(parUbound, 10)), + 'parprior': parseInt(parprior, 10), + 'parpriormean': (parpriormean.toLowerCase()=='inf') ? (parpriormean.toLowerCase()):(parseFloat(parpriormean, 10)), + 'parpriorstderr': (parpriorstderr.toLowerCase()=='inf') ? (parpriorstderr.toLowerCase()):(parseFloat(parpriorstderr, 10)), + 'parprior3par': (parprior3par.toLowerCase()=='inf') ? (parprior3par.toLowerCase()):(parseFloat(parprior3par, 10)), + 'parprior4par': (parprior4par.toLowerCase()=='inf') ? (parprior4par.toLowerCase()):(parseFloat(parprior4par, 10)), + 'parpriorscale': (parpriorscale.toLowerCase()=='inf') ? (parpriorscale.toLowerCase()):(parseFloat(parpriorscale, 10)), + 'parassoshockindex': parseInt(parassoshockindex, 10) + }); + + //we count the number of this specific shock + // shocksflag[shockindex] = shocksflag[parshockindex] + 1; + } + if (parcountshocks == parrowCount) { + parxcond = 1; + } + pariter = pariter + 1; + } + + + } + + + if (obsglobalvaluescount == 0) { + $('.nav-tabs a[href="#estimsetuptable"]').tab('show'); + popthis('Estimation input error.', 'You have submitted no observable variable(s) for the estimation. Please add observable variable(s) and retry.'); + return (0); + } + + if (parglobalvaluescount == 0) { + $('.nav-tabs a[href="#estimparams"]').tab('show'); + popthis('Estimation input error.', 'You have submitted no parameters/variables to be estimated. Please add observable variable(s) and retry.'); + return (0); + } + + + // options check + + parnobs = $('#estimopt_nobs').val(); + parmhreplic = $('#estimopt_mh_replic').val(); + parmhnblocks = $('#estimopt_mh_nblocks').val(); + parmhjscale = $('#estimopt_mh_jscale').val(); + + if (!(parnobs == null || parnobs == "")) { + if (!(Number.isInteger(Number(parnobs)))) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of observations should be an integer number.'); + return (0); + } + if (Number(parnobs) < 0) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of observations cannot be negative.'); + return (0); + } + } + + if (!(parmhreplic == null || parmhreplic == "")) { + if (!(Number.isInteger(Number(parmhreplic)))) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of replications should be an integer number.'); + return (0); + } + if (Number(parmhreplic) < 0) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of replications cannot be negative.'); + return (0); + } + } + + if (!(parmhnblocks == null || parmhnblocks == "")) { + if (!(Number.isInteger(Number(parmhnblocks)))) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of blocks should be an integer number.'); + return (0); + } + if (Number(parmhnblocks) < 0) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Number of blocks cannot be negative.'); + return (0); + } + } + + if (!(parmhjscale == null || parmhjscale == "")) { + if (!(IsNumeric(parmhjscale))) { + $('.nav-tabs a[href="#estimoptions"]').tab('show'); + popthis('Options error.', 'Scale parameter is not a number.'); + return (0); + } + } + + + + + + + + + + + + + //we post to the server + + console.log('Ready to post variables'); + + //getting the file to be sent + + // var formData = new FormData(document.getElementById("estfile").files[0]); + // formData.append("CustomField", "This is some extra data"); + + var fd = new FormData(); + var re = /(?:\.([^.]+))?$/; + fd.append("file", document.getElementById('estfile').files[0]); + fd.append("filename", $('#codehash').val()); + fd.append("filetype", re.exec(document.getElementById('estfile').files[0].name)[1]); + + // console.log(fd) + + var estimationval = { + 'modelhash': $('#codehash').val(), + 'parnobs': parseInt(parnobs, 10), + 'parmhreplic': parseInt(parmhreplic, 10), + 'parmhnblocks': parseInt(parmhnblocks, 10), + 'parmhjscale': parseInt(parmhjscale, 10), + 'ssstatus': parseInt(estssstatus, 10), + 'ssdescription': estssdescription, + 'obsdescription': obsdescription, + 'pardescription': pardescription, + 'datafiletype': re.exec(document.getElementById('estfile').files[0].name)[1], + 'accesstype': 'runestimation' + }; + + var estimationvaldata = JSON.stringify(estimationval); + $("#outputtable").empty(); + $("#outputtable2").empty(); + $("#plotbtn").empty(); + $("#plotbox").empty(); + $('#estimModal').modal('hide'); + var div = document.createElement('div'); + div.className = 'loader'; + div.innerHTML = ''; + document.getElementById('inner').appendChild(div); + $('.nav-tabs a[href="#console"]').tab('show'); + + console.log(estimationvaldata); + + + $.ajax({ + headers: { + 'x-csrf-token': $('#_csrf').val() + }, + url: "/fileroute", + type: "POST", + data: fd, + processData: false, // indique Ă jQuery de ne pas traiter les donnĂ©es + cache: false, + contentType: false, // indique Ă jQuery de ne pas configurer le contentType + success: function (resp) { + + console.log(resp); + + //if file upload was sucessful we send rest of the data + $.ajax({ + url: $(editorform).attr('action'), + headers: { + 'x-csrf-token': $('#_csrf').val() + }, + type: "PUT", + contentType: "application/json", + dataType: 'json', + data: estimationvaldata, + success: function (resp) { + + // console.log(resp) + if (resp.status == 200) { + console.log("200") + return popthis('Error', resp.message); + } else if (resp.status == 100) { + console.log("100") + showconsolealert(resp.message, 1); + scrolltextarea(); + console.log('console error'); + return false; + } + + console.log('All done here !') + + }, + error: function (e) { + console.log('there was a problem checking the fields:' + e); + } + + + + + }); + + }, + error: function (e) { + console.log('Unable to upload datafile to server: ' + e); + } + }); + + + + + + + + return false; + + + +}); + + +$(function () { + socket.on('estimationfinish', function (msg) { + // $('#messages').append($('<li>').text(msg)); + // console.log(msg); + scrolltextarea(); + $('#MHmodal').modal('hide'); + + $('.nav-tabs a[href="#output"]').tab('show'); + + estmatlabdata = msg; + + if (estmatlabdata.estimtypeflag == 0) { + //Reporting ML estimation + + var estbl1 = ` + <section> + <h2>Results from Maximum Likelihood Estimation</h2> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th>#</th> + <th>Variable/parameter</th> + <th>Estimate</th> + <th>Std. Dev</th> + <th>t-stat</th> + </tr> + </thead> + <tbody> + `; + + + + if ("parameters" in estmatlabdata.mle_mode) { + estbl1 += '<tr><th id="par" colspan="5" scope="colgroup">Parameters</th></tr>'; + y = 0; + for (x in estmatlabdata.mle_mode.parameters) { + y = y + 1; + estbl1 += '<tr><th scope="row">' + y + '</th>'; + + estbl1 += "<td>" + x + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_mode.parameters[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_std_at_mode.parameters[x] + "</td>"; + estbl1 += "<td></td></tr>"; + } + } + + if ("shocks_std" in estmatlabdata.mle_mode) { + estbl1 += '<tr><th id="par" colspan="5" scope="colgroup">Std. Dev. of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.mle_mode.shocks_std) { + y = y + 1; + estbl1 += '<tr><th scope="row">' + y + '</th>'; + + estbl1 += "<td>" + x + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_mode.shocks_std[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_std_at_mode.shocks_std[x] + "</td>"; + estbl1 += "<td></td></tr>"; + } + } + + if ("shocks_corr" in estmatlabdata.mle_mode) { + estbl1 += '<tr><th id="par" colspan="5" scope="colgroup">Correlation of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.mle_mode.shocks_corr) { + y = y + 1; + estbl1 += '<tr><th scope="row">' + y + '</th>'; + + estbl1 += "<td>" + x + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_mode.shocks_corr[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.mle_std_at_mode.shocks_corr[x] + "</td>"; + estbl1 += "<td></td></tr>"; + } + } + + + estbl1 += "</tbody></table></section>"; + + + var plotdropdown = ` + <section> + <h2>Plots</h2> + <div class="btn-group" role="group" aria-label="..."> + <div class="btn-group" role="group"> + <button id="plotbtn" class="btn btn-primary btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Select graph <span class="caret"></span><span class="sr-only">Toggle Dropdown</span> + </button> + <ul class="dropdown-menu" aria-labelledby="plotbtn"> + <li class="dropdown-header">Smoothed shocks:</li>`; + + y = 0; + if ("SmoothedShocks" in estmatlabdata) { + for (x in estmatlabdata.SmoothedShocks) { + plotdropdown += '<li onclick="estplotsmoothedshocks("' + x + '")"><a href="#stophere">' + x + '</a></li>'; + if (y == 0) { + var firstname = x; + y = 1; + } + } + } + + plotdropdown += '<li class="dropdown-header">Historical and smoothed variables:</li>'; + + if ("SmoothedObs" in estmatlabdata) { + for (x in estmatlabdata.SmoothedObs) { + plotdropdown += '<li onclick="estplotsmoothedvars("' + x + '")"><a href="#stophere">' + x + '</a></li>'; + } + } + + plotdropdown += '</ul></div>'; + plotdropdown += ` + <div class="btn-group" role="group"> + <button id="exportbtn" class="btn btn-primary btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Export data <span class="caret"></span><span class="sr-only">Toggle Dropdown</span> + </button> + <ul class="dropdown-menu" aria-labelledby="exportbtn"> + <li class="dropdown-header">Select file type:</li> + <li onclick="exportfile("json")"><a href="#stophere">Export to JSON</a></li> + <li onclick="exportfile("csv")"><a href="#stophere">Export to CSV</a></li> + </ul> + </div>`; + + plotdropdown += ` + </div> + </section> + `; + document.getElementById("plotbtn").innerHTML = plotdropdown; + + + estplotsmoothedshocks(firstname); + + } + + var priorname = ['dummy', 'beta_pdf', 'gamma_pdf', 'normal_pdf', 'inv_gamma_pdf', 'uniform_pdf', 'inv_gamma2_pdf', 'dummy', 'weibull_pdf']; + + if (estmatlabdata.estimtypeflag == 1) { + //Reporting Bayesian estimation + + + var estbl1 = ` + <section> + <h2>Results from Posterior Estimation</h2> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th>#</th> + <th>Variable/parameter</th> + <th>Prior mean</th> + <th>Mode</th> + <th>Std. Dev</th> + <th>Prior</th> + <th>Pstdev</th> + </tr> + </thead> + <tbody> + `; + + + if ("param_vals" in estmatlabdata) { + estbl1 += '<tr><th id="par" colspan="7" scope="colgroup">Parameters</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mode.parameters) { + estbl1 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl1 += "<td>" + x + "</td>"; + + if (Array.isArray(estmatlabdata.param_vals[0])) { + estbl1 += "<td>" + estmatlabdata.param_vals[y][5] + "</td>"; + } else { + estbl1 += "<td>" + estmatlabdata.param_vals[5] + "</td>"; + } + + estbl1 += "<td>" + estmatlabdata.posterior_mode.parameters[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.posterior_std.parameters[x] + "</td>"; + if (Array.isArray(estmatlabdata.param_vals[0])) { + estbl1 += "<td>" + priorname[estmatlabdata.param_vals[y][4]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.param_vals[y][6] + "</td>"; + } else { + estbl1 += "<td>" + priorname[estmatlabdata.param_vals[4]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.param_vals[6] + "</td>"; + } + estbl1 += "<td></td></tr>"; + y = y + 1; + } + } + + if ("var_exo" in estmatlabdata) { + estbl1 += '<tr><th id="par" colspan="7" scope="colgroup">Standard deviation of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mode.shocks_std) { + estbl1 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl1 += "<td>" + x + "</td>"; + + if (Array.isArray(estmatlabdata.var_exo[0])) { + estbl1 += "<td>" + estmatlabdata.var_exo[y][5] + "</td>"; + } else { + estbl1 += "<td>" + estmatlabdata.var_exo[5] + "</td>"; + } + estbl1 += "<td>" + estmatlabdata.posterior_mode.shocks_std[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.posterior_std.shocks_std[x] + "</td>"; + if (Array.isArray(estmatlabdata.var_exo[0])) { + estbl1 += "<td>" + priorname[estmatlabdata.var_exo[y][4]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.var_exo[y][6] + "</td>"; + } else { + estbl1 += "<td>" + priorname[estmatlabdata.var_exo[4]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.var_exo[6] + "</td>"; + } + estbl1 += "<td></td></tr>"; + y = y + 1; + } + } + + if ("corrx" in estmatlabdata) { + estbl1 += '<tr><th id="par" colspan="7" scope="colgroup">Correlation of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mode.shocks_corr) { + estbl1 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl1 += "<td>" + x + "</td>"; + + if (Array.isArray(estmatlabdata.corrx[0])) { + estbl1 += "<td>" + estmatlabdata.corrx[y][6] + "</td>"; + } else { + estbl1 += "<td>" + estmatlabdata.corrx[6] + "</td>"; + } + estbl1 += "<td>" + estmatlabdata.posterior_mode.shocks_corr[x] + "</td>"; + estbl1 += "<td>" + estmatlabdata.posterior_std.shocks_corr[x] + "</td>"; + if (Array.isArray(estmatlabdata.corrx[0])) { + estbl1 += "<td>" + priorname[estmatlabdata.corrx[y][5]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.corrx[y][7] + "</td>"; + } else { + estbl1 += "<td>" + priorname[estmatlabdata.corrx[5]] + "</td>"; + estbl1 += "<td>" + estmatlabdata.corrx[7] + "</td>"; + } + estbl1 += "<td></td></tr>"; + y = y + 1; + } + } + + estbl1 += "</tbody></table></section>"; + + + + var estbl2 = ` + <section> + <h2>Estimation Results</h2> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th>#</th> + <th>Variable/parameter</th> + <th>Prior mean</th> + <th>Post. mean</th> + <th>90% HPD int. (inf)</th> + <th>90% HPD int. (sup)</th> + <th>Prior</th> + <th>Pstdev</th> + </tr> + </thead> + <tbody> + `; + + if ("param_vals" in estmatlabdata) { + estbl2 += '<tr><th id="par" colspan="8" scope="colgroup">Parameters</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mean.parameters) { + estbl2 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl2 += "<td>" + x + "</td>"; + + if (Array.isArray(estmatlabdata.param_vals[0])) { + estbl2 += "<td>" + estmatlabdata.param_vals[y][5] + "</td>"; + } else { + estbl2 += "<td>" + estmatlabdata.param_vals[5] + "</td>"; + } + estbl2 += "<td>" + estmatlabdata.posterior_mean.parameters[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdinf.parameters[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdsup.parameters[x] + "</td>"; + + if (Array.isArray(estmatlabdata.param_vals[0])) { + estbl2 += "<td>" + priorname[estmatlabdata.param_vals[y][4]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.param_vals[y][6] + "</td>"; + } else { + estbl2 += "<td>" + priorname[estmatlabdata.param_vals[4]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.param_vals[6] + "</td>"; + } + estbl2 += "<td></td></tr>"; + y = y + 1; + } + } + + if ("var_exo" in estmatlabdata) { + estbl2 += '<tr><th id="par" colspan="8" scope="colgroup">Standard deviation of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mean.shocks_std) { + estbl2 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl2 += "<td>" + x + "</td>"; + // estbl2+="<td>"+estmatlabdata.exo_names[y]+"</td>"; + if (Array.isArray(estmatlabdata.var_exo[0])) { + estbl2 += "<td>" + estmatlabdata.var_exo[y][5] + "</td>"; + } else { + estbl2 += "<td>" + estmatlabdata.var_exo[5] + "</td>"; + } + + estbl2 += "<td>" + estmatlabdata.posterior_mean.shocks_std[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdinf.shocks_std[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdsup.shocks_std[x] + "</td>"; + + if (Array.isArray(estmatlabdata.var_exo[0])) { + estbl2 += "<td>" + priorname[estmatlabdata.var_exo[y][4]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.var_exo[y][6] + "</td>"; + } else { + estbl2 += "<td>" + priorname[estmatlabdata.var_exo[4]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.var_exo[6] + "</td>"; + } + estbl2 += "<td></td></tr>"; + y = y + 1; + } + } + + if ("corrx" in estmatlabdata) { + estbl2 += '<tr><th id="par" colspan="8" scope="colgroup">Correlation of shocks</th></tr>'; + y = 0; + for (x in estmatlabdata.posterior_mean.shocks_corr) { + estbl2 += '<tr><th scope="row">' + (y + 1) + '</th>'; + estbl2 += "<td>" + x + "</td>"; + // estbl2+="<td>"+estmatlabdata.exo_names[y]+"</td>"; + if (Array.isArray(estmatlabdata.corrx[0])) { + estbl2 += "<td>" + estmatlabdata.corrx[y][6] + "</td>"; + } else { + estbl2 += "<td>" + estmatlabdata.corrx[6] + "</td>"; + } + + estbl2 += "<td>" + estmatlabdata.posterior_mean.shocks_corr[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdinf.shocks_corr[x] + "</td>"; + estbl2 += "<td>" + estmatlabdata.posterior_hpdsup.shocks_corr[x] + "</td>"; + + if (Array.isArray(estmatlabdata.corrx[0])) { + estbl2 += "<td>" + priorname[estmatlabdata.corrx[y][5]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.corrx[y][7] + "</td>"; + } else { + estbl2 += "<td>" + priorname[estmatlabdata.corrx[5]] + "</td>"; + estbl2 += "<td>" + estmatlabdata.corrx[7] + "</td>"; + } + estbl2 += "<td></td></tr>"; + y = y + 1; + } + } + + estbl2 += "</tbody></table></section>"; + + + var plotdropdown = ` + <section> + <h2>Plots</h2> + <div class="btn-group" role="group" aria-label="..."> + <div class="btn-group" role="group"> + <button id="plotbtn" class="btn btn-primary btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Select graph <span class="caret"></span><span class="sr-only">Toggle Dropdown</span> + </button> + <ul class="dropdown-menu" aria-labelledby="plotbtn"> + <li class="dropdown-header">Priors:</li>`; + + //plotting priors + y = 0; + if ("parameters" in estmatlabdata.prior_density) { + for (x in estmatlabdata.prior_density.parameters) { + plotdropdown += '<li onclick="estplotpriors("' + x + '",0)"><a href="#stophere">' + x + '</a></li>'; + if (y == 0) { + var firstname = x; + var firsttype = 0; + y = 1; + } + } + } + + if ("shocks_std" in estmatlabdata.prior_density) { + for (x in estmatlabdata.prior_density.shocks_std) { + plotdropdown += '<li onclick="estplotpriors("' + x + '",1)"><a href="#stophere">' + x + '</a></li>'; + if (y == 0) { + var firstname = x; + var firsttype = 1; + y = 1; + } + } + } + + if ("shocks_corr" in estmatlabdata.prior_density) { + for (x in estmatlabdata.prior_density.shocks_corr) { + plotdropdown += '<li onclick="estplotpriors("' + x + '",2)"><a href="#stophere">' + x + '</a></li>'; + } + } + + //plotting priors+posteriors + plotdropdown += '<li class="dropdown-header">Priors and posteriors:</li>'; + + if ("parameters" in estmatlabdata.posterior_density) { + for (x in estmatlabdata.posterior_density.parameters) { + plotdropdown += '<li onclick="estplotposteriors("' + x + '",0)"><a href="#stophere">' + x + '</a></li>'; + } + } + + if ("shocks_std" in estmatlabdata.posterior_density) { + for (x in estmatlabdata.posterior_density.shocks_std) { + plotdropdown += '<li onclick="estplotposteriors("' + x + '",1)"><a href="#stophere">' + x + '</a></li>'; + } + } + + if ("shocks_corr" in estmatlabdata.posterior_density) { + for (x in estmatlabdata.posterior_density.shocks_corr) { + plotdropdown += '<li onclick="estplotposteriors("' + x + '",2)"><a href="#stophere">' + x + '</a></li>'; + } + } + + plotdropdown += '<li class="dropdown-header">Smoothed shocks:</li>'; + + if ("SmoothedShocks" in estmatlabdata) { + for (x in estmatlabdata.SmoothedShocks) { + plotdropdown += '<li onclick="estplotsmoothedshocks("' + x + '")"><a href="#stophere">' + x + '</a></li>'; + } + } + + plotdropdown += '<li class="dropdown-header">Historical and smoothed variables:</li>'; + + if ("SmoothedObs" in estmatlabdata) { + for (x in estmatlabdata.SmoothedObs) { + plotdropdown += '<li onclick="estplotsmoothedvars("' + x + '")"><a href="#stophere">' + x + '</a></li>'; + } + } + + + + + plotdropdown += '</ul></div>'; + plotdropdown += ` + <div class="btn-group" role="group"> + <button id="exportbtn" class="btn btn-primary btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Export data <span class="caret"></span><span class="sr-only">Toggle Dropdown</span> + </button> + <ul class="dropdown-menu" aria-labelledby="exportbtn"> + <li class="dropdown-header">Select file type:</li> + <li onclick="exportfile("json")"><a href="#stophere">Export to JSON</a></li> + <li onclick="exportfile("csv")"><a href="#stophere">Export to CSV</a></li> + </ul> + </div>`; + + plotdropdown += ` + </div> + </section> + `; + document.getElementById("plotbtn").innerHTML = plotdropdown; + + + estplotpriors(firstname, firsttype); + + } + + + + + + + $("#inner").empty(); + document.getElementById("outputtable").innerHTML = estbl1; + + if (estmatlabdata.estimtypeflag == 1) { + document.getElementById("outputtable2").innerHTML = estbl2; + } + + + + }); +}); + +function estplotpriors(plotvar, priortype) { + + if (priortype == 0) { + xvar = []; + yvar = []; + if ("parameters" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.parameters[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.parameters[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.parameters[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var data = [trace1]; + var layout = { + title: plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + } + }; + } + } + + if (priortype == 1) { + xvar = []; + yvar = []; + if ("shocks_std" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.shocks_std[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.shocks_std[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.shocks_std[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var data = [trace1]; + var layout = { + title: 'SE_' + plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + } + }; + } + } + + if (priortype == 2) { + xvar = []; + yvar = []; + if ("shocks_corr" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.shocks_corr[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.shocks_corr[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.shocks_corr[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var data = [trace1]; + var layout = { + title: 'CC_' + plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + } + }; + } + } + + Plotly.newPlot('plotbox', data, layout); + +} + +function estplotposteriors(plotvar, priortype) { + + if (priortype == 0) { + xvar = []; + yvar = []; + x2var = []; + y2var = []; + if ("parameters" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.parameters[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.parameters[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.parameters[plotvar][i][1]); + } + for (i = 0; i < estmatlabdata.posterior_density.parameters[plotvar].length; i++) { + x2var.push(estmatlabdata.posterior_density.parameters[plotvar][i][0]); + y2var.push(estmatlabdata.posterior_density.parameters[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + name: 'Prior', + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var trace2 = { + x: x2var, + y: y2var, + name: 'Posterior', + line: { + color: 'rgb(0, 0, 0)', + width: 3 + } + }; + + + var data = [trace1, trace2]; + var layout = { + title: plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + }, + shapes: [{ + type: 'line', + x0: estmatlabdata.posterior_mode.parameters[plotvar], + y0: 0, + x1: estmatlabdata.posterior_mode.parameters[plotvar], + y1: Math.max(...trace2.y), + line: { + color: 'rgb(25, 253, 2)', + width: 2, + dash: 'dot' + } + }] + }; + } + } + + if (priortype == 1) { + xvar = []; + yvar = []; + x2var = []; + y2var = []; + if ("shocks_std" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.shocks_std[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.shocks_std[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.shocks_std[plotvar][i][1]); + } + for (i = 0; i < estmatlabdata.posterior_density.shocks_std[plotvar].length; i++) { + x2var.push(estmatlabdata.posterior_density.shocks_std[plotvar][i][0]); + y2var.push(estmatlabdata.posterior_density.shocks_std[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + name: 'Prior', + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var trace2 = { + x: x2var, + y: y2var, + name: 'Posterior', + line: { + color: 'rgb(0, 0, 0)', + width: 3 + } + }; + + var data = [trace1, trace2]; + var layout = { + title: 'SE_' + plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + }, + shapes: [{ + type: 'line', + x0: estmatlabdata.posterior_mode.shocks_std[plotvar], + y0: 0, + x1: estmatlabdata.posterior_mode.shocks_std[plotvar], + y1: Math.max(...trace2.y), + line: { + color: 'rgb(25, 253, 2)', + width: 2, + dash: 'dot' + } + }] + }; + } + } + + if (priortype == 2) { + xvar = []; + yvar = []; + x2var = []; + y2var = []; + if ("shocks_corr" in estmatlabdata.prior_density) { + for (i = 0; i < estmatlabdata.prior_density.shocks_corr[plotvar].length; i++) { + xvar.push(estmatlabdata.prior_density.shocks_corr[plotvar][i][0]); + yvar.push(estmatlabdata.prior_density.shocks_corr[plotvar][i][1]); + } + for (i = 0; i < estmatlabdata.posterior_density.shocks_corr[plotvar].length; i++) { + x2var.push(estmatlabdata.posterior_density.shocks_corr[plotvar][i][0]); + y2var.push(estmatlabdata.posterior_density.shocks_corr[plotvar][i][1]); + } + var trace1 = { + x: xvar, + y: yvar, + name: 'Prior', + line: { + color: 'rgb(182, 179, 179)', + width: 3 + } + }; + var trace2 = { + x: x2var, + y: y2var, + name: 'Posterior', + line: { + color: 'rgb(0, 0, 0)', + width: 3 + } + }; + + var data = [trace1, trace2]; + var layout = { + title: 'CC_' + plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: "Density" + }, + shapes: [{ + type: 'line', + x0: estmatlabdata.posterior_mode.shocks_corr[plotvar], + y0: 0, + x1: estmatlabdata.posterior_mode.shocks_corr[plotvar], + y1: Math.max(...trace2.y), + line: { + color: 'rgb(25, 253, 2)', + width: 2, + dash: 'dot' + } + }] + }; + } + } + + Plotly.newPlot('plotbox', data, layout); + +} + +function estplotsmoothedshocks(plotvar) { + + yvar = []; + for (i = 0; i < estmatlabdata.SmoothedShocks[plotvar].length; i++) { + yvar.push(estmatlabdata.SmoothedShocks[plotvar][i][0]); + } + + var trace1 = { + y: yvar, + line: { + color: 'rgb(0, 0, 0)', + width: 1 + } + }; + + var data = [trace1]; + var layout = { + title: plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: '' + }, + shapes: [{ + type: 'line', + x0: 0, + y0: 0, + x1: (estmatlabdata.SmoothedShocks[plotvar].length - 1), + y1: 0, + line: { + color: 'rgb(253, 63, 2)', + width: 2, + dash: 'solid' + } + }] + }; + Plotly.newPlot('plotbox', data, layout); + +} + + +function estplotsmoothedvars(plotvar) { + + yvar = []; + y2var = []; + + for (i = 0; i < estmatlabdata.obs_data[plotvar].length; i++) { + yvar.push(estmatlabdata.obs_data[plotvar][i][0]); + } + for (i = 0; i < estmatlabdata.SmoothedObs[plotvar].length; i++) { + y2var.push(estmatlabdata.SmoothedObs[plotvar][i][0]); + } + var trace1 = { + y: yvar, + name: 'Historical', + line: { + color: 'rgb(0, 0, 0)', + width: 1 + } + }; + var trace2 = { + y: y2var, + name: 'Smoothed', + line: { + color: 'rgb(253, 63, 2)', + dash: 'longdash', + width: 1 + } + }; + + var data = [trace1, trace2]; + var layout = { + title: plotvar, + xaxis: { + title: '' + }, + yaxis: { + title: '' + } + }; + + Plotly.newPlot('plotbox', data, layout); + +} \ No newline at end of file diff --git a/public/static/js/perfectforesight.js b/public/static/js/perfectforesight.js index 3e5ad80bfc99420bb07e6ed497fd835c58e93c8f..39ec0ae635c757ea7f01d5924875007d0a3cf277 100644 --- a/public/static/js/perfectforesight.js +++ b/public/static/js/perfectforesight.js @@ -41,11 +41,13 @@ $('#setperfect').click(function () { } else if (resp.status == 100) { console.log("100") showconsolealert(resp.message, 1); + scrolltextarea(); console.log('console error'); return false; } showconsolealert(resp.message, 1); + scrolltextarea(); var currentdate = new Date(); $('#classlist-form-messages').text('Last saved at: ' + currentdate); @@ -255,6 +257,12 @@ $('#runperfect').click(function() { if (numshocks[iter] == 1) { // if numshocks identifies a valid row in the table, we start further checks countshocks = countshocks + 1; + + //we find the true row number of the current checked line in the table + var perftablerow = $('#shockname' + iter.toString()).closest('tr'); + var perftablerowindex = perftablerow.index()+1; + + shockvaluearray = []; // we fetch periods and values and anticipation dates @@ -299,11 +307,11 @@ $('#runperfect').click(function() { shockanticipdate = 0; } else { if (!(Number.isInteger(Number(shockanticipdate)))) { - popthis('Shocks error.', 'The shock expectation date on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock expectation date on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockanticipdate) < 1) { - popthis('Shocks error.', 'The shock expectation date on row ' + countshocks + ' can not be lower than 1.'); + popthis('Shocks error.', 'The shock expectation date on row ' + perftablerowindex + ' can not be lower than 1.'); return (0); } delayexist = 1; @@ -320,15 +328,15 @@ $('#runperfect').click(function() { transitoryflag[shockindex] = 1; // we validate the starting period if (shockstart == null || shockstart == "") { - popthis('Shocks error.', 'You did not specify any starting period for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any starting period for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(Number.isInteger(Number(shockstart)))) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockstart) < 1) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' can not be lower than 1.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' can not be lower than 1.'); return (0); } shockstart = parseInt(shockstart, 10); @@ -336,7 +344,7 @@ $('#runperfect').click(function() { // we validate the shock value if (shockvalue == null || shockvalue == "") { - popthis('Shocks error.', 'You did not specify any value for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any value for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(IsNumeric(shockvalue))) { @@ -351,19 +359,19 @@ $('#runperfect').click(function() { if (columnsplitlength > 1) { // if we are sure there should be at least 2 periods, we check the end period if (shockend == null || shockend == "") { - popthis('Shocks error.', 'You did not specify any ending period for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any ending period for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(Number.isInteger(Number(shockend)))) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockend) > Number(simperiods)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' can not be larger than the number of simulation periods.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' can not be larger than the number of simulation periods.'); return (0); } if (Number(shockend) < Number(shockstart)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' cannot be before the shock starting period.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' cannot be before the shock starting period.'); return (0); } shockend = parseInt(shockend, 10); @@ -371,14 +379,14 @@ $('#runperfect').click(function() { // we verify if the number of periods and values match if (!(columnsplitlength == (shockend - shockstart + 1))) { - popthis('Shocks error.', 'The number of periods and the number of shock values does not match on row ' + countshocks + '.'); + popthis('Shocks error.', 'The number of periods and the number of shock values does not match on row ' + perftablerowindex + '.'); return (0); } // we define a values array for (i = 0; i < columnsplitlength; i++) { if (!(IsNumeric(columnsplit[i]))) { - popthis('Shocks error.', 'At least one shock vector value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'At least one shock vector value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockvaluearray.push(Number(columnsplit[i])); @@ -386,14 +394,14 @@ $('#runperfect').click(function() { } else { // this is a single shock with just a start period if (!(IsNumeric(columnsplit[0]))) { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockvaluearray.push(Number(columnsplit[0])); shockend = parseInt(shockstart, 10); } } else { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } } else { @@ -402,7 +410,7 @@ $('#runperfect').click(function() { if (shockend == null || shockend == "") { // this is a single shock with just a start period if (!(IsNumeric(shockvalue))) { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockend = parseInt(shockstart, 10); @@ -410,11 +418,11 @@ $('#runperfect').click(function() { } else { // this is a single value but with a range, we repeat the value over the range if (!(Number.isInteger(Number(shockend)))) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockend) > Number(simperiods)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' can not be larger than the number of simulation periods.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' can not be larger than the number of simulation periods.'); return (0); } shockend = parseInt(shockend, 10); @@ -446,11 +454,11 @@ $('#runperfect').click(function() { shockstart = 1; } else { if (!(Number.isInteger(Number(shockstart)))) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockstart) < 1) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' can not be lower than 1.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' can not be lower than 1.'); return (0); } shockstart = parseInt(shockstart, 10); @@ -461,7 +469,7 @@ $('#runperfect').click(function() { shockanticipdate = 0; } else { if (Number(shockanticipdate) > Number(shockstart)) { - popthis('Shocks error.', 'The shock expectation date on row ' + countshocks + ' can not be after the start date.'); + popthis('Shocks error.', 'The shock expectation date on row ' + perftablerowindex + ' can not be after the start date.'); return (0); } // if ((nonanticipatedshockexist==1)&&(delayexist==1)){popthis('Shocks error.','Please either choose a non anticipated shock or a delayed anticipation shock with anticipation date for shock on row '+countshocks+', but not both.');return(0);} @@ -488,11 +496,11 @@ $('#runperfect').click(function() { shockstart = 1; } else { if (!(Number.isInteger(Number(shockstart)))) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockstart) < 1) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' can not be lower than 1.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' can not be lower than 1.'); return (0); } shockstart = parseInt(shockstart, 10); @@ -500,11 +508,11 @@ $('#runperfect').click(function() { // we validate the shock value if (shockvalue == null || shockvalue == "") { - popthis('Shocks error.', 'You did not specify any value for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any value for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(IsNumeric(shockvalue))) { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not numeric. A permanent shock can only have a single numeric value, no comma or semi-colon is authorized.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not numeric. A permanent shock can only have a single numeric value, no comma or semi-colon is authorized.'); return (0); } else { // we collect the value @@ -529,15 +537,15 @@ $('#runperfect').click(function() { // we validate the starting period if (shockstart == null || shockstart == "") { - popthis('Shocks error.', 'You did not specify any starting period for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any starting period for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(Number.isInteger(Number(shockstart)))) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockstart) < 1) { - popthis('Shocks error.', 'The shock starting period on row ' + countshocks + ' can not be lower than 1.'); + popthis('Shocks error.', 'The shock starting period on row ' + perftablerowindex + ' can not be lower than 1.'); return (0); } shockstart = parseInt(shockstart, 10); @@ -548,14 +556,14 @@ $('#runperfect').click(function() { shockanticipdate = 0; } else { if (Number(shockanticipdate) > Number(shockstart)) { - popthis('Shocks error.', 'The shock expectation date on row ' + countshocks + ' can not be after the start date.'); + popthis('Shocks error.', 'The shock expectation date on row ' + perftablerowindex + ' can not be after the start date.'); return (0); } } // we validate the shock value if (shockvalue == null || shockvalue == "") { - popthis('Shocks error.', 'You did not specify any value for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any value for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(IsNumeric(shockvalue))) { @@ -570,19 +578,19 @@ $('#runperfect').click(function() { if (columnsplitlength > 1) { // if we are sure there should be at least 2 periods, we check the end period if (shockend == null || shockend == "") { - popthis('Shocks error.', 'You did not specify any ending period for shock on row ' + countshocks + '.'); + popthis('Shocks error.', 'You did not specify any ending period for shock on row ' + perftablerowindex + '.'); return (0); } else { if (!(Number.isInteger(Number(shockend)))) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockend) > Number(simperiods)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' can not be larger than the number of simulation periods.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' can not be larger than the number of simulation periods.'); return (0); } if (Number(shockend) < Number(shockstart)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' can before the shock starting period.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' can before the shock starting period.'); return (0); } shockend = parseInt(shockend, 10); @@ -590,14 +598,14 @@ $('#runperfect').click(function() { // we verify if the number of periods and values match if (!(columnsplitlength == (shockend - shockstart + 1))) { - popthis('Shocks error.', 'The number of periods and the number of shock values does not match on row ' + countshocks + '.'); + popthis('Shocks error.', 'The number of periods and the number of shock values does not match on row ' + perftablerowindex + '.'); return (0); } // we define a values array for (i = 0; i < columnsplitlength; i++) { if (!(IsNumeric(columnsplit[i]))) { - popthis('Shocks error.', 'At least one shock vector value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'At least one shock vector value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockvaluearray.push(Number(columnsplit[i])); @@ -605,14 +613,14 @@ $('#runperfect').click(function() { } else { // this is a single shock with just a start period if (!(IsNumeric(columnsplit[0]))) { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockvaluearray.push(Number(columnsplit[0])); shockend = parseInt(shockstart, 10); } } else { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } } else { @@ -621,7 +629,7 @@ $('#runperfect').click(function() { if (shockend == null || shockend == "") { // this is a single shock with just a start period if (!(IsNumeric(shockvalue))) { - popthis('Shocks error.', 'The shock value on row ' + countshocks + ' is not a number.'); + popthis('Shocks error.', 'The shock value on row ' + perftablerowindex + ' is not a number.'); return (0); } shockend = parseInt(shockstart, 10); @@ -629,11 +637,11 @@ $('#runperfect').click(function() { } else { // this is a single value but with a range, we repeat the value over the range if (!(Number.isInteger(Number(shockend)))) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' is not an integer number.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' is not an integer number.'); return (0); } if (Number(shockend) > Number(simperiods)) { - popthis('Shocks error.', 'The shock ending period on row ' + countshocks + ' can not be larger than the number of simulation periods.'); + popthis('Shocks error.', 'The shock ending period on row ' + perftablerowindex + ' can not be larger than the number of simulation periods.'); return (0); } shockend = parseInt(shockend, 10); @@ -735,6 +743,7 @@ $('#runperfect').click(function() { var perforvaldata = JSON.stringify(perforval); $("#outputtable").empty(); + $("#outputtable2").empty(); $("#plotbtn").empty(); $("#plotbox").empty(); $('#perforModal').modal('hide'); @@ -778,6 +787,7 @@ $('#runperfect').click(function() { } else if (resp.status == 100) { console.log("100") showconsolealert(resp.message, 1); + scrolltextarea(); console.log('console error'); return false; } @@ -802,8 +812,9 @@ $('#runperfect').click(function() { $(function () { socket.on('perfectsimfinish', function(msg){ // $('#messages').append($('<li>').text(msg)); - console.log(msg); + // console.log(msg); + scrolltextarea(); matlabdata = msg; var endovarname; diff --git a/public/static/js/stochastic.js b/public/static/js/stochastic.js index aa8d9ea03e15d75d298d2d85077b095758d66b9c..fe56e7dbf8edca387c719baf9230a09cb8df0682 100644 --- a/public/static/js/stochastic.js +++ b/public/static/js/stochastic.js @@ -1,21 +1,3 @@ -// const ipc = require('electron').ipcRenderer; -// const path = require('path'); -// var fs = require('fs'); -// const savetodb = require('./appModules').savetodb; -// const updatedbSS = require('./appModules').updatedbSS; -// const basedir = require('./appModules').basedir; -// const cl = require('./appModules').cl; -// const popthis = require('./appModules').popthis; -// const createnewfile = require('./appModules').createnewfile; -// const removeoldfile = require('./appModules').removeoldfile; -// const loadjsonfile = require('./appModules').loadjsonfile; -// const checkfileexist = require('./appModules').checkfileexist -// const preprocess = require('./appModules').preprocess; -// const showconsolealert = require('./appModules').showconsolealert; -// const IsNumeric = require('./appModules').IsNumeric; -// const preparejsonfiles = require('./appModules').preparejsonfiles; -// const remote = require('electron').remote; -// const app = remote.app; var stomatlabdata; var stonumshocks = []; @@ -63,11 +45,13 @@ $('#setstochastic').click(function () { } else if (resp.status == 100) { console.log("100") showconsolealert(resp.message, 1); + scrolltextarea(); console.log('console error'); return false; } showconsolealert(resp.message, 1); + scrolltextarea(); var currentdate = new Date(); $('#classlist-form-messages').text('Last saved at: ' + currentdate); @@ -164,7 +148,7 @@ function disableassociated(shockindex) { if (selectedvalue < 3) { $("#stoassoshockname" + shockindex).attr('disabled', 'disabled'); } else { - $("#stoassoshockname" + shockindex).removeAttr('disabled');; + $("#stoassoshockname" + shockindex).removeAttr('disabled'); } //cl(selectedvalue); } @@ -279,6 +263,10 @@ $('#runstochastic').click(async function () { // if stonumshocks identifies a valid row in the table, we start further checks countshocks = countshocks + 1; + //we find the true row number of the current checked line in the table + var stotablerow = $('#stoshockname' + stoiter.toString()).closest('tr'); + var stotablerowindex = stotablerow.index()+1; + // We fetch shock infos shockindex = $('#stoshockname' + stoiter.toString()).val(); shockattributevalue = $("#stoshockattribute" + stoiter.toString()).val(); @@ -289,7 +277,7 @@ $('#runstochastic').click(async function () { if (shockattributevalue > 2) { //covariance or correation was selected assoshockindex = $('#stoassoshockname' + stoiter.toString()).val(); if (shockindex == assoshockindex) { - popthis('Shocks error.', 'On row ' + countshocks + ', the covariance/correlation should be taken for separate shocks.'); + popthis('Shocks error.', 'On row ' + stotablerowindex + ', the covariance/correlation should be taken for separate shocks.'); return (0); } // we verify if covariance/correlation has already been specified for any two same shocks @@ -297,14 +285,14 @@ $('#runstochastic').click(async function () { if (shockspairs.indexOf(shockindex + '-' + assoshockindex) == -1) { shockspairs.push(shockindex + '-' + assoshockindex); } else { - popthis('Shocks error.', 'On row ' + countshocks + ', this covariance/correlation has already been specified between these shocks.'); + popthis('Shocks error.', 'On row ' + stotablerowindex + ', this covariance/correlation has already been specified between these shocks.'); return (0); } } else { if (shockspairs.indexOf(assoshockindex + '-' + shockindex) == -1) { shockspairs.push(assoshockindex + '-' + shockindex); } else { - popthis('Shocks error.', 'On row ' + countshocks + ', this covariance/correlation has already been specified between these shocks.'); + popthis('Shocks error.', 'On row ' + stotablerowindex + ', this covariance/correlation has already been specified between these shocks.'); return (0); } } @@ -339,16 +327,17 @@ $('#runstochastic').click(async function () { stoyiter = stoyiter + 1; } if (stoyflag < 2) { - popthis('Shocks error.', 'On row ' + countshocks + ', the covariance relation requires that the variances (or std deviation) of both related shocks are declared. Please declare a value for both of them.'); + popthis('Shocks error.', 'On row ' + stotablerowindex + ', the covariance relation requires that the variances (or std deviation) of both related shocks are declared. Please declare a value for both of them.'); return (0); } } + } else { //we check if the same shock already has a std or variance flag if (attributeflag[shockindex] > 0) { - popthis('Shocks error.', 'On row ' + countshocks + ', You have already specified a variance or standard deviation attribute for this shock. Please keep only one such attribute per shock.'); + popthis('Shocks error.', 'On row ' + stotablerowindex + ', You have already specified a variance or standard deviation attribute for this shock. Please keep only one such attribute per shock.'); return (0); } else { attributeflag[shockindex] = shockattributevalue; @@ -405,6 +394,7 @@ $('#runstochastic').click(async function () { var stosimvaldata = JSON.stringify(stosimval); $("#outputtable").empty(); + $("#outputtable2").empty(); $("#plotbtn").empty(); $("#plotbox").empty(); $('#stosimModal').modal('hide'); @@ -432,6 +422,7 @@ $('#runstochastic').click(async function () { } else if (resp.status == 100) { console.log("100") showconsolealert(resp.message, 1); + scrolltextarea(); console.log('console error'); return false; } @@ -460,7 +451,9 @@ $('#runstochastic').click(async function () { $(function () { socket.on('stochasticsimfinish', function(msg){ // $('#messages').append($('<li>').text(msg)); - console.log(msg); + // console.log(msg); + + scrolltextarea(); stomatlabdata=msg; diff --git a/routes/index.js b/routes/index.js index f0372378101182629b3e89cd69e10897db99c4db..0baa608e9634300678e8e86b88ac9c9c583cc671 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,16 +1,19 @@ var express = require('express'); var router = express.Router(); var bodyParser = require('body-parser'); +const formidableMiddleware = require('express-formidable'); var csrf = require('csurf'); var cookieParser = require('cookie-parser'); const getmodelfromdb = require('../appModules').getmodelfromdb; const savetodb = require('../appModules').savetodb; const newmodelindb = require('../appModules').newmodelindb; +const movenewdatafile = require('../appModules').movenewdatafile; const setpreprocess = require('../middleware/runprocesses').setpreprocess; const setpreprocessmore = require('../middleware/runprocesses').setpreprocessmore; const runstochasticnode = require('../middleware/runprocesses').runstochasticnode; const runperfectnode = require('../middleware/runprocesses').runperfectnode; +const runestimationnode = require('../middleware/runprocesses').runestimationnode; // const ipc = require('node-ipc'); const csrfProtection = csrf({ @@ -73,6 +76,38 @@ router.get('/', function (req, res, next) { }); +//body-parser does not handle file uploads +//express-formidable does handle both files and text but to avoid changing the whole code there is a route just for files +router.post('/fileroute', formidableMiddleware(), async (req, res) => { + const file = req.files.file; + const filepath = req.files.file.path; + console.log('file info: ' + file+' '+filepath); + + const fields = req.fields; + console.log('fields = ' + JSON.stringify(fields)); + + console.log(fields.filename) + + movenewdatafile(fields.filename, fields.filetype, filepath) + .then(function (data) { + // console.log(data); + // res.json(data); + res.json({ + 'status': 1 + }); + }) + .catch(function (e) { + console.log(e.toString()); + res.json({ + 'status': 200, + 'message': e.toString() + }); + }); + + +}); + + router.post('/', function (req, res) { console.log(req.body.accesstype); @@ -126,40 +161,45 @@ router.post('/', function (req, res) { res.json(data); }) .catch(function (e) { - res.json(data); + res.json(e); }); break; case 'setstochastic': - setpreprocessmore(req.body) .then(function (data) { console.log(data); res.json(data); }) .catch(function (e) { - res.json(data); + res.json(e); }); - - - break; case 'setperfect': - console.log('Got setperfect'); - setpreprocessmore(req.body) .then(function (data) { console.log(data); res.json(data); }) .catch(function (e) { - res.json(data); + res.json(e); }); + break; + + case 'setestimation': + setpreprocessmore(req.body) + .then(function (data) { + console.log(data); + res.json(data); + }) + .catch(function (e) { + res.json(e); + }); break; default: @@ -179,6 +219,22 @@ router.put('/', function (req, res) { switch (req.body.accesstype) { + case 'runestimation': + + console.log('runestimation got it'); + + + runestimationnode(req.body) + .then(function (data) { + console.log(data); + res.json(data); + }) + .catch(function (e) { + res.json(data); + }); + + break; + case 'runstochastic': runstochasticnode(req.body) diff --git a/views/index.handlebars b/views/index.handlebars index 025495a7786ed2077dc4e1bd2f0792a43a8b94a8..72c28a12baac485c8a80cb5c832c58962db5af9f 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -76,12 +76,13 @@ </div> <div class="btn-group"> <button id="runsim" type="button" title="Simulation" class="btn btn-success btn-lg dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Simulation <span class="caret"></span> + <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Run... <span class="caret"></span> </button> <ul class="dropdown-menu"> <!-- <li data-toggle="modal" data-target="#perforModal"><a href="#">Perfect foresight</a></li> --> - <li id="setperfect"><a href="#">Perfect foresight</a></li> - <li id="setstochastic"><a href="#">Stochastic</a></li> + <li id="setperfect"><a href="#">Perfect foresight simulation</a></li> + <li id="setstochastic"><a href="#">Stochastic simulation</a></li> + <li id="setestimation"><a href="#">Estimation</a></li> <!-- <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> @@ -118,6 +119,7 @@ </div> <div class="outputdata"> <div id="outputtable"></div> + <div id="outputtable2"></div> <div id="plotbtn"></div> <div id="plotbox" style="height:500px;"></div> <div id="graphend"><a href="#stophere"></a></div> @@ -141,9 +143,34 @@ <!-- Modals --> + +<!-- MH acceptance ratio modal --> +<div class="modal fade" id="MHmodal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <!-- Modal Header --> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal"> + <span aria-hidden="true">×</span> + <span class="sr-only">Close</span> + </button> + <h4 class="modal-title" id="myModalLabel"> + RW Metropolis-Hastings (<span id="MHloop">1</span>/<span id="MHloopover">2</span>) Current acceptance ratio <span id="MHCAR">1</span> + </h4> + </div> + + <div class="modal-body"> + <div id="myProgress"> + <div id="myBar">0%</div> + </div> + </div> + + </div> + </div> +</div> + <!-- perfect foresight modal Start --> -<div class="modal fade" id="perforModal" tabindex="-1" role="dialog" - aria-labelledby="myModalLabel" aria-hidden="true"> +<div class="modal fade" id="perforModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <!-- Modal Header --> @@ -324,6 +351,156 @@ </div> <!-- stochastic sim modal End--> + + +<!-- estimation modal Start --> +<div class="modal fade" id="estimModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> + <div class="modal-dialog modal-lg"> + <div class="modal-content"> + <!-- Modal Header --> + <div class="modal-header"> + <button type="button" class="close" + data-dismiss="modal"> + <span aria-hidden="true">×</span> + <span class="sr-only">Close</span> + </button> + <h4 class="modal-title" id="myModalLabel"> + Estimation + </h4> + </div> + + <!-- Modal Body --> + <div class="modal-body"> + + <ul class="nav nav-tabs tabs-up" id="estimmodaltabs"> + <li class="active"><a data-toggle="tab" href="#estimsetuptable">Setup</a></li> + <li><a data-toggle="tab" href="#estimparams">Parameters</a></li> + <li><a data-toggle="tab" href="#estimoptions">Options</a></li> + </ul> + <br> + <div class="tab-content"> + + <div id="estimsetuptable" class="tab-pane fade in active"> + <h4>Data <div class="tooltipcsshead"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcsshead">A .m file, a .mat file, a .csv file, or a .xls/.xlsx file.</span></div></h4> + <table class="table small"> + <tbody> + <tr> + <td>Please choose a data file:</td> + <td><input type="file" class="form-control-file no-border" id="estfile" accept=".m,.csv,.xls,.xlsx,.mat"></td> + <input id="estmodel_endonum" name="estmodel_endonum" value="" type="hidden"> + <input id="estmodel_exonum" name="estmodel_exonum" value="" type="hidden"> + <input id="estmodel_paramnum" name="estmodel_paramnum" value="" type="hidden"> + </tr> + </tbody> + </table> + + <h4>Observable variables <div class="tooltipcsshead"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcsshead">List of the name(s) of observed endogenous variables for the estimation procedure. These variables must be available in the data file.</span></div></h4> + <button id="estaddobs" type="button" title="addobs" class="btn btn-success btn-sm">Add observables</button> + <table id="estobstable" class="table table-striped small"> + <thead> + <tr> + <!-- <th>#</th> --> + <th>Variable</th> + <th>X</th> + </tr> + </thead> + <tbody> + </tbody> + </table> + <div id="estinittable"></div> + </div> + + + <div id="estimparams" class="tab-pane fade in"> + <h4>Estimated parameters <div class="tooltipcsshead"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcsshead">List of all parameters to be estimated and specification of bounds and priors as necessary.</span></div></h4> + <button id="estaddparam" type="button" title="addparam" class="btn btn-success btn-sm">Add parameter</button> + <table id="estpartable" class="table table-striped small"> + <thead> + <tr> + <!-- <th>#</th> --> + <th>Parameter/Variable</th> + <th>Value</th> + <th>Lower bound</th> + <th>Upper bound</th> + <th>Prior density</th> + <th>Prior Mean</th> + <th>Prior StdErr</th> + <th>Prior 3rd param</th> + <th>Prior 4th param</th> + <th>Scale</th> + <th>Correleted var</th> + <th>X</th> + </tr> + </thead> + <tbody> + </tbody> + </table> + + </div> + + <div id="estimoptions" class="tab-pane fade in"> + <h4>Options</h4> + <table class="table table-striped small"> + <thead> + <tr> + <th>#</th> + <th>Option</th> + <th>Value</th> + <th>Info</th> + </tr> + </thead> + <tbody> + <tr> + <th scope="row">1</th> + <td>Number of observations (nobs)</td> + <td><input class="form-control no-border input-sm" name="estimopt_nobs" id="estimopt_nobs" placeholder="All" type="text" value=""></td> + <td><div class="tooltipcss"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcss">The number of observations following first_obs to be used.<br> Default: all observations in the file after first_obs.</span></div></td> + </tr> + <tr> + <th scope="row">2</th> + <td>Number of replications (mh_replic)</td> + <td><input class="form-control no-border input-sm" name="estimopt_mh_replic" id="estimopt_mh_replic" placeholder="20000" type="text" value=""></td> + <td><div class="tooltipcss"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcss">Number of replications for Metropolis-Hastings algorithm. For the time being, mh_replic should be larger than 1200.<br> Default: 20000.</span></div></td> + </tr> + + <tr> + <th scope="row">3</th> + <td>Number of blocks (mh_nblocks)</td> + <td><input class="form-control no-border input-sm" name="estimopt_mh_nblocks" id="estimopt_mh_nblocks" placeholder="2" type="text" value=""></td> + <td><div class="tooltipcss"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcss">Number of parallel chains for Metropolis-Hastings algorithm.<br> Default: 2.</span></div></td> + </tr> + + <tr> + <th scope="row">4</th> + <td>Scale parameter (mh_jscale)</td> + <td><input class="form-control no-border input-sm" name="estimopt_mh_jscale" id="estimopt_mh_jscale" placeholder="0.2" type="text" value=""></td> + <td><div class="tooltipcss"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span><span class="tooltiptextcss">The scale parameter of the jumping distribution’s covariance matrix (Metropolis-Hastings or TaRB-algorithm). The default value is rarely satisfactory. This option must be tuned to obtain, ideally, an acceptance ratio of 25%-33%. Basically, the idea is to increase the variance of the jumping distribution if the acceptance ratio is too high, and decrease the same variance if the acceptance ratio is too low. In some situations it may help to consider parameter-specific values for this scale parameter. This can be done in the estimated_params- block.<br> Note that mode_compute=6 will tune the scale parameter to achieve an acceptance rate of AcceptanceRateTarget. The resulting scale parameter will be saved into a file named MODEL_FILENAME_mh_scale.mat. This file can be loaded in subsequent runs via the posterior_sampler_options-option scale_file. Both mode_compute=6 and scale_file will overwrite any value specified in estimated_params with the tuned value.<br> Default: 0.2.</span></div></td> + </tr> + + </tbody> + </table> + </div> + + + + </div> + </div> + + <!-- Modal Footer --> + <div class="modal-footer"> + <button type="button" class="btn btn-default" + data-dismiss="modal"> + Close + </button> + <button type="button" id="runestimation" class="btn btn-primary"> + Run estimation + </button> + </div> + </div> + </div> +</div> +<!-- estimation modal End--> + <!-- End Modals --> @@ -403,6 +580,7 @@ <script src="./static/js/editor.js"></script> <script src="./static/js/perfectforesight.js"></script> <script src="./static/js/stochastic.js"></script> + <script src="./static/js/estimation.js"></script> <script> createNewModel('{{dynaremodel.modelname}}', '{{dynaremodel.modelhash}}', '{{dynaremodel.modelname}}',`{{{dynaremodel.modelcode}}}`);