From 7c06b8e3ffb91f8ff06eac9881d959321b22ad0c Mon Sep 17 00:00:00 2001
From: Benoit Lavenier <benoit.lavenier@e-is.pro>
Date: Thu, 2 Jan 2020 18:28:53 +0100
Subject: [PATCH] [fix] Fix JSHint for plugins JS files [fix] In hooks script,
 make sure all JS files are processed

---
 gulpfile.js                                   | 37 +++++---
 hooks/after_prepare/040_useref.js             |  6 +-
 hooks/before_prepare/02_jshint.js             | 70 ++++++++-------
 package.json                                  |  6 +-
 www/js/api/app.js                             |  8 +-
 www/js/services/bma-services.js               |  4 +-
 www/js/services/tx-services.js                | 12 +--
 .../graph/js/services/data-services.js        | 86 ++++++++++---------
 .../map/js/controllers/network-controllers.js | 10 ++-
 .../map/js/services/registry-services.js      | 14 +--
 yarn.lock                                     | 84 ++++++++----------
 11 files changed, 178 insertions(+), 159 deletions(-)

diff --git a/gulpfile.js b/gulpfile.js
index b686b2f9..95e725f6 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -20,7 +20,7 @@ const gulp = require('gulp'),
   del = require('del'),
   useref = require('gulp-useref'),
   filter = require('gulp-filter'),
-  uglify = require('gulp-uglify'),
+  uglify = require('gulp-uglify-es').default,
   csso = require('gulp-csso'),
   replace = require('gulp-replace'),
   rev = require('gulp-rev'),
@@ -31,7 +31,6 @@ const gulp = require('gulp'),
   markdown = require('gulp-markdown'),
   sourcemaps = require('gulp-sourcemaps'),
   log = require('fancy-log'),
-  merge = require('merge2'),
   colors = require('ansi-colors');
 
 const paths = {
@@ -282,7 +281,7 @@ function webCopyFiles() {
   log(colors.green('Preparing dist/web files...'));
 
   var tmpPath = './dist/web/www';
-  return es.concat(
+  return es.merge(
     // Copy Js (and remove unused code)
     gulp.src('./www/js/**/*.js')
       .pipe(removeCode({"no-device": true}))
@@ -392,7 +391,21 @@ function webNgAnnotate() {
 
 function webPluginCopyFiles() {
   var tmpPath = './dist/web/www';
-  return es.concat(
+  return es.merge(
+    // Copy Js (and remove unused code)
+    gulp.src('./www/plugins/**/*.js')
+      .pipe(removeCode({"no-device": true}))
+      .pipe(jshint())
+      .pipe(gulp.dest(tmpPath + '/plugins')),
+
+    // Copy HTML templates (and remove unused code)
+    gulp.src('./www/plugins/**/*.html')
+      .pipe(removeCode({"no-device": true}))
+      .pipe(removeHtml('.hidden-no-device'))
+      .pipe(removeHtml('[remove-if][remove-if="no-device"]'))
+      .pipe(htmlmin())
+      .pipe(gulp.dest(tmpPath + '/plugins')),
+
     // Transform i18n into JS
     gulp.src(paths.ng_translate_plugin)
       .pipe(ngTranslate({standalone:true, module: 'cesium.plugins.translations'}))
@@ -406,7 +419,7 @@ function webPluginCopyFiles() {
 
 function webPluginNgTemplate() {
   var tmpPath = './dist/web/www';
-  return gulp.src(paths.templatecache_plugin)
+  return gulp.src(tmpPath + '/plugins/**/*.html')
     .pipe(templateCache({
       standalone:true,
       module:"cesium.plugins.templates",
@@ -417,7 +430,7 @@ function webPluginNgTemplate() {
 
 function webPluginNgAnnotate() {
   var tmpPath = './dist/web/www';
-  return gulp.src(paths.ng_annotate_plugin)
+  return gulp.src(tmpPath + '/plugins/**/*.js')
     .pipe(ngAnnotate({single_quotes: true}))
     .pipe(gulp.dest(tmpPath + '/dist/dist_js/plugins'));
 }
@@ -439,6 +452,7 @@ function webUglify() {
   const revFilesFilter = filter(['**/*', '!**/index.html', '!**/config.js'], { restore: true });
   const uglifyOptions = {
     toplevel: true,
+    warnings: true,
     compress: {
       global_defs: {
         "@console.log": "alert"
@@ -447,7 +461,7 @@ function webUglify() {
     },
     output: {
       beautify: false,
-      preamble: "/* uglified */",
+      preamble: "/* minified */",
       max_line_len: 120000
     }
   };
@@ -458,7 +472,7 @@ function webUglify() {
 
     // Process JS
     .pipe(jsFilter)
-    .pipe(uglify(uglifyOptions.output))             // Minify any javascript sources
+    .pipe(uglify(uglifyOptions)) // Minify javascript files
     .pipe(jsFilter.restore)
 
     // Process CSS
@@ -502,6 +516,7 @@ function webApiUglify() {
   const indexFilter = filter('**/index.html', { restore: true });
   const uglifyOptions = {
     toplevel: true,
+    warnings: true,
     compress: {
       global_defs: {
         "@console.log": "alert"
@@ -510,7 +525,7 @@ function webApiUglify() {
     },
     output: {
       beautify: false,
-      preamble: "/* uglified */",
+      preamble: "/* minified */",
       max_line_len: 120000
     }
   };
@@ -521,7 +536,7 @@ function webApiUglify() {
 
     // Process JS
     .pipe(jsFilter)
-    .pipe(uglify(uglifyOptions.output)) // Minify any javascript sources
+    .pipe(uglify(uglifyOptions)) // Minify any javascript sources
     .pipe(jsFilter.restore)
 
     // Process CSS
@@ -660,3 +675,5 @@ gulp.task('webZip', ['webCleanUnusedDirectories'], webZip);
 
 gulp.task('webBuild', ['webZip'], webBuildSuccess);
 
+gulp.task('build:web', ['webZip'], webBuildSuccess); // @deprecated
+
diff --git a/hooks/after_prepare/040_useref.js b/hooks/after_prepare/040_useref.js
index e7527ca5..cce0031e 100755
--- a/hooks/after_prepare/040_useref.js
+++ b/hooks/after_prepare/040_useref.js
@@ -5,7 +5,7 @@ const path = require("path");
 const es = require('event-stream');
 const useref = require('gulp-useref');
 const filter = require('gulp-filter');
-const uglify = require('gulp-uglify');
+const uglify = require('gulp-uglify-es').default;
 const csso = require('gulp-csso');
 const rev = require('gulp-rev');
 const revReplace = require('gulp-rev-replace');
@@ -49,7 +49,7 @@ if (rootdir && !skip) {
       },
       output: {
         beautify: false,
-        preamble: "/* uglified */",
+        preamble: "/* minified */",
         max_line_len: 120000
       }
     };
@@ -59,7 +59,7 @@ if (rootdir && !skip) {
       gulp.src(indexPath)
         .pipe(useref())      // Concatenate with gulp-useref
         .pipe(jsFilter)
-        .pipe(uglify(uglifyOptions.output)) // Minify any javascript sources
+        .pipe(uglify(uglifyOptions)) // Minify any javascript sources
         .pipe(jsFilter.restore)
         .pipe(cssFilter)
         .pipe(csso())               // Minify any CSS sources
diff --git a/hooks/before_prepare/02_jshint.js b/hooks/before_prepare/02_jshint.js
index 23954804..bb78f766 100755
--- a/hooks/before_prepare/02_jshint.js
+++ b/hooks/before_prepare/02_jshint.js
@@ -1,30 +1,37 @@
 #!/usr/bin/env node
 
-var fs = require('fs');
-var path = require('path');
-var jshint = require('jshint').JSHINT;
-var async = require('async');
+const fs = require('fs'),
+ path = require('path'),
+ jshint = require('jshint').JSHINT,
+ async = require('async'),
+ log = require('fancy-log'),
+ colors = require('ansi-colors'),
+ glob = require("glob");
 
-var foldersToProcess = [
-    'js',
-    'js/controllers',
-    'js/entities',
-    'js/services',
-    'plugins/es/js',
-    'plugins/es/js/controllers',
-    'plugins/es/js/entities',
-    'plugins/es/js/services'
-];
 
-foldersToProcess.forEach(function(folder) {
-    processFiles("www/" + folder);
-});
+// Get folders, from files
+const jsFolders =  glob.sync("www/**/*.js", {nonull: true})
+  // Map to file's folder
+  .map(file => file.substring(0, file.lastIndexOf('/')))
+  // Reduce to a map of folders
+  .reduce((res, folder) => {
 
-function processFiles(dir, callback) {
+    if (folder.indexOf('www/dist/') !== -1 || // Exclude dist js
+      folder.indexOf('/plugins/rml') !== -1 || // Exclude plugin tutorial
+      folder.indexOf('/vendor') // exclude vendor libs
+    ) return res;
+    res[folder] = res[folder] || true;
+    return res;
+  }, {});
+
+// Process each folder with Js file
+Object.keys(jsFolders).forEach(folder => processFiles(folder));
+
+function processFiles(dir) {
     let errorCount = 0;
     fs.readdir(dir, function(err, list) {
         if (err) {
-            console.log('processFiles err: ' + err);
+            log(colors.red('processFiles err: ' + err));
             return;
         }
         async.eachSeries(list, function(file, innercallback) {
@@ -54,26 +61,23 @@ function processFiles(dir, callback) {
 }
 
 function lintFile(file, callback) {
-    console.log("Linting '" + file + "'");
-    fs.readFile(file, function(err, data) {
+    //log(colors.grey(`Linting ${colors.bold(file)}...`));
+    fs.readFile(file, (err, data) => {
         if(err) {
-            console.error('Error: ' + err);
+            log(colors.red('Error: ' + err));
             return;
         }
         if(jshint(data.toString())) {
-            //console.log('File ' + file + ' has no errors.');
-            //console.log('-----------------------------------------');
             callback(false);
         } else {
-            console.error("Errors in file '" + file + "':");
-            var out = jshint.data(),
-            errors = out.errors;
-            for(var j = 0; j < errors.length; j++) {
-                console.error( " Line " + errors[j].line + ':' + errors[j].character + ' -> ' + errors[j].reason + ' -> ' +
-errors[j].evidence);
-            }
-            console.log('-----------------------------------------');
-            callback(true);
+          const out = jshint.data(),
+          errors = out.errors;
+          for(let j = 0; j < errors.length; j++) {
+            log(colors.red(`${colors.bold(file)}:${colors.bold(errors[j].line)} -> ${colors.bold(errors[j].evidence.trim())}`));
+            log(colors.red(` ${errors[j].reason}`));
+          }
+          log('-----------------------------------------');
+          callback(true);
         }
     });
 }
diff --git a/package.json b/package.json
index 4ae57ef8..fadd2541 100644
--- a/package.json
+++ b/package.json
@@ -123,7 +123,7 @@
     "gulp-header": "^2.0.7",
     "gulp-html-remove": "^0.1.1",
     "gulp-htmlmin": "^2.0.0",
-    "gulp-jshint": "^2.0.1",
+    "gulp-jshint": "^2.1.0",
     "gulp-markdown": "^1.2.0",
     "gulp-ng-annotate": "^2.0.0",
     "gulp-ng-constant": "^1.1.0",
@@ -134,7 +134,7 @@
     "gulp-rev-replace": "^0.4.3",
     "gulp-sass": "^4.0.2",
     "gulp-sourcemaps": "^1.6.0",
-    "gulp-uglify": "^2.1.0",
+    "gulp-uglify-es": "^2.0.0",
     "gulp-useref": "^3.1.0",
     "gulp-zip": "^3.2.0",
     "ionic": "^5.4.13",
@@ -211,4 +211,4 @@
   "engines": {
     "yarn": ">= 1.0.0"
   }
-}
+}
\ No newline at end of file
diff --git a/www/js/api/app.js b/www/js/api/app.js
index cf809a25..c595aa43 100644
--- a/www/js/api/app.js
+++ b/www/js/api/app.js
@@ -255,10 +255,10 @@ angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalpr
 
       if (state.stateParams && state.stateParams.amount) {
         var amountStr = state.stateParams.amount.trim();
-        var amounts = ((amountStr.indexOf('|') !== -1) && amountStr.split('|'))
-          || ((amountStr.indexOf(' ') !== -1) && amountStr.split(' '))
-          || ((amountStr.indexOf(';') !== -1) && amountStr.split(';'));
-        if (amounts){
+        var amounts = ((amountStr.indexOf('|') !== -1) && amountStr.split('|')) ||
+          ((amountStr.indexOf(' ') !== -1) && amountStr.split(' ')) ||
+          ((amountStr.indexOf(';') !== -1) && amountStr.split(';'));
+        if (amounts) {
           $scope.transferData.amounts = amounts.reduce(function(res, amountStr) {
             var amount = normalizeAmount(amountStr);
             return amount > 0 ? res.concat(amount) : res;
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index 2ba2adb0..14ee2a30 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -451,7 +451,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
         history: {
           all: function(params) {
             return exports.raw.tx.history.all(params)
-              .then(res => {
+              .then(function(res) {
                 res.history = res.history || {};
                 // Clean sending and pendings, because already returned by tx/history/:pubkey/pending
                 res.history.sending = [];
@@ -462,7 +462,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium.
           times: function(params, withCache) {
             // No cache by default
             return ((withCache !== true) ? exports.raw.tx.history.times(params) : exports.raw.tx.history.timesWithCache(params))
-              .then(res => {
+              .then(function(res) {
                 res.history = res.history || {};
                 // Clean sending and pendings, because already returned by tx/history/:pubkey/pending
                 res.history.sending = [];
diff --git a/www/js/services/tx-services.js b/www/js/services/tx-services.js
index ff37081a..08e32e59 100644
--- a/www/js/services/tx-services.js
+++ b/www/js/services/tx-services.js
@@ -30,7 +30,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
             var otherReceiver;
             var outputBase;
             var sources = [];
-            let lockedOutputs;
+            var lockedOutputs;
             var amount = tx.outputs.reduce(function(sum, output, noffset) {
               // FIXME duniter v1.4.13
               var outputArray = (typeof output == 'string') ? output.split(':',3) : [output.amount,output.base,output.conditions];
@@ -137,8 +137,8 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
             errors: []
           };
 
-          const processedTxMap = {};
-          const _reducePendingTx = function (res) {
+          var processedTxMap = {};
+          var _reducePendingTx = function (res) {
             _reduceTxAndPush(pubkey, res.history.sending, tx.pendings, processedTxMap, true /*allow pendings*/);
             _reduceTxAndPush(pubkey, res.history.pending, tx.pendings, processedTxMap, true /*allow pendings*/);
           };
@@ -154,7 +154,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
 
           // get TX history since
           if (fromTime !== 'pending') {
-            const _reduceTx = function (res) {
+            var _reduceTx = function (res) {
               _reduceTxAndPush(pubkey, res.history.sent, tx.history, processedTxMap, false);
               _reduceTxAndPush(pubkey, res.history.received, tx.history, processedTxMap, false);
             };
@@ -162,7 +162,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
             // get TX from a given time
             if (fromTime > 0) {
               // Use slice, to be able to cache requests result
-              const sliceTime = csSettings.data.walletHistorySliceSecond;
+              var sliceTime = csSettings.data.walletHistorySliceSecond;
               fromTime = fromTime - (fromTime % sliceTime);
               for(var i = fromTime; i - sliceTime < nowInSec; i += sliceTime)  {
                 jobs.push(BMA.tx.history.times({pubkey: pubkey, from: i, to: i+sliceTime-1}, true /*with cache*/)
@@ -229,7 +229,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
               tx.history.sort(function(tx1, tx2) {
                 return (tx2.time - tx1.time);
               });
-              const firstValidatedTxIndex = tx.history.findIndex((tx) => {
+              var firstValidatedTxIndex = tx.history.findIndex(function(tx){
                 return (tx.block_number <= current.number - csSettings.data.blockValidityWindow);
               });
               // remove validating from history
diff --git a/www/plugins/graph/js/services/data-services.js b/www/plugins/graph/js/services/data-services.js
index 57876dce..3d32d0be 100644
--- a/www/plugins/graph/js/services/data-services.js
+++ b/www/plugins/graph/js/services/data-services.js
@@ -684,6 +684,26 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
       var from = moment.unix(options.startTime).utc().startOf(options.rangeDuration);
       var to = moment.unix(options.endTime).utc().startOf(options.rangeDuration);
       var ranges = [];
+
+      var processSearchResult = function (res) {
+        var aggs = res.aggregations;
+        return (aggs.range && aggs.range.buckets || []).reduce(function (res, agg) {
+          var item = {
+            from: agg.from,
+            to: agg.to
+          };
+          _.forEach(agg.index && agg.index.buckets || [], function (agg) {
+            var index = agg.key;
+            _.forEach(agg.type && agg.type.buckets || [], function (agg) {
+              var key = (index + '_' + agg.key);
+              item[key] = agg.max.value;
+              if (!indices[key]) indices[key] = true;
+            });
+          });
+          return res.concat(item);
+        }, []);
+      };
+
       while(from.isBefore(to)) {
 
         ranges.push({
@@ -734,31 +754,13 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
           ranges = [];
           var indices = {};
 
-          if (jobs.length == 10) {
+          if (jobs.length === 10) {
             console.error('Too many parallel jobs!');
             from = moment.unix(options.endTime).utc(); // stop while
           }
           else {
             jobs.push(
-              exports.raw.docstat.search(request)
-                .then(function (res) {
-                  var aggs = res.aggregations;
-                  return (aggs.range && aggs.range.buckets || []).reduce(function (res, agg) {
-                    var item = {
-                      from: agg.from,
-                      to: agg.to
-                    };
-                    _.forEach(agg.index && agg.index.buckets || [], function (agg) {
-                      var index = agg.key;
-                      _.forEach(agg.type && agg.type.buckets || [], function (agg) {
-                        var key = (index + '_' + agg.key);
-                        item[key] = agg.max.value;
-                        if (!indices[key]) indices[key] = true;
-                      });
-                    });
-                    return res.concat(item);
-                  }, []);
-                })
+              exports.raw.docstat.search(request).then(processSearchResult)
             );
           }
         }
@@ -797,6 +799,27 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
       var from = moment.unix(options.startTime).utc().startOf(options.rangeDuration);
       var to = moment.unix(options.endTime).utc().startOf(options.rangeDuration);
       var ranges = [];
+      var processSearchResult = function (res) {
+        var aggs = res.aggregations;
+
+        return (aggs.range && aggs.range.buckets || []).reduce(function (res, agg) {
+          var item = {
+            from: agg.from,
+            to: agg.to,
+            inserts: agg.result.inserts.value,
+            updates: agg.result.inserts.value,
+            deletes: agg.result.deletes.value,
+            duration: agg.duration.value
+          };
+          _.forEach(agg.api && agg.api.buckets || [], function (api) {
+            item[api.key] = api.peer_count && api.peer_count.value || 0;
+            if (!apis[api.key]) apis[api.key] = true;
+          });
+
+          return res.concat(item);
+        }, []);
+      };
+
       while(from.isBefore(to)) {
 
         ranges.push({
@@ -866,33 +889,14 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
           ranges = [];
           var apis = {};
 
-          if (jobs.length == 10) {
+          if (jobs.length === 10) {
             console.error('Too many parallel jobs!');
             from = moment.unix(options.endTime).utc(); // stop while
           }
           else {
             jobs.push(
               exports.raw.synchro.search(request, {currency: options.currency})
-                .then(function (res) {
-                  var aggs = res.aggregations;
-
-                  return (aggs.range && aggs.range.buckets || []).reduce(function (res, agg) {
-                    var item = {
-                      from: agg.from,
-                      to: agg.to,
-                      inserts: agg.result.inserts.value,
-                      updates: agg.result.inserts.value,
-                      deletes: agg.result.deletes.value,
-                      duration: agg.duration.value
-                    };
-                    _.forEach(agg.api && agg.api.buckets || [], function (api) {
-                      item[api.key] = api.peer_count && api.peer_count.value || 0;
-                      if (!apis[api.key]) apis[api.key] = true;
-                    });
-
-                    return res.concat(item);
-                  }, []);
-                })
+                .then(processSearchResult)
             );
           }
         }
diff --git a/www/plugins/map/js/controllers/network-controllers.js b/www/plugins/map/js/controllers/network-controllers.js
index 6ee819bc..22ac3d55 100644
--- a/www/plugins/map/js/controllers/network-controllers.js
+++ b/www/plugins/map/js/controllers/network-controllers.js
@@ -179,12 +179,14 @@ angular.module('cesium.map.network.controllers', ['cesium.services', 'cesium.map
             else
               this._map.panTo(lnglat);
             var popupMarkerId = lnglat.layer && lnglat.layer.options && lnglat.layer.options.popupMarkerId;
-            popupMarkerId && $timeout(function(){
-              var popupMarker = _.find(map._layers, function(layer) {
+            if (popupMarkerId) {
+              $timeout(function(){
+                var popupMarker = _.find(map._layers, function(layer) {
                   return (layer.options && layer.options.id === popupMarkerId);
                 });
-              popupMarker && popupMarker.openPopup();
-            }, 400);
+                if (popupMarker) popupMarker.openPopup();
+              }, 400);
+            }
           },
           firstTipSubmit: true,
           tooltipLimit: 50
diff --git a/www/plugins/map/js/services/registry-services.js b/www/plugins/map/js/services/registry-services.js
index 30cc657f..7e7a52c4 100644
--- a/www/plugins/map/js/services/registry-services.js
+++ b/www/plugins/map/js/services/registry-services.js
@@ -83,7 +83,10 @@ angular.module('cesium.map.registry.services', ['cesium.services'])
     }*/
 
     var search = mixedSearch ? that.raw.profile.mixedSearch : that.raw.profile.search;
-
+    var processSearchResult = function(res) {
+      if (!res.hits || !res.hits.hits.length) return $q.when([]);
+      return processLoadHits(options, res);
+    };
     return search(request)
       .then(function(res) {
         if (!res.hits || !res.hits.total) return [];
@@ -95,11 +98,9 @@ angular.module('cesium.map.registry.services', ['cesium.services'])
         // Additional slice requests
         request.from += request.size;
         while (request.from < res.hits.total) {
-          jobs.push(search(angular.copy(request))
-            .then(function(res) {
-              if (!res.hits || !res.hits.hits.length) return [];
-              return processLoadHits(options, res);
-            }));
+          jobs.push(
+            search(angular.copy(request)).then(processSearchResult)
+          );
           request.from += request.size;
         }
         return $q.all(jobs)
@@ -112,7 +113,6 @@ angular.module('cesium.map.registry.services', ['cesium.services'])
   }
 
   function processLoadHits(options, res) {
-
     // Transform hits
     var commaRegexp = new RegExp('[,]');
     var searchAddressItems = [];
diff --git a/yarn.lock b/yarn.lock
index bfa276fa..3f409800 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1677,7 +1677,7 @@ commander@2.9.x:
   dependencies:
     graceful-readlink ">= 1.0.0"
 
-commander@^2.9.0:
+commander@^2.20.0, commander@^2.9.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -4012,7 +4012,7 @@ gulp-if@^2.0.2:
     ternary-stream "^2.0.1"
     through2 "^2.0.1"
 
-gulp-jshint@^2.0.1:
+gulp-jshint@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/gulp-jshint/-/gulp-jshint-2.1.0.tgz#bfaf927f78eee263c5bbac5f63e314d44a7bd41e"
   integrity sha512-sP3NK8Y/1e58O0PH9t6s7DAr/lKDSUbIY207oWSeufM6/VclB7jJrIBcPCsyhrFTCDUl9DauePbt6VqP2vPM5w==
@@ -4163,6 +4163,17 @@ gulp-sourcemaps@^1.6.0:
     through2 "2.X"
     vinyl "1.X"
 
+gulp-uglify-es@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/gulp-uglify-es/-/gulp-uglify-es-2.0.0.tgz#0a48d9f352393397e78cf2be44bf0fb66a353031"
+  integrity sha512-00KkawzjWdjPo1YfD1FXKijVxZkyr6YSwJ2cJQgD1fNKFZCFPNjGc5sTyzyW8tZns8FmZafgHMrg7LUDNvIQ5A==
+  dependencies:
+    o-stream "^0.2.2"
+    plugin-error "^1.0.1"
+    terser "^4.3.9"
+    vinyl "^2.2.0"
+    vinyl-sourcemaps-apply "^0.2.1"
+
 gulp-uglify@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-0.2.1.tgz#34f13ecb16c60d86fd84e2093823e62ff72f2ece"
@@ -4174,20 +4185,6 @@ gulp-uglify@^0.2.1:
     uglify-js "~2.4.6"
     vinyl "~0.2.3"
 
-gulp-uglify@^2.1.0:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-2.1.2.tgz#6db85b1d0ee63d18058592b658649d65c2ec4541"
-  integrity sha1-bbhbHQ7mPRgFhZK2WGSdZcLsRUE=
-  dependencies:
-    gulplog "^1.0.0"
-    has-gulplog "^0.1.0"
-    lodash "^4.13.1"
-    make-error-cause "^1.1.1"
-    through2 "^2.0.0"
-    uglify-js "~2.8.10"
-    uglify-save-license "^0.4.1"
-    vinyl-sourcemaps-apply "^0.2.0"
-
 gulp-useref@^3.1.0:
   version "3.1.6"
   resolved "https://registry.yarnpkg.com/gulp-useref/-/gulp-useref-3.1.6.tgz#67721f0ba6747bcfdf40e8bbebaf3cf9330e29da"
@@ -5949,7 +5946,7 @@ lodash@^3.9.1:
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
   integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
 
-lodash@^4.0.0, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.14.1, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5, lodash@~4.17.10, lodash@~4.17.11:
+lodash@^4.0.0, lodash@^4.12.0, lodash@^4.14.1, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5, lodash@~4.17.10, lodash@~4.17.11:
   version "4.17.15"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
   integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -6038,18 +6035,6 @@ make-dir@^1.0.0:
   dependencies:
     pify "^3.0.0"
 
-make-error-cause@^1.1.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
-  integrity sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=
-  dependencies:
-    make-error "^1.2.0"
-
-make-error@^1.2.0:
-  version "1.3.5"
-  resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
-  integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
-
 make-iterator@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
@@ -6653,6 +6638,11 @@ number-is-nan@^1.0.0:
   resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
   integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
 
+o-stream@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/o-stream/-/o-stream-0.2.2.tgz#7fe03af870b8f9537af33b312b381b3034ab410f"
+  integrity sha512-V3j76KU3g/Gyl8rpdi2z72rn5zguMvTCQgAXfBe3pxEefKqXmOUOD7mvx/mNjykdxGqDVfpSoo8r+WdrkWg/1Q==
+
 oauth-sign@~0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.3.0.tgz#cb540f93bb2b22a7d5941691a288d60e8ea9386e"
@@ -8369,6 +8359,14 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
     source-map-url "^0.4.0"
     urix "^0.1.0"
 
+source-map-support@~0.5.12:
+  version "0.5.16"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
+  integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
+  dependencies:
+    buffer-from "^1.0.0"
+    source-map "^0.6.0"
+
 source-map-url@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
@@ -8400,7 +8398,7 @@ source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, sour
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
   integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
 
-source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -8869,6 +8867,15 @@ ternary-stream@^2.0.1:
     merge-stream "^1.0.0"
     through2 "^2.0.1"
 
+terser@^4.3.9:
+  version "4.4.3"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.3.tgz#401abc52b88869cf904412503b1eb7da093ae2f0"
+  integrity sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA==
+  dependencies:
+    commander "^2.20.0"
+    source-map "~0.6.1"
+    source-map-support "~0.5.12"
+
 textextensions@~1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-1.0.2.tgz#65486393ee1f2bb039a60cbba05b0b68bd9501d2"
@@ -9191,21 +9198,6 @@ uglify-js@~2.4.6:
     uglify-to-browserify "~1.0.0"
     yargs "~3.5.4"
 
-uglify-js@~2.8.10:
-  version "2.8.29"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
-  integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0=
-  dependencies:
-    source-map "~0.5.1"
-    yargs "~3.10.0"
-  optionalDependencies:
-    uglify-to-browserify "~1.0.0"
-
-uglify-save-license@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/uglify-save-license/-/uglify-save-license-0.4.1.tgz#95726c17cc6fd171c3617e3bf4d8d82aa8c4cce1"
-  integrity sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=
-
 uglify-to-browserify@~1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
@@ -9524,7 +9516,7 @@ vinyl@^0.5.0:
     clone-stats "^0.0.1"
     replace-ext "0.0.1"
 
-vinyl@^2.0.0, vinyl@^2.1.0:
+vinyl@^2.0.0, vinyl@^2.1.0, vinyl@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86"
   integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==
-- 
GitLab