[SPARK-35175][BUILD] Add linter for JavaScript source files

### What changes were proposed in this pull request?

This PR proposes to add linter for JavaScript source files.
[ESLint](https://eslint.org/) seems to be a popular linter for JavaScript so I choose it.

### Why are the changes needed?

Linter enables us to check style and keeps code clean.

### Does this PR introduce _any_ user-facing change?

No.

### How was this patch tested?

Manually run `dev/lint-js` (Node.js and npm are required).

In this PR, mainly indentation style is also fixed an linter passes.

Closes #32274 from sarutak/introduce-eslint.

Authored-by: Kousuke Saruta <sarutak@oss.nttdata.com>
Signed-off-by: Kousuke Saruta <sarutak@oss.nttdata.com>
This commit is contained in:
Kousuke Saruta 2021-05-07 21:55:08 +09:00
parent d3b92eec45
commit 2634dbac35
19 changed files with 3491 additions and 2358 deletions

4
.gitignore vendored
View file

@ -54,6 +54,7 @@ sql/docs
sql/site sql/site
lib_managed/ lib_managed/
lint-r-report.log lint-r-report.log
lint-js-report.log
log/ log/
logs/ logs/
out/ out/
@ -105,3 +106,6 @@ spark-warehouse/
# For SBT # For SBT
.jvmopts .jvmopts
# For Node.js
node_modules

View file

@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $, formatTimeMillis, getTimeZone */
$(document).ready(function() { $(document).ready(function() {
if ($('#last-updated').length) { if ($('#last-updated').length) {
var lastUpdatedMillis = Number($('#last-updated').text()); var lastUpdatedMillis = Number($('#last-updated').text());

View file

@ -15,11 +15,15 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $, Mustache, formatDuration, formatTimeMillis, jQuery, uiRoot */
var appLimit = -1; var appLimit = -1;
/* eslint-disable no-unused-vars */
function setAppLimit(val) { function setAppLimit(val) {
appLimit = val; appLimit = val;
} }
/* eslint-enable no-unused-vars*/
function makeIdNumeric(id) { function makeIdNumeric(id) {
var strs = id.split("_"); var strs = id.split("_");
@ -30,8 +34,8 @@ function makeIdNumeric(id) {
var resl = strs[0] + "_" + strs[1] + "_"; var resl = strs[0] + "_" + strs[1] + "_";
var diff = 10 - appSeqNum.length; var diff = 10 - appSeqNum.length;
while (diff > 0) { while (diff > 0) {
resl += "0"; // padding 0 before the app sequence number to make sure it has 10 characters resl += "0"; // padding 0 before the app sequence number to make sure it has 10 characters
diff--; diff--;
} }
resl += appSeqNum; resl += appSeqNum;
return resl; return resl;
@ -39,7 +43,7 @@ function makeIdNumeric(id) {
function getParameterByName(name, searchString) { function getParameterByName(name, searchString) {
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(searchString); results = regex.exec(searchString);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
} }
@ -56,183 +60,185 @@ function getColumnIndex(columns, columnName) {
} }
jQuery.extend( jQuery.fn.dataTableExt.oSort, { jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-numeric-pre": function ( a ) { "title-numeric-pre": function ( a ) {
var x = a.match(/title="*(-?[0-9\.]+)/)[1]; var x = a.match(/title="*(-?[0-9.]+)/)[1];
return parseFloat( x ); return parseFloat( x );
}, },
"title-numeric-asc": function ( a, b ) { "title-numeric-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0)); return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}, },
"title-numeric-desc": function ( a, b ) { "title-numeric-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0)); return ((a < b) ? 1 : ((a > b) ? -1 : 0));
} }
} ); });
jQuery.extend( jQuery.fn.dataTableExt.oSort, { jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"appid-numeric-pre": function ( a ) { "appid-numeric-pre": function ( a ) {
var x = a.match(/title="*(-?[0-9a-zA-Z\-\_]+)/)[1]; var x = a.match(/title="*(-?[0-9a-zA-Z\-_]+)/)[1];
return makeIdNumeric(x); return makeIdNumeric(x);
}, },
"appid-numeric-asc": function ( a, b ) { "appid-numeric-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0)); return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}, },
"appid-numeric-desc": function ( a, b ) { "appid-numeric-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0)); return ((a < b) ? 1 : ((a > b) ? -1 : 0));
} }
} ); });
jQuery.extend( jQuery.fn.dataTableExt.ofnSearch, { jQuery.extend( jQuery.fn.dataTableExt.ofnSearch, {
"appid-numeric": function ( a ) { "appid-numeric": function ( a ) {
return a.replace(/[\r\n]/g, " ").replace(/<.*?>/g, ""); return a.replace(/[\r\n]/g, " ").replace(/<.*?>/g, "");
} }
} ); });
$(document).ajaxStop($.unblockUI); $(document).ajaxStop($.unblockUI);
$(document).ajaxStart(function(){ $(document).ajaxStart(function(){
$.blockUI({ message: '<h3>Loading history summary...</h3>'}); $.blockUI({ message: '<h3>Loading history summary...</h3>'});
}); });
$(document).ready(function() { $(document).ready(function() {
$.extend( $.fn.dataTable.defaults, { $.extend( $.fn.dataTable.defaults, {
stateSave: true, stateSave: true,
lengthMenu: [[20,40,60,100,-1], [20, 40, 60, 100, "All"]], lengthMenu: [[20,40,60,100,-1], [20, 40, 60, 100, "All"]],
pageLength: 20 pageLength: 20
}); });
var historySummary = $("#history-summary"); var historySummary = $("#history-summary");
var searchString = window.location.search; var searchString = window.location.search;
var requestedIncomplete = getParameterByName("showIncomplete", searchString); var requestedIncomplete = getParameterByName("showIncomplete", searchString);
requestedIncomplete = (requestedIncomplete == "true" ? true : false); requestedIncomplete = (requestedIncomplete == "true" ? true : false);
var appParams = { var appParams = {
limit: appLimit, limit: appLimit,
status: (requestedIncomplete ? "running" : "completed") status: (requestedIncomplete ? "running" : "completed")
};
$.getJSON(uiRoot + "/api/v1/applications", appParams, function(response, _ignored_status, _ignored_jqXHR) {
var array = [];
var hasMultipleAttempts = false;
for (var i in response) {
var app = response[i];
if (app["attempts"][0]["completed"] == requestedIncomplete) {
continue; // if we want to show for Incomplete, we skip the completed apps; otherwise skip incomplete ones.
}
var version = "Unknown"
if (app["attempts"].length > 0) {
version = app["attempts"][0]["appSparkVersion"]
}
var id = app["id"];
var name = app["name"];
if (app["attempts"].length > 1) {
hasMultipleAttempts = true;
}
// TODO: Replace hasOwnProperty with prototype.hasOwnProperty after we find it's safe to do.
/* eslint-disable no-prototype-builtins */
for (var j in app["attempts"]) {
var attempt = app["attempts"][j];
attempt["startTime"] = formatTimeMillis(attempt["startTimeEpoch"]);
attempt["endTime"] = formatTimeMillis(attempt["endTimeEpoch"]);
attempt["lastUpdated"] = formatTimeMillis(attempt["lastUpdatedEpoch"]);
attempt["log"] = uiRoot + "/api/v1/applications/" + id + "/" +
(attempt.hasOwnProperty("attemptId") ? attempt["attemptId"] + "/" : "") + "logs";
attempt["durationMillisec"] = attempt["duration"];
attempt["duration"] = formatDuration(attempt["duration"]);
attempt["id"] = id;
attempt["name"] = name;
attempt["version"] = version;
attempt["attemptUrl"] = uiRoot + "/history/" + id + "/" +
(attempt.hasOwnProperty("attemptId") ? attempt["attemptId"] + "/" : "") + "jobs/";
array.push(attempt);
}
/* eslint-enable no-prototype-builtins */
}
if(array.length < 20) {
$.fn.dataTable.defaults.paging = false;
}
var data = {
"uiroot": uiRoot,
"applications": array,
"hasMultipleAttempts": hasMultipleAttempts,
"showCompletedColumns": !requestedIncomplete,
}; };
$.getJSON(uiRoot + "/api/v1/applications", appParams, function(response,status,jqXHR) { $.get(uiRoot + "/static/historypage-template.html", function(template) {
var array = []; var sibling = historySummary.prev();
var hasMultipleAttempts = false; historySummary.detach();
for (var i in response) { var apps = $(Mustache.render($(template).filter("#history-summary-template").html(),data));
var app = response[i]; var attemptIdColumnName = 'attemptId';
if (app["attempts"][0]["completed"] == requestedIncomplete) { var startedColumnName = 'started';
continue; // if we want to show for Incomplete, we skip the completed apps; otherwise skip incomplete ones. var completedColumnName = 'completed';
} var durationColumnName = 'duration';
var version = "Unknown" var conf = {
if (app["attempts"].length > 0) { "data": array,
version = app["attempts"][0]["appSparkVersion"] "columns": [
} {name: 'version', data: 'version' },
var id = app["id"]; {
var name = app["name"]; name: 'appId',
if (app["attempts"].length > 1) { type: "appid-numeric",
hasMultipleAttempts = true; data: 'id',
} render: (id, type, row) => `<span title="${id}"><a href="${row.attemptUrl}">${id}</a></span>`
},
for (var j in app["attempts"]) { {name: 'appName', data: 'name' },
var attempt = app["attempts"][j]; {
attempt["startTime"] = formatTimeMillis(attempt["startTimeEpoch"]); name: attemptIdColumnName,
attempt["endTime"] = formatTimeMillis(attempt["endTimeEpoch"]); data: 'attemptId',
attempt["lastUpdated"] = formatTimeMillis(attempt["lastUpdatedEpoch"]); render: (attemptId, type, row) => (attemptId ? `<a href="${row.attemptUrl}">${attemptId}</a>` : '')
attempt["log"] = uiRoot + "/api/v1/applications/" + id + "/" + },
(attempt.hasOwnProperty("attemptId") ? attempt["attemptId"] + "/" : "") + "logs"; {name: startedColumnName, data: 'startTime' },
attempt["durationMillisec"] = attempt["duration"]; {name: completedColumnName, data: 'endTime' },
attempt["duration"] = formatDuration(attempt["duration"]); {name: durationColumnName, type: "title-numeric", data: 'duration' },
attempt["id"] = id; {name: 'user', data: 'sparkUser' },
attempt["name"] = name; {name: 'lastUpdated', data: 'lastUpdated' },
attempt["version"] = version; {
attempt["attemptUrl"] = uiRoot + "/history/" + id + "/" + name: 'eventLog',
(attempt.hasOwnProperty("attemptId") ? attempt["attemptId"] + "/" : "") + "jobs/"; data: 'log',
render: (log, _ignored_type, _ignored_row) => `<a href="${log}" class="btn btn-info btn-mini">Download</a>`
array.push(attempt); },
} ],
} "aoColumnDefs": [
if(array.length < 20) { {
$.fn.dataTable.defaults.paging = false; aTargets: [0, 1, 2],
} fnCreatedCell: (nTd, _ignored_sData, _ignored_oData, _ignored_iRow, _ignored_iCol) => {
if (hasMultipleAttempts) {
var data = { $(nTd).css('background-color', '#fff');
"uiroot": uiRoot, }
"applications": array, }
"hasMultipleAttempts": hasMultipleAttempts, },
"showCompletedColumns": !requestedIncomplete, ],
"autoWidth": false,
"deferRender": true
}; };
$.get(uiRoot + "/static/historypage-template.html", function(template) { if (hasMultipleAttempts) {
var sibling = historySummary.prev(); conf.rowsGroup = [
historySummary.detach(); 'appId:name',
var apps = $(Mustache.render($(template).filter("#history-summary-template").html(),data)); 'version:name',
var attemptIdColumnName = 'attemptId'; 'appName:name'
var startedColumnName = 'started';
var completedColumnName = 'completed';
var durationColumnName = 'duration';
var conf = {
"data": array,
"columns": [
{name: 'version', data: 'version' },
{
name: 'appId',
type: "appid-numeric",
data: 'id',
render: (id, type, row) => `<span title="${id}"><a href="${row.attemptUrl}">${id}</a></span>`
},
{name: 'appName', data: 'name' },
{
name: attemptIdColumnName,
data: 'attemptId',
render: (attemptId, type, row) => (attemptId ? `<a href="${row.attemptUrl}">${attemptId}</a>` : '')
},
{name: startedColumnName, data: 'startTime' },
{name: completedColumnName, data: 'endTime' },
{name: durationColumnName, type: "title-numeric", data: 'duration' },
{name: 'user', data: 'sparkUser' },
{name: 'lastUpdated', data: 'lastUpdated' },
{
name: 'eventLog',
data: 'log',
render: (log, type, row) => `<a href="${log}" class="btn btn-info btn-mini">Download</a>`
},
],
"aoColumnDefs": [
{
aTargets: [0, 1, 2],
fnCreatedCell: (nTd, sData, oData, iRow, iCol) => {
if (hasMultipleAttempts) {
$(nTd).css('background-color', '#fff');
}
}
},
],
"autoWidth": false,
"deferRender": true
};
if (hasMultipleAttempts) {
conf.rowsGroup = [
'appId:name',
'version:name',
'appName:name'
];
} else {
conf.columns = removeColumnByName(conf.columns, attemptIdColumnName);
}
var defaultSortColumn = completedColumnName;
if (requestedIncomplete) {
defaultSortColumn = startedColumnName;
conf.columns = removeColumnByName(conf.columns, completedColumnName);
conf.columns = removeColumnByName(conf.columns, durationColumnName);
}
conf.order = [[ getColumnIndex(conf.columns, defaultSortColumn), "desc" ]];
conf.columnDefs = [
{"searchable": false, "targets": [getColumnIndex(conf.columns, durationColumnName)]}
]; ];
historySummary.append(apps); } else {
apps.DataTable(conf); conf.columns = removeColumnByName(conf.columns, attemptIdColumnName);
sibling.after(historySummary); }
$('#history-summary [data-toggle="tooltip"]').tooltip();
}); var defaultSortColumn = completedColumnName;
if (requestedIncomplete) {
defaultSortColumn = startedColumnName;
conf.columns = removeColumnByName(conf.columns, completedColumnName);
conf.columns = removeColumnByName(conf.columns, durationColumnName);
}
conf.order = [[ getColumnIndex(conf.columns, defaultSortColumn), "desc" ]];
conf.columnDefs = [
{"searchable": false, "targets": [getColumnIndex(conf.columns, durationColumnName)]}
];
historySummary.append(apps);
apps.DataTable(conf);
sibling.after(historySummary);
$('#history-summary [data-toggle="tooltip"]').tooltip();
}); });
});
}); });

View file

@ -15,7 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $ */
$(document).ready(function(){ $(document).ready(function(){
$("[data-toggle=tooltip]").tooltip({container: 'body'}); $("[data-toggle=tooltip]").tooltip({container: 'body'});
}); });

View file

@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $ */
var baseParams; var baseParams;
var curLogLength; var curLogLength;
@ -59,11 +61,12 @@ function getRESTEndPoint() {
var words = document.baseURI.split('/'); var words = document.baseURI.split('/');
var ind = words.indexOf("proxy"); var ind = words.indexOf("proxy");
if (ind > 0) { if (ind > 0) {
return words.slice(0, ind + 2).join('/') + "/log"; return words.slice(0, ind + 2).join('/') + "/log";
} }
return "/log" return "/log"
} }
/* eslint-disable no-unused-vars */
function loadMore() { function loadMore() {
var offset = Math.max(startByte - byteLength, 0); var offset = Math.max(startByte - byteLength, 0);
var moreByteLength = Math.min(byteLength, startByte); var moreByteLength = Math.min(byteLength, startByte);
@ -140,3 +143,4 @@ function initLogPage(params, logLen, start, end, totLogLen, defaultLen) {
disableMoreButton(); disableMoreButton();
} }
} }
/* eslint-enable no-unused-vars */

View file

@ -51,6 +51,8 @@
* since it was forked (commit 101503833a8ce5fe369547f6addf3e71172ce10b). * since it was forked (commit 101503833a8ce5fe369547f6addf3e71172ce10b).
*/ */
/* global $, appBasePath, d3, dagreD3, graphlibDot, uiRoot */
var VizConstants = { var VizConstants = {
svgMarginX: 16, svgMarginX: 16,
svgMarginY: 16, svgMarginY: 16,
@ -166,7 +168,7 @@ function renderDagViz(forJob) {
} }
// Find cached RDDs and mark them as such // Find cached RDDs and mark them as such
metadataContainer().selectAll(".cached-rdd").each(function(v) { metadataContainer().selectAll(".cached-rdd").each(function(_ignored_v) {
var rddId = d3.select(this).text().trim(); var rddId = d3.select(this).text().trim();
var nodeId = VizConstants.nodePrefix + rddId; var nodeId = VizConstants.nodePrefix + rddId;
svg.selectAll("g." + nodeId).classed("cached", true); svg.selectAll("g." + nodeId).classed("cached", true);
@ -180,7 +182,7 @@ function renderDagViz(forJob) {
svg.selectAll("g[id=" + stageClusterId + "] g." + opClusterId).classed("barrier", true) svg.selectAll("g[id=" + stageClusterId + "] g." + opClusterId).classed("barrier", true)
}); });
metadataContainer().selectAll(".indeterminate-rdd").each(function(v) { metadataContainer().selectAll(".indeterminate-rdd").each(function(_ignored_v) {
var rddId = d3.select(this).text().trim(); var rddId = d3.select(this).text().trim();
var nodeId = VizConstants.nodePrefix + rddId; var nodeId = VizConstants.nodePrefix + rddId;
svg.selectAll("g." + nodeId).classed("indeterminate", true); svg.selectAll("g." + nodeId).classed("indeterminate", true);
@ -275,7 +277,7 @@ function renderDagVizForJob(svgContainer) {
// If there are any incoming edges into this graph, keep track of them to render // If there are any incoming edges into this graph, keep track of them to render
// them separately later. Note that we cannot draw them now because we need to // them separately later. Note that we cannot draw them now because we need to
// put these edges in a separate container that is on top of all stage graphs. // put these edges in a separate container that is on top of all stage graphs.
metadata.selectAll(".incoming-edge").each(function(v) { metadata.selectAll(".incoming-edge").each(function(_ignored_v) {
var edge = d3.select(this).text().trim().split(","); // e.g. 3,4 => [3, 4] var edge = d3.select(this).text().trim().split(","); // e.g. 3,4 => [3, 4]
crossStageEdges.push(edge); crossStageEdges.push(edge);
}); });

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $, d3, timeFormat, timeTipStrings */
// timeFormat: StreamingPage.scala will generate a global "timeFormat" dictionary to store the time // timeFormat: StreamingPage.scala will generate a global "timeFormat" dictionary to store the time
// and its formatted string. Because we cannot specify a timezone in JavaScript, to make sure the // and its formatted string. Because we cannot specify a timezone in JavaScript, to make sure the
@ -37,87 +38,90 @@ var onClickTimeline = function() {};
// Show a tooltip "text" for "node" // Show a tooltip "text" for "node"
function showBootstrapTooltip(node, text) { function showBootstrapTooltip(node, text) {
$(node).tooltip({title: text, trigger: "manual", container: "body"}); $(node).tooltip({title: text, trigger: "manual", container: "body"});
$(node).tooltip("show"); $(node).tooltip("show");
} }
// Hide the tooltip for "node" // Hide the tooltip for "node"
function hideBootstrapTooltip(node) { function hideBootstrapTooltip(node) {
$(node).tooltip("dispose"); $(node).tooltip("dispose");
} }
/* eslint-disable no-unused-vars */
// Return the function to scroll to the corresponding // Return the function to scroll to the corresponding
// row on clicking a point of batch in the timeline. // row on clicking a point of batch in the timeline.
function getOnClickTimelineFunction() { function getOnClickTimelineFunction() {
// If the user click one point in the graphs, jump to the batch row and highlight it. And // If the user click one point in the graphs, jump to the batch row and highlight it. And
// recovery the batch row after 3 seconds if necessary. // recovery the batch row after 3 seconds if necessary.
// We need to remember the last clicked batch so that we can recovery it. // We need to remember the last clicked batch so that we can recovery it.
var lastClickedBatch = null; var lastClickedBatch = null;
var lastTimeout = null; var lastTimeout = null;
return function(d) { return function(d) {
var batchSelector = $("#batch-" + d.x); var batchSelector = $("#batch-" + d.x);
// If there is a corresponding batch row, scroll down to it and highlight it. // If there is a corresponding batch row, scroll down to it and highlight it.
if (batchSelector.length > 0) { if (batchSelector.length > 0) {
if (lastTimeout != null) { if (lastTimeout != null) {
window.clearTimeout(lastTimeout); window.clearTimeout(lastTimeout);
} }
if (lastClickedBatch != null) { if (lastClickedBatch != null) {
clearBatchRow(lastClickedBatch); clearBatchRow(lastClickedBatch);
lastClickedBatch = null; lastClickedBatch = null;
} }
lastClickedBatch = d.x; lastClickedBatch = d.x;
highlightBatchRow(lastClickedBatch); highlightBatchRow(lastClickedBatch);
lastTimeout = window.setTimeout(function () { lastTimeout = window.setTimeout(function () {
lastTimeout = null; lastTimeout = null;
if (lastClickedBatch != null) { if (lastClickedBatch != null) {
clearBatchRow(lastClickedBatch); clearBatchRow(lastClickedBatch);
lastClickedBatch = null; lastClickedBatch = null;
}
}, 3000); // Clean up after 3 seconds
var topOffset = batchSelector.offset().top - 15;
if (topOffset < 0) {
topOffset = 0;
}
$('html,body').animate({scrollTop: topOffset}, 200);
} }
}, 3000); // Clean up after 3 seconds
var topOffset = batchSelector.offset().top - 15;
if (topOffset < 0) {
topOffset = 0;
}
$('html,body').animate({scrollTop: topOffset}, 200);
} }
}
} }
// Register a timeline graph. All timeline graphs should be register before calling any // Register a timeline graph. All timeline graphs should be register before calling any
// "drawTimeline" so that we can determine the max margin left for all timeline graphs. // "drawTimeline" so that we can determine the max margin left for all timeline graphs.
function registerTimeline(minY, maxY) { function registerTimeline(minY, maxY) {
var numOfChars = yValueFormat(maxY).length; var numOfChars = yValueFormat(maxY).length;
// A least width for "maxY" in the graph // A least width for "maxY" in the graph
var pxForMaxY = numOfChars * 8 + 10; var pxForMaxY = numOfChars * 8 + 10;
// Make sure we have enough space to show the ticks in the y axis of timeline // Make sure we have enough space to show the ticks in the y axis of timeline
maxMarginLeftForTimeline = pxForMaxY > maxMarginLeftForTimeline? pxForMaxY : maxMarginLeftForTimeline; maxMarginLeftForTimeline = pxForMaxY > maxMarginLeftForTimeline? pxForMaxY : maxMarginLeftForTimeline;
} }
// Register a histogram graph. All histogram graphs should be register before calling any // Register a histogram graph. All histogram graphs should be register before calling any
// "drawHistogram" so that we can determine the max X value for histograms. // "drawHistogram" so that we can determine the max X value for histograms.
function registerHistogram(values, minY, maxY) { function registerHistogram(values, minY, maxY) {
var data = d3.layout.histogram().range([minY, maxY]).bins(histogramBinCount)(values); var data = d3.layout.histogram().range([minY, maxY]).bins(histogramBinCount)(values);
// d.x is the y values while d.y is the x values // d.x is the y values while d.y is the x values
var maxX = d3.max(data, function(d) { return d.y; }); var maxX = d3.max(data, function(d) { return d.y; });
maxXForHistogram = maxX > maxXForHistogram ? maxX : maxXForHistogram; maxXForHistogram = maxX > maxXForHistogram ? maxX : maxXForHistogram;
} }
/* eslint-enable no-unused-vars */
// Draw a line between (x1, y1) and (x2, y2) // Draw a line between (x1, y1) and (x2, y2)
function drawLine(svg, xFunc, yFunc, x1, y1, x2, y2) { function drawLine(svg, xFunc, yFunc, x1, y1, x2, y2) {
var line = d3.svg.line() var line = d3.svg.line()
.x(function(d) { return xFunc(d.x); }) .x(function(d) { return xFunc(d.x); })
.y(function(d) { return yFunc(d.y); }); .y(function(d) { return yFunc(d.y); });
var data = [{x: x1, y: y1}, {x: x2, y: y2}]; var data = [{x: x1, y: y1}, {x: x2, y: y2}];
svg.append("path") svg.append("path")
.datum(data) .datum(data)
.style("stroke-dasharray", ("6, 6")) .style("stroke-dasharray", ("6, 6"))
.style("stroke", "lightblue") .style("stroke", "lightblue")
.attr("class", "line") .attr("class", "line")
.attr("d", line); .attr("d", line);
} }
/* eslint-disable no-unused-vars */
/** /**
* @param id the `id` used in the html `div` tag * @param id the `id` used in the html `div` tag
* @param data the data for the timeline graph * @param data the data for the timeline graph
@ -129,108 +133,105 @@ function drawLine(svg, xFunc, yFunc, x1, y1, x2, y2) {
* @param batchInterval if "batchInterval" is specified, we will draw a line for "batchInterval" in the graph * @param batchInterval if "batchInterval" is specified, we will draw a line for "batchInterval" in the graph
*/ */
function drawTimeline(id, data, minX, maxX, minY, maxY, unitY, batchInterval) { function drawTimeline(id, data, minX, maxX, minY, maxY, unitY, batchInterval) {
// Hide the right border of "<td>". We cannot use "css" directly, or "sorttable.js" will override them. // Hide the right border of "<td>". We cannot use "css" directly, or "sorttable.js" will override them.
d3.select(d3.select(id).node().parentNode) d3.select(d3.select(id).node().parentNode)
.style("padding", "8px 0 8px 8px") .style("padding", "8px 0 8px 8px")
.style("border-right", "0px solid white"); .style("border-right", "0px solid white");
var margin = {top: 20, right: 27, bottom: 30, left: maxMarginLeftForTimeline};
var width = 500 - margin.left - margin.right;
var height = 150 - margin.top - margin.bottom;
var margin = {top: 20, right: 27, bottom: 30, left: maxMarginLeftForTimeline}; var x = d3.scale.linear().domain([minX, maxX]).range([0, width]);
var width = 500 - margin.left - margin.right; var y = d3.scale.linear().domain([minY, maxY]).range([height, 0]);
var height = 150 - margin.top - margin.bottom;
var x = d3.scale.linear().domain([minX, maxX]).range([0, width]); var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(function(d) {
var y = d3.scale.linear().domain([minY, maxY]).range([height, 0]); var formattedDate = timeFormat[d];
var dotIndex = formattedDate.indexOf('.');
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(function(d) { if (dotIndex >= 0) {
var formattedDate = timeFormat[d]; // Remove milliseconds
var dotIndex = formattedDate.indexOf('.'); return formattedDate.substring(0, dotIndex);
if (dotIndex >= 0) { } else {
// Remove milliseconds return formattedDate;
return formattedDate.substring(0, dotIndex);
} else {
return formattedDate;
}
});
var formatYValue = d3.format(",.2f");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5).tickFormat(formatYValue);
var line = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var svg = d3.select(id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Only show the first and last time in the graph
xAxis.tickValues(x.domain());
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "translate(0," + unitLabelYOffset + ")")
.text(unitY);
if (batchInterval && batchInterval <= maxY) {
drawLine(svg, x, y, minX, batchInterval, maxX, batchInterval);
} }
});
var formatYValue = d3.format(",.2f");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5).tickFormat(formatYValue);
svg.append("path") var line = d3.svg.line()
.datum(data) .x(function(d) { return x(d.x); })
.attr("class", "line") .y(function(d) { return y(d.y); });
.attr("d", line);
// If the user click one point in the graphs, jump to the batch row and highlight it. And var svg = d3.select(id).append("svg")
// recovery the batch row after 3 seconds if necessary. .attr("width", width + margin.left + margin.right)
// We need to remember the last clicked batch so that we can recovery it. .attr("height", height + margin.top + margin.bottom)
var lastClickedBatch = null; .append("g")
var lastTimeout = null; .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function isFailedBatch(batchTime) { // Only show the first and last time in the graph
return $("#batch-" + batchTime).attr("isFailed") == "true"; xAxis.tickValues(x.domain());
}
// Add points to the line. However, we make it invisible at first. But when the user moves mouse svg.append("g")
// over a point, it will be displayed with its detail. .attr("class", "x axis")
svg.selectAll(".point") .attr("transform", "translate(0," + height + ")")
.data(data) .call(xAxis);
.enter().append("circle")
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "white";}) // white and opacity = 0 make it invisible svg.append("g")
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "white";}) .attr("class", "y axis")
.attr("opacity", function(d) { return isFailedBatch(d.x) ? "1" : "0";}) .call(yAxis)
.style("cursor", "pointer") .append("text")
.attr("cx", function(d) { return x(d.x); }) .attr("transform", "translate(0," + unitLabelYOffset + ")")
.attr("cy", function(d) { return y(d.y); }) .text(unitY);
.attr("r", function(d) { return isFailedBatch(d.x) ? "2" : "3";})
.on('mouseover', function(d) { if (batchInterval && batchInterval <= maxY) {
var tip = formatYValue(d.y) + " " + unitY + " at " + timeTipStrings[d.x]; drawLine(svg, x, y, minX, batchInterval, maxX, batchInterval);
showBootstrapTooltip(d3.select(this).node(), tip); }
// show the point
d3.select(this) svg.append("path")
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "steelblue";}) .datum(data)
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "steelblue";}) .attr("class", "line")
.attr("opacity", "1") .attr("d", line);
.attr("r", "3"); // If the user click one point in the graphs, jump to the batch row and highlight it. And
}) // recovery the batch row after 3 seconds if necessary.
.on('mouseout', function() { // We need to remember the last clicked batch so that we can recovery it.
hideBootstrapTooltip(d3.select(this).node()); var lastClickedBatch = null;
// hide the point var lastTimeout = null;
d3.select(this)
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "white";}) function isFailedBatch(batchTime) {
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "white";}) return $("#batch-" + batchTime).attr("isFailed") == "true";
.attr("opacity", function(d) { return isFailedBatch(d.x) ? "1" : "0";}) }
.attr("r", function(d) { return isFailedBatch(d.x) ? "2" : "3";});
}) // Add points to the line. However, we make it invisible at first. But when the user moves mouse
.on("click", onClickTimeline); // over a point, it will be displayed with its detail.
svg.selectAll(".point")
.data(data)
.enter().append("circle")
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "white";}) // white and opacity = 0 make it invisible
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "white";})
.attr("opacity", function(d) { return isFailedBatch(d.x) ? "1" : "0";})
.style("cursor", "pointer")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", function(d) { return isFailedBatch(d.x) ? "2" : "3";})
.on('mouseover', function(d) {
var tip = formatYValue(d.y) + " " + unitY + " at " + timeTipStrings[d.x];
showBootstrapTooltip(d3.select(this).node(), tip);
// show the point
d3.select(this)
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "steelblue";})
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "steelblue";})
.attr("opacity", "1")
.attr("r", "3");
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
// hide the point
d3.select(this)
.attr("stroke", function(d) { return isFailedBatch(d.x) ? "red" : "white";})
.attr("fill", function(d) { return isFailedBatch(d.x) ? "red" : "white";})
.attr("opacity", function(d) { return isFailedBatch(d.x) ? "1" : "0";})
.attr("r", function(d) { return isFailedBatch(d.x) ? "2" : "3";});
})
.on("click", onClickTimeline);
} }
/** /**
@ -242,105 +243,106 @@ function drawTimeline(id, data, minX, maxX, minY, maxY, unitY, batchInterval) {
* @param batchInterval if "batchInterval" is specified, we will draw a line for "batchInterval" in the graph * @param batchInterval if "batchInterval" is specified, we will draw a line for "batchInterval" in the graph
*/ */
function drawHistogram(id, values, minY, maxY, unitY, batchInterval) { function drawHistogram(id, values, minY, maxY, unitY, batchInterval) {
// Hide the left border of "<td>". We cannot use "css" directly, or "sorttable.js" will override them. // Hide the left border of "<td>". We cannot use "css" directly, or "sorttable.js" will override them.
d3.select(d3.select(id).node().parentNode) d3.select(d3.select(id).node().parentNode)
.style("padding", "8px 8px 8px 0") .style("padding", "8px 8px 8px 0")
.style("border-left", "0px solid white"); .style("border-left", "0px solid white");
var margin = {top: 20, right: 30, bottom: 30, left: 10}; var margin = {top: 20, right: 30, bottom: 30, left: 10};
var width = 350 - margin.left - margin.right; var width = 350 - margin.left - margin.right;
var height = 150 - margin.top - margin.bottom; var height = 150 - margin.top - margin.bottom;
var x = d3.scale.linear().domain([0, maxXForHistogram]).range([0, width - 50]); var x = d3.scale.linear().domain([0, maxXForHistogram]).range([0, width - 50]);
var y = d3.scale.linear().domain([minY, maxY]).range([height, 0]); var y = d3.scale.linear().domain([minY, maxY]).range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("top").ticks(5); var xAxis = d3.svg.axis().scale(x).orient("top").ticks(5);
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(0).tickFormat(function(d) { return ""; }); var yAxis = d3.svg.axis().scale(y).orient("left").ticks(0).tickFormat(function(d) { return ""; });
var data = d3.layout.histogram().range([minY, maxY]).bins(histogramBinCount)(values); var data = d3.layout.histogram().range([minY, maxY]).bins(histogramBinCount)(values);
var svg = d3.select(id).append("svg") var svg = d3.select(id).append("svg")
.attr("width", width + margin.left + margin.right) .attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom) .attr("height", height + margin.top + margin.bottom)
.append("g") .append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
if (batchInterval && batchInterval <= maxY) { if (batchInterval && batchInterval <= maxY) {
drawLine(svg, x, y, 0, batchInterval, maxXForHistogram, batchInterval); drawLine(svg, x, y, 0, batchInterval, maxXForHistogram, batchInterval);
} }
svg.append("g") svg.append("g")
.attr("class", "x axis") .attr("class", "x axis")
.call(xAxis) .call(xAxis)
.append("text") .append("text")
.attr("transform", "translate(" + (margin.left + width - 45) + ", " + unitLabelYOffset + ")") .attr("transform", "translate(" + (margin.left + width - 45) + ", " + unitLabelYOffset + ")")
.text("#batches"); .text("#batches");
svg.append("g") svg.append("g")
.attr("class", "y axis") .attr("class", "y axis")
.call(yAxis); .call(yAxis);
svg.selectAll(".bar") svg.selectAll(".bar")
.data(data) .data(data)
.enter() .enter()
.append("g") .append("g")
.attr("transform", function(d) { return "translate(0," + (y(d.x) - height + y(d.dx)) + ")";}) .attr("transform", function(d) { return "translate(0," + (y(d.x) - height + y(d.dx)) + ")";})
.attr("class", "bar").append("rect") .attr("class", "bar").append("rect")
.attr("width", function(d) { return x(d.y); }) .attr("width", function(d) { return x(d.y); })
.attr("height", function(d) { return height - y(d.dx); }) .attr("height", function(d) { return height - y(d.dx); })
.on('mouseover', function(d) { .on('mouseover', function(d) {
var percent = yValueFormat(d.y * 100.0 / values.length) + "%"; var percent = yValueFormat(d.y * 100.0 / values.length) + "%";
var tip = d.y + " batches (" + percent + ") between " + yValueFormat(d.x) + " and " + yValueFormat(d.x + d.dx) + " " + unitY; var tip = d.y + " batches (" + percent + ") between " + yValueFormat(d.x) + " and " + yValueFormat(d.x + d.dx) + " " + unitY;
showBootstrapTooltip(d3.select(this).node(), tip); showBootstrapTooltip(d3.select(this).node(), tip);
}) })
.on('mouseout', function() { .on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node()); hideBootstrapTooltip(d3.select(this).node());
});
if (batchInterval && batchInterval <= maxY) {
// Add the "stable" text to the graph below the batch interval line.
var stableXOffset = x(maxXForHistogram) - 20;
var stableYOffset = y(batchInterval) + 15;
svg.append("text")
.style("fill", "lightblue")
.attr("class", "stable-text")
.attr("text-anchor", "middle")
.attr("transform", "translate(" + stableXOffset + "," + stableYOffset + ")")
.text("stable")
.on('mouseover', function(d) {
var tip = "Processing Time <= Batch Interval (" + yValueFormat(batchInterval) +" " + unitY +")";
showBootstrapTooltip(d3.select(this).node(), tip);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
});
}
}
$(function() {
var status = window.localStorage && window.localStorage.getItem("show-streams-detail") == "true";
$("span.expand-input-rate").click(function() {
status = !status;
$("#inputs-table").toggle('collapsed');
// Toggle the class of the arrow between open and closed
$(this).find('.expand-input-rate-arrow').toggleClass('arrow-open').toggleClass('arrow-closed');
if (window.localStorage) {
window.localStorage.setItem("show-streams-detail", "" + status);
}
}); });
if (status) { if (batchInterval && batchInterval <= maxY) {
$("#inputs-table").toggle('collapsed'); // Add the "stable" text to the graph below the batch interval line.
// Toggle the class of the arrow between open and closed var stableXOffset = x(maxXForHistogram) - 20;
$(this).find('.expand-input-rate-arrow').toggleClass('arrow-open').toggleClass('arrow-closed'); var stableYOffset = y(batchInterval) + 15;
svg.append("text")
.style("fill", "lightblue")
.attr("class", "stable-text")
.attr("text-anchor", "middle")
.attr("transform", "translate(" + stableXOffset + "," + stableYOffset + ")")
.text("stable")
.on('mouseover', function(d) {
var tip = "Processing Time <= Batch Interval (" + yValueFormat(batchInterval) +" " + unitY +")";
showBootstrapTooltip(d3.select(this).node(), tip);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
});
}
}
/* eslint-enable no-unused-vars */
$(function() {
var status = window.localStorage && window.localStorage.getItem("show-streams-detail") == "true";
$("span.expand-input-rate").click(function() {
status = !status;
$("#inputs-table").toggle('collapsed');
// Toggle the class of the arrow between open and closed
$(this).find('.expand-input-rate-arrow').toggleClass('arrow-open').toggleClass('arrow-closed');
if (window.localStorage) {
window.localStorage.setItem("show-streams-detail", "" + status);
} }
});
if (status) {
$("#inputs-table").toggle('collapsed');
// Toggle the class of the arrow between open and closed
$(this).find('.expand-input-rate-arrow').toggleClass('arrow-open').toggleClass('arrow-closed');
}
}); });
function highlightBatchRow(batch) { function highlightBatchRow(batch) {
$("#batch-" + batch).parent().addClass("batch-table-cell-highlight"); $("#batch-" + batch).parent().addClass("batch-table-cell-highlight");
} }
function clearBatchRow(batch) { function clearBatchRow(batch) {
$("#batch-" + batch).parent().removeClass("batch-table-cell-highlight"); $("#batch-" + batch).parent().removeClass("batch-table-cell-highlight");
} }

View file

@ -15,157 +15,158 @@
* limitations under the License. * limitations under the License.
*/ */
/* global d3, formattedTimeTipStrings, formattedTimeToValues, hideBootstrapTooltip, maxMarginLeftForTimeline, showBootstrapTooltip, unitLabelYOffset */
// pre-define some colors for legends. // pre-define some colors for legends.
var colorPool = ["#F8C471", "#F39C12", "#B9770E", "#73C6B6", "#16A085", "#117A65", "#B2BABB", "#7F8C8D", "#616A6B"]; var colorPool = ["#F8C471", "#F39C12", "#B9770E", "#73C6B6", "#16A085", "#117A65", "#B2BABB", "#7F8C8D", "#616A6B"];
/* eslint-disable no-unused-vars */
function drawAreaStack(id, labels, values, minX, maxX, minY, maxY) { function drawAreaStack(id, labels, values, minX, maxX, minY, maxY) {
d3.select(d3.select(id).node().parentNode) d3.select(d3.select(id).node().parentNode)
.style("padding", "8px 0 8px 8px") .style("padding", "8px 0 8px 8px")
.style("border-right", "0px solid white"); .style("border-right", "0px solid white");
// Setup svg using Bostock's margin convention // Setup svg using Bostock's margin convention
var margin = {top: 20, right: 40, bottom: 30, left: maxMarginLeftForTimeline}; var margin = {top: 20, right: 40, bottom: 30, left: maxMarginLeftForTimeline};
var width = 850 - margin.left - margin.right; var width = 850 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom; var height = 300 - margin.top - margin.bottom;
var svg = d3.select(id) var svg = d3.select(id)
.append("svg") .append("svg")
.attr("width", width + margin.left + margin.right) .attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom) .attr("height", height + margin.top + margin.bottom)
.append("g") .append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var data = values; var data = values;
var parse = d3.time.format("%H:%M:%S.%L").parse; var parse = d3.time.format("%H:%M:%S.%L").parse;
// Transpose the data into layers // Transpose the data into layers
var dataset = d3.layout.stack()(labels.map(function(fruit) { var dataset = d3.layout.stack()(labels.map(function(fruit) {
return data.map(function(d) { return data.map(function(d) {
return {_x: d.x, x: parse(d.x), y: +d[fruit]}; return {_x: d.x, x: parse(d.x), y: +d[fruit]};
}); });
})); }));
// Set x, y and colors
var x = d3.scale.ordinal()
.domain(dataset[0].map(function(d) { return d.x; }))
.rangeRoundBands([10, width-10], 0.02);
// Set x, y and colors var y = d3.scale.linear()
var x = d3.scale.ordinal() .domain([0, d3.max(dataset, function(d) { return d3.max(d, function(d) { return d.y0 + d.y; }); })])
.domain(dataset[0].map(function(d) { return d.x; })) .range([height, 0]);
.rangeRoundBands([10, width-10], 0.02);
var y = d3.scale.linear() var colors = colorPool.slice(0, labels.length);
.domain([0, d3.max(dataset, function(d) { return d3.max(d, function(d) { return d.y0 + d.y; }); })])
.range([height, 0]);
var colors = colorPool.slice(0, labels.length) // Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(7)
.tickFormat( function(d) { return d } );
// Define and draw axes var xAxis = d3.svg.axis()
var yAxis = d3.svg.axis() .scale(x)
.scale(y) .orient("bottom")
.orient("left") .tickFormat(d3.time.format("%H:%M:%S.%L"));
.ticks(7)
.tickFormat( function(d) { return d } );
var xAxis = d3.svg.axis() // Only show the first and last time in the graph
.scale(x) var xline = [];
.orient("bottom") xline.push(x.domain()[0]);
.tickFormat(d3.time.format("%H:%M:%S.%L")); xline.push(x.domain()[x.domain().length - 1]);
xAxis.tickValues(xline);
// Only show the first and last time in the graph svg.append("g")
var xline = [] .attr("class", "y axis")
xline.push(x.domain()[0]) .call(yAxis)
xline.push(x.domain()[x.domain().length - 1]) .append("text")
xAxis.tickValues(xline); .attr("transform", "translate(0," + unitLabelYOffset + ")")
.text("ms");
svg.append("g") svg.append("g")
.attr("class", "y axis") .attr("class", "x axis")
.call(yAxis) .attr("transform", "translate(0," + height + ")")
.append("text") .call(xAxis);
.attr("transform", "translate(0," + unitLabelYOffset + ")")
.text("ms");
svg.append("g") // Create groups for each series, rects for each segment
.attr("class", "x axis") var groups = svg.selectAll("g.cost")
.attr("transform", "translate(0," + height + ")") .data(dataset)
.call(xAxis); .enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) { return colors[i]; });
// Create groups for each series, rects for each segment var rect = groups.selectAll("rect")
var groups = svg.selectAll("g.cost") .data(function(d) { return d; })
.data(dataset) .enter()
.enter().append("g") .append("rect")
.attr("class", "cost") .attr("x", function(d) { return x(d.x); })
.style("fill", function(d, i) { return colors[i]; }); .attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.attr("width", x.rangeBand())
.on('mouseover', function(d) {
var tip = '';
var idx = 0;
var _values = formattedTimeToValues[d._x];
_values.forEach(function (k) {
tip += labels[idx] + ': ' + k + ' ';
idx += 1;
});
tip += " at " + formattedTimeTipStrings[d._x];
showBootstrapTooltip(d3.select(this).node(), tip);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
var rect = groups.selectAll("rect") // Draw legend
.data(function(d) { return d; }) var legend = svg.selectAll(".legend")
.enter() .data(colors)
.append("rect") .enter().append("g")
.attr("x", function(d) { return x(d.x); }) .attr("class", "legend")
.attr("y", function(d) { return y(d.y0 + d.y); }) .attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; });
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.attr("width", x.rangeBand())
.on('mouseover', function(d) {
var tip = '';
var idx = 0;
var _values = formattedTimeToValues[d._x];
_values.forEach(function (k) {
tip += labels[idx] + ': ' + k + ' ';
idx += 1;
});
tip += " at " + formattedTimeTipStrings[d._x];
showBootstrapTooltip(d3.select(this).node(), tip);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
legend.append("rect")
.attr("x", width - 20)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {return colors.slice().reverse()[i];})
.on('mouseover', function(d, i) {
var len = labels.length;
showBootstrapTooltip(d3.select(this).node(), labels[len - 1 - i]);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
// Draw legend // Prep the tooltip bits, initial display is hidden
var legend = svg.selectAll(".legend") var tooltip = svg.append("g")
.data(colors) .attr("class", "tooltip")
.enter().append("g") .style("display", "none");
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; });
legend.append("rect") tooltip.append("rect")
.attr("x", width - 20) .attr("width", 30)
.attr("width", 18) .attr("height", 20)
.attr("height", 18) .attr("fill", "white")
.style("fill", function(d, i) {return colors.slice().reverse()[i];}) .style("opacity", 0.5);
.on('mouseover', function(d, i) {
var len = labels.length
showBootstrapTooltip(d3.select(this).node(), labels[len - 1 - i]);
})
.on('mouseout', function() {
hideBootstrapTooltip(d3.select(this).node());
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
// Prep the tooltip bits, initial display is hidden tooltip.append("text")
var tooltip = svg.append("g") .attr("x", 15)
.attr("class", "tooltip") .attr("dy", "1.2em")
.style("display", "none"); .style("text-anchor", "middle")
.attr("font-size", "12px")
tooltip.append("rect") .attr("font-weight", "bold");
.attr("width", 30)
.attr("height", 20)
.attr("fill", "white")
.style("opacity", 0.5);
tooltip.append("text")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-weight", "bold");
} }
/* eslint-enable no-unused-vars */

View file

@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $ */
/* eslint-disable no-unused-vars */
/* Adds background colors to stripe table rows in the summary table (on the stage page). This is /* Adds background colors to stripe table rows in the summary table (on the stage page). This is
* necessary (instead of using css or the table striping provided by bootstrap) because the summary * necessary (instead of using css or the table striping provided by bootstrap) because the summary
* table has hidden rows. * table has hidden rows.
@ -22,84 +24,88 @@
* An ID selector (rather than a class selector) is used to ensure this runs quickly even on pages * An ID selector (rather than a class selector) is used to ensure this runs quickly even on pages
* with thousands of task rows (ID selectors are much faster than class selectors). */ * with thousands of task rows (ID selectors are much faster than class selectors). */
function stripeSummaryTable() { function stripeSummaryTable() {
$("#task-summary-table").find("tr:not(:hidden)").each(function (index) { $("#task-summary-table").find("tr:not(:hidden)").each(function (index) {
if (index % 2 == 1) { if (index % 2 == 1) {
$(this).css("background-color", "#f9f9f9"); $(this).css("background-color", "#f9f9f9");
} else { } else {
$(this).css("background-color", "#ffffff"); $(this).css("background-color", "#ffffff");
} }
}); });
} }
/* eslint-enable no-unused-vars */
function toggleThreadStackTrace(threadId, forceAdd) { function toggleThreadStackTrace(threadId, forceAdd) {
var stackTrace = $("#" + threadId + "_stacktrace") var stackTrace = $("#" + threadId + "_stacktrace");
if (stackTrace.length == 0) { if (stackTrace.length == 0) {
var stackTraceText = $('#' + threadId + "_td_stacktrace").html() var stackTraceText = $('#' + threadId + "_td_stacktrace").html();
var threadCell = $("#thread_" + threadId + "_tr") var threadCell = $("#thread_" + threadId + "_tr");
threadCell.after("<tr id=\"" + threadId +"_stacktrace\" class=\"accordion-body\"><td colspan=\"4\"><pre>" + threadCell.after("<tr id=\"" + threadId +"_stacktrace\" class=\"accordion-body\"><td colspan=\"4\"><pre>" +
stackTraceText + "</pre></td></tr>") stackTraceText + "</pre></td></tr>")
} else { } else {
if (!forceAdd) { if (!forceAdd) {
stackTrace.remove() stackTrace.remove()
}
} }
}
} }
/* eslint-disable no-unused-vars */
function expandAllThreadStackTrace(toggleButton) { function expandAllThreadStackTrace(toggleButton) {
$('.accordion-heading').each(function() { $('.accordion-heading').each(function() {
//get thread ID //get thread ID
if (!$(this).hasClass("d-none")) { if (!$(this).hasClass("d-none")) {
var trId = $(this).attr('id').match(/thread_([0-9]+)_tr/m)[1] var trId = $(this).attr('id').match(/thread_([0-9]+)_tr/m)[1];
toggleThreadStackTrace(trId, true) toggleThreadStackTrace(trId, true)
}
})
if (toggleButton) {
$('.expandbutton').toggleClass('d-none')
} }
});
if (toggleButton) {
$('.expandbutton').toggleClass('d-none')
}
} }
/* eslint-enable no-unused-vars */
function collapseAllThreadStackTrace(toggleButton) { function collapseAllThreadStackTrace(toggleButton) {
$('.accordion-body').each(function() { $('.accordion-body').each(function() {
$(this).remove() $(this).remove()
}) });
if (toggleButton) { if (toggleButton) {
$('.expandbutton').toggleClass('d-none'); $('.expandbutton').toggleClass('d-none');
} }
} }
/* eslint-disable no-unused-vars */
// inOrOut - true: over, false: out // inOrOut - true: over, false: out
function onMouseOverAndOut(threadId) { function onMouseOverAndOut(threadId) {
$("#" + threadId + "_td_id").toggleClass("threaddump-td-mouseover"); $("#" + threadId + "_td_id").toggleClass("threaddump-td-mouseover");
$("#" + threadId + "_td_name").toggleClass("threaddump-td-mouseover"); $("#" + threadId + "_td_name").toggleClass("threaddump-td-mouseover");
$("#" + threadId + "_td_state").toggleClass("threaddump-td-mouseover"); $("#" + threadId + "_td_state").toggleClass("threaddump-td-mouseover");
$("#" + threadId + "_td_locking").toggleClass("threaddump-td-mouseover"); $("#" + threadId + "_td_locking").toggleClass("threaddump-td-mouseover");
} }
function onSearchStringChange() { function onSearchStringChange() {
var searchString = $('#search').val().toLowerCase(); var searchString = $('#search').val().toLowerCase();
//remove the stacktrace //remove the stacktrace
collapseAllThreadStackTrace(false) collapseAllThreadStackTrace(false);
if (searchString.length == 0) { if (searchString.length == 0) {
$('tr').each(function() { $('tr').each(function() {
$(this).removeClass('d-none') $(this).removeClass('d-none')
}) })
} else { } else {
$('tr').each(function(){ $('tr').each(function(){
if($(this).attr('id') && $(this).attr('id').match(/thread_[0-9]+_tr/) ) { if($(this).attr('id') && $(this).attr('id').match(/thread_[0-9]+_tr/) ) {
var children = $(this).children() var children = $(this).children();
var found = false var found = false;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
if (children.eq(i).text().toLowerCase().indexOf(searchString) >= 0) { if (children.eq(i).text().toLowerCase().indexOf(searchString) >= 0) {
found = true found = true;
} }
} }
if (found) { if (found) {
$(this).removeClass('d-none') $(this).removeClass('d-none')
} else { } else {
$(this).addClass('d-none') $(this).addClass('d-none')
} }
} }
}); });
} }
} }
/* eslint-enable no-unused-vars */

View file

@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $, vis, uiRoot, appBasePath */
/* eslint-disable no-unused-vars */
function drawApplicationTimeline(groupArray, eventObjArray, startTime, offset) { function drawApplicationTimeline(groupArray, eventObjArray, startTime, offset) {
var groups = new vis.DataSet(groupArray); var groups = new vis.DataSet(groupArray);
var items = new vis.DataSet(eventObjArray); var items = new vis.DataSet(eventObjArray);
@ -249,7 +251,7 @@ function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, ma
var visibilityState = status ? "" : "none"; var visibilityState = status ? "" : "none";
$("#task-assignment-timeline").css("display", visibilityState); $("#task-assignment-timeline").css("display", visibilityState);
// Switch the class of the arrow from open to closed. // Switch the class of the arrow from open to closed.
$(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-open"); $(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-open");
$(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-closed"); $(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-closed");
@ -280,6 +282,7 @@ function setupExecutorEventAction() {
); );
}); });
} }
/* eslint-enable no-unused-vars */
function setupZoomable(id, timeline) { function setupZoomable(id, timeline) {
$(id + ' > input[type="checkbox"]').click(function() { $(id + ' > input[type="checkbox"]').click(function() {

View file

@ -15,42 +15,46 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $, uiRoot */
/* eslint-disable no-unused-vars */
// this function works exactly the same as UIUtils.formatDuration // this function works exactly the same as UIUtils.formatDuration
function formatDuration(milliseconds) { function formatDuration(milliseconds) {
if (milliseconds < 100) { if (milliseconds < 100) {
return parseInt(milliseconds).toFixed(1) + " ms"; return parseInt(milliseconds).toFixed(1) + " ms";
} }
var seconds = milliseconds * 1.0 / 1000; var seconds = milliseconds * 1.0 / 1000;
if (seconds < 1) { if (seconds < 1) {
return seconds.toFixed(1) + " s"; return seconds.toFixed(1) + " s";
} }
if (seconds < 60) { if (seconds < 60) {
return seconds.toFixed(0) + " s"; return seconds.toFixed(0) + " s";
} }
var minutes = seconds / 60; var minutes = seconds / 60;
if (minutes < 10) { if (minutes < 10) {
return minutes.toFixed(1) + " min"; return minutes.toFixed(1) + " min";
} else if (minutes < 60) { } else if (minutes < 60) {
return minutes.toFixed(0) + " min"; return minutes.toFixed(0) + " min";
} }
var hours = minutes / 60; var hours = minutes / 60;
return hours.toFixed(1) + " h"; return hours.toFixed(1) + " h";
} }
function formatBytes(bytes, type) { function formatBytes(bytes, type) {
if (type !== 'display') return bytes; if (type !== 'display') return bytes;
if (bytes <= 0) return '0.0 B'; if (bytes <= 0) return '0.0 B';
var k = 1024; var k = 1024;
var dm = 1; var dm = 1;
var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var i = Math.floor(Math.log(bytes) / Math.log(k)); var i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
} }
/* eslint-enable no-unused-vars */
function padZeroes(num) { function padZeroes(num) {
return ("0" + num).slice(-2); return ("0" + num).slice(-2);
} }
/* eslint-disable no-unused-vars */
function formatTimeMillis(timeMillis) { function formatTimeMillis(timeMillis) {
if (timeMillis <= 0) { if (timeMillis <= 0) {
return "-"; return "-";
@ -59,16 +63,18 @@ function formatTimeMillis(timeMillis) {
return formatDateString(dt); return formatDateString(dt);
} }
} }
/* eslint-enable no-unused-vars */
function formatDateString(dt) { function formatDateString(dt) {
return dt.getFullYear() + "-" + return dt.getFullYear() + "-" +
padZeroes(dt.getMonth() + 1) + "-" + padZeroes(dt.getMonth() + 1) + "-" +
padZeroes(dt.getDate()) + " " + padZeroes(dt.getDate()) + " " +
padZeroes(dt.getHours()) + ":" + padZeroes(dt.getHours()) + ":" +
padZeroes(dt.getMinutes()) + ":" + padZeroes(dt.getMinutes()) + ":" +
padZeroes(dt.getSeconds()); padZeroes(dt.getSeconds());
} }
/* eslint-disable no-unused-vars */
function getTimeZone() { function getTimeZone() {
try { try {
return Intl.DateTimeFormat().resolvedOptions().timeZone; return Intl.DateTimeFormat().resolvedOptions().timeZone;
@ -92,14 +98,15 @@ function formatLogsCells(execLogs, type) {
function getStandAloneAppId(cb) { function getStandAloneAppId(cb) {
var words = document.baseURI.split('/'); var words = document.baseURI.split('/');
var ind = words.indexOf("proxy"); var ind = words.indexOf("proxy");
var appId;
if (ind > 0) { if (ind > 0) {
var appId = words[ind + 1]; appId = words[ind + 1];
cb(appId); cb(appId);
return; return;
} }
ind = words.indexOf("history"); ind = words.indexOf("history");
if (ind > 0) { if (ind > 0) {
var appId = words[ind + 1]; appId = words[ind + 1];
cb(appId); cb(appId);
return; return;
} }
@ -119,7 +126,7 @@ function getStandAloneAppId(cb) {
// It will convert the string into integer for correct ordering // It will convert the string into integer for correct ordering
function ConvertDurationString(data) { function ConvertDurationString(data) {
data = data.toString(); data = data.toString();
var units = data.replace(/[\d\.]/g, '' ) var units = data.replace(/[\d.]/g, '' )
.replace(' ', '') .replace(' ', '')
.toLowerCase(); .toLowerCase();
var multiplier = 1; var multiplier = 1;
@ -143,13 +150,14 @@ function ConvertDurationString(data) {
function createTemplateURI(appId, templateName) { function createTemplateURI(appId, templateName) {
var words = document.baseURI.split('/'); var words = document.baseURI.split('/');
var ind = words.indexOf("proxy"); var ind = words.indexOf("proxy");
var baseURI;
if (ind > 0) { if (ind > 0) {
var baseURI = words.slice(0, ind + 1).join('/') + '/' + appId + '/static/' + templateName + '-template.html'; baseURI = words.slice(0, ind + 1).join('/') + '/' + appId + '/static/' + templateName + '-template.html';
return baseURI; return baseURI;
} }
ind = words.indexOf("history"); ind = words.indexOf("history");
if(ind > 0) { if(ind > 0) {
var baseURI = words.slice(0, ind).join('/') + '/static/' + templateName + '-template.html'; baseURI = words.slice(0, ind).join('/') + '/static/' + templateName + '-template.html';
return baseURI; return baseURI;
} }
return uiRoot + "/static/" + templateName + "-template.html"; return uiRoot + "/static/" + templateName + "-template.html";
@ -159,7 +167,7 @@ function setDataTableDefaults() {
$.extend($.fn.dataTable.defaults, { $.extend($.fn.dataTable.defaults, {
stateSave: true, stateSave: true,
stateSaveParams: function(_, data) { stateSaveParams: function(_, data) {
data.search.search = ""; data.search.search = "";
}, },
lengthMenu: [[20, 40, 60, 100, -1], [20, 40, 60, 100, "All"]], lengthMenu: [[20, 40, 60, 100, -1], [20, 40, 60, 100, "All"]],
pageLength: 20 pageLength: 20
@ -169,51 +177,54 @@ function setDataTableDefaults() {
function formatDate(date) { function formatDate(date) {
if (date <= 0) return "-"; if (date <= 0) return "-";
else { else {
var dt = new Date(date.replace("GMT", "Z")); var dt = new Date(date.replace("GMT", "Z"));
return formatDateString(dt); return formatDateString(dt);
} }
} }
function createRESTEndPointForExecutorsPage(appId) { function createRESTEndPointForExecutorsPage(appId) {
var words = document.baseURI.split('/'); var words = document.baseURI.split('/');
var ind = words.indexOf("proxy"); var ind = words.indexOf("proxy");
if (ind > 0) { var newBaseURI;
var appId = words[ind + 1]; if (ind > 0) {
var newBaseURI = words.slice(0, ind + 2).join('/'); appId = words[ind + 1];
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors"; newBaseURI = words.slice(0, ind + 2).join('/');
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors";
}
ind = words.indexOf("history");
if (ind > 0) {
appId = words[ind + 1];
var attemptId = words[ind + 2];
newBaseURI = words.slice(0, ind).join('/');
if (isNaN(attemptId)) {
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors";
} else {
return newBaseURI + "/api/v1/applications/" + appId + "/" + attemptId + "/allexecutors";
} }
ind = words.indexOf("history"); }
if (ind > 0) { return uiRoot + "/api/v1/applications/" + appId + "/allexecutors";
var appId = words[ind + 1];
var attemptId = words[ind + 2];
var newBaseURI = words.slice(0, ind).join('/');
if (isNaN(attemptId)) {
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors";
} else {
return newBaseURI + "/api/v1/applications/" + appId + "/" + attemptId + "/allexecutors";
}
}
return uiRoot + "/api/v1/applications/" + appId + "/allexecutors";
} }
function createRESTEndPointForMiscellaneousProcess(appId) { function createRESTEndPointForMiscellaneousProcess(appId) {
var words = document.baseURI.split('/'); var words = document.baseURI.split('/');
var ind = words.indexOf("proxy"); var ind = words.indexOf("proxy");
if (ind > 0) { var newBaseURI;
var appId = words[ind + 1]; if (ind > 0) {
var newBaseURI = words.slice(0, ind + 2).join('/'); appId = words[ind + 1];
return newBaseURI + "/api/v1/applications/" + appId + "/allmiscellaneousprocess"; newBaseURI = words.slice(0, ind + 2).join('/');
return newBaseURI + "/api/v1/applications/" + appId + "/allmiscellaneousprocess";
}
ind = words.indexOf("history");
if (ind > 0) {
appId = words[ind + 1];
var attemptId = words[ind + 2];
newBaseURI = words.slice(0, ind).join('/');
if (isNaN(attemptId)) {
return newBaseURI + "/api/v1/applications/" + appId + "/allmiscellaneousprocess";
} else {
return newBaseURI + "/api/v1/applications/" + appId + "/" + attemptId + "/allmiscellaneousprocess";
} }
ind = words.indexOf("history"); }
if (ind > 0) { return uiRoot + "/api/v1/applications/" + appId + "/allmiscellaneousprocess";
var appId = words[ind + 1];
var attemptId = words[ind + 2];
var newBaseURI = words.slice(0, ind).join('/');
if (isNaN(attemptId)) {
return newBaseURI + "/api/v1/applications/" + appId + "/allmiscellaneousprocess";
} else {
return newBaseURI + "/api/v1/applications/" + appId + "/" + attemptId + "/allmiscellaneousprocess";
}
}
return uiRoot + "/api/v1/applications/" + appId + "/allmiscellaneousprocess";
} }
/* eslint-enable no-unused-vars */

View file

@ -15,16 +15,19 @@
* limitations under the License. * limitations under the License.
*/ */
/* global $ */
/* eslint-disable no-unused-vars */
var uiRoot = ""; var uiRoot = "";
var appBasePath = ""; var appBasePath = "";
function setUIRoot(val) { function setUIRoot(val) {
uiRoot = val; uiRoot = val;
} }
function setAppBasePath(path) { function setAppBasePath(path) {
appBasePath = path; appBasePath = path;
} }
/* eslint-enable no-unused-vars */
function collapseTablePageLoad(name, table){ function collapseTablePageLoad(name, table){
if (window.localStorage.getItem(name) == "true") { if (window.localStorage.getItem(name) == "true") {
@ -35,20 +38,20 @@ function collapseTablePageLoad(name, table){
} }
function collapseTable(thisName, table){ function collapseTable(thisName, table){
var status = window.localStorage.getItem(thisName) == "true"; var status = window.localStorage.getItem(thisName) == "true";
status = !status; status = !status;
var thisClass = '.' + thisName; var thisClass = '.' + thisName;
// Expand the list of additional metrics. // Expand the list of additional metrics.
var tableDiv = $(thisClass).parent().find('.' + table); var tableDiv = $(thisClass).parent().find('.' + table);
$(tableDiv).toggleClass('collapsed'); $(tableDiv).toggleClass('collapsed');
// Switch the class of the arrow from open to closed. // Switch the class of the arrow from open to closed.
$(thisClass).find('.collapse-table-arrow').toggleClass('arrow-open'); $(thisClass).find('.collapse-table-arrow').toggleClass('arrow-open');
$(thisClass).find('.collapse-table-arrow').toggleClass('arrow-closed'); $(thisClass).find('.collapse-table-arrow').toggleClass('arrow-closed');
window.localStorage.setItem(thisName, "" + status); window.localStorage.setItem(thisName, "" + status);
} }
// Add a call to collapseTablePageLoad() on each collapsible table // Add a call to collapseTablePageLoad() on each collapsible table
@ -101,8 +104,8 @@ $(function() {
}); });
$(function() { $(function() {
// Show/hide full job description on click event. // Show/hide full job description on click event.
$(".description-input").click(function() { $(".description-input").click(function() {
$(this).toggleClass("description-input-full"); $(this).toggleClass("description-input-full");
}); });
}); });

View file

@ -134,3 +134,4 @@ flights_tiny.txt.1
over1k over1k
over10k over10k
exported_table/* exported_table/*
node_modules

24
dev/eslint.json Normal file
View file

@ -0,0 +1,24 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"rules": {
"indent": [
"error",
2,
{
"SwitchCase": 1,
"MemberExpression": "off"
}
],
"no-unused-vars": ["error", {"argsIgnorePattern": "^_ignored_.*"}]
},
"ignorePatterns": [
"*.min.js",
"sorttable.js",
"jquery.mustache.js",
"dataTables.rowsGroup.js"
]
}

56
dev/lint-js Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set -o pipefail
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
SPARK_ROOT_DIR="$(dirname $SCRIPT_DIR)"
LINT_JS_REPORT_FILE_NAME="$SPARK_ROOT_DIR/dev/lint-js-report.log"
LINT_TARGET_FILES=(
"$SPARK_ROOT_DIR/core/src/main/resources/org/apache/spark/ui/static/"
"$SPARK_ROOT_DIR/sql/core/src/main/resources/org/apache/spark/sql/execution/ui/static/"
"$SPARK_ROOT_DIR/docs/js"
)
if ! type "npm" > /dev/null; then
echo "ERROR: You should install npm"
exit 1
fi
if ! type "npx" > /dev/null; then
echo "ERROR: You should install npx"
exit 1
fi
cd $SCRIPT_DIR
if ! npm ls eslint > /dev/null; then
npm ci eslint
fi
npx eslint -c "$SPARK_ROOT_DIR/dev/eslint.json" $LINT_TARGET_FILES | tee "$LINT_JS_REPORT_FILE_NAME"
lint_status=$?
if [ "$lint_status" = "0" ] ; then
echo "lint-js checks passed."
else
echo "lint-js checks failed."
fi
exit "$lint_status"

979
dev/package-lock.json generated Normal file
View file

@ -0,0 +1,979 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@babel/code-frame": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.4"
}
},
"@babel/helper-validator-identifier": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
"integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
"dev": true
},
"@babel/highlight": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
"integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.14.0",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
},
"dependencies": {
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
}
}
},
"@eslint/eslintrc": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
"integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.1.1",
"espree": "^7.3.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
}
}
},
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
"acorn-jsx": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
"integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
"dev": true
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": 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"
}
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
"astral-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"eslint": {
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.25.0.tgz",
"integrity": "sha512-TVpSovpvCNpLURIScDRB6g5CYu/ZFq9GfX2hLNIV4dSBKxIWojeDODvYl3t0k0VtMxYeR8OXPCFE5+oHMlGfhw==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
"@eslint/eslintrc": "^0.4.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.1",
"eslint-utils": "^2.1.0",
"eslint-visitor-keys": "^2.0.0",
"espree": "^7.3.1",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"file-entry-cache": "^6.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^13.6.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.21",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^3.1.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
"table": "^6.0.4",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
}
},
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
}
},
"eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
}
}
},
"eslint-visitor-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
"dev": true
},
"espree": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
"integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
"dev": true,
"requires": {
"acorn": "^7.4.0",
"acorn-jsx": "^5.3.1",
"eslint-visitor-keys": "^1.3.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
}
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"esquery": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"requires": {
"estraverse": "^5.2.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": 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==",
"dev": 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==",
"dev": true
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"dev": true,
"requires": {
"flat-cache": "^3.0.4"
}
},
"flat-cache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
"dev": true,
"requires": {
"flatted": "^3.1.0",
"rimraf": "^3.0.2"
}
},
"flatted": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"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"
}
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz",
"integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
},
"dependencies": {
"type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true
}
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"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==",
"dev": true
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"dev": true
},
"lodash.flatten": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
"dev": true
},
"lodash.truncate": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
"dev": true
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.3"
}
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0"
}
},
"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=",
"dev": true
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"regexpp": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true
},
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
"dev": true,
"requires": {
"ansi-styles": "^4.0.0",
"astral-regex": "^2.0.0",
"is-fullwidth-code-point": "^3.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
}
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"string-width": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"table": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/table/-/table-6.6.0.tgz",
"integrity": "sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg==",
"dev": true,
"requires": {
"ajv": "^8.0.1",
"lodash.clonedeep": "^4.5.0",
"lodash.flatten": "^4.4.0",
"lodash.truncate": "^4.4.2",
"slice-ansi": "^4.0.0",
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"ajv": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz",
"integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
}
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
}

5
dev/package.json Normal file
View file

@ -0,0 +1,5 @@
{
"devDependencies": {
"eslint": "^7.25.0"
}
}