diff --git a/.eslintrc.js b/.eslintrc.js index 5d15ec385..e79f87a5d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -245,4 +245,5 @@ module.exports = { })), ], ignorePatterns: findGeneratedJS(["apps/", "modules/"]), + reportUnusedDisableDirectives: true, } diff --git a/apps/btadv/app.ts b/apps/btadv/app.ts index b56546ba1..3511cca5d 100644 --- a/apps/btadv/app.ts +++ b/apps/btadv/app.ts @@ -1,6 +1,6 @@ { // @ts-expect-error helper -// eslint-disable-next-line @typescript-eslint/no-unused-vars + const __assign = Object.assign; const Layout = require("Layout"); diff --git a/apps/clkinfogps/geotools.js b/apps/clkinfogps/geotools.js index d251c1f95..2f25c8453 100644 --- a/apps/clkinfogps/geotools.js +++ b/apps/clkinfogps/geotools.js @@ -1,5 +1,5 @@ /** - * + * * A module of Geo functions for use with gps fixes * * let geo = require("geotools"); @@ -71,7 +71,7 @@ OsGridRef.latLongToOsGrid = function(point) { * */ function to_map_ref(digits, easting, northing) { - if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); // eslint-disable-line comma-spacing + if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); let e = easting; let n = northing; @@ -108,7 +108,7 @@ function to_map_ref(digits, easting, northing) { } /** - * + * * Module exports section, example code below * * let geo = require("geotools"); diff --git a/apps/gipy/pkg/gps.d.ts b/apps/gipy/pkg/gps.d.ts index 9ad646068..6e2c14f5a 100644 --- a/apps/gipy/pkg/gps.d.ts +++ b/apps/gipy/pkg/gps.d.ts @@ -1,5 +1,5 @@ /* tslint:disable */ -/* eslint-disable */ + /** * @param {Gps} gps */ diff --git a/apps/gipy/pkg/gps_bg.wasm.d.ts b/apps/gipy/pkg/gps_bg.wasm.d.ts index 251d9c3b1..5b84a9229 100644 --- a/apps/gipy/pkg/gps_bg.wasm.d.ts +++ b/apps/gipy/pkg/gps_bg.wasm.d.ts @@ -1,5 +1,5 @@ /* tslint:disable */ -/* eslint-disable */ + export const memory: WebAssembly.Memory; export function __wbg_gps_free(a: number): void; export function disable_elevation(a: number): void; diff --git a/apps/gpstouch/geotools.js b/apps/gpstouch/geotools.js index 5adc57872..93fcc1fdc 100644 --- a/apps/gpstouch/geotools.js +++ b/apps/gpstouch/geotools.js @@ -1,5 +1,5 @@ /** - * + * * A module of Geo functions for use with gps fixes * * let geo = require("geotools"); @@ -71,7 +71,7 @@ OsGridRef.latLongToOsGrid = function(point) { * */ function to_map_ref(digits, easting, northing) { - if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); // eslint-disable-line comma-spacing + if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); let e = easting; let n = northing; @@ -108,7 +108,7 @@ function to_map_ref(digits, easting, northing) { } /** - * + * * Module exports section, example code below * * let geo = require("geotools"); diff --git a/apps/kitchen/kitchen.app.js b/apps/kitchen/kitchen.app.js index 2c2cebaef..1d3d70a1f 100644 --- a/apps/kitchen/kitchen.app.js +++ b/apps/kitchen/kitchen.app.js @@ -463,7 +463,7 @@ OsGridRef.latLongToOsGrid = function(point) { * */ function to_map_ref(digits, easting, northing) { - if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); // eslint-disable-line comma-spacing + if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); let e = easting; let n = northing; diff --git a/apps/lint_exemptions.js b/apps/lint_exemptions.js index 055e3e1dc..e5a2170bd 100644 --- a/apps/lint_exemptions.js +++ b/apps/lint_exemptions.js @@ -926,7 +926,7 @@ module.exports = { ] }, "apps/kitchen/kitchen.app.js": { - "hash": "1ef7b31e52110e34fb952d7ba0426c8bd9574e5f18be9fbc3b8ad1cc762dda21", + "hash": "cea726937a7179851091b0728d3ad1e773eac703a5bfdc28be6e2f247fdd44c9", "rules": [ "no-undef" ] @@ -1004,7 +1004,7 @@ module.exports = { ] }, "apps/gpstouch/geotools.js": { - "hash": "5816fbb2dd630f574e5ee505e1b9ec6f80c3c53778b7a5520e5db28b91cdffc5", + "hash": "7e67733286f9d7708a54814f6f27d73ddffed2f433febc9604138f2f7a832cbf", "rules": [ "no-undef" ] @@ -1314,7 +1314,7 @@ module.exports = { ] }, "apps/schoolCalendar/fullcalendar/main.js": { - "hash": "04dcd3cb3025c7aa67631d287b025a897b1cd984b8ea306abae2d722976fb7c5", + "hash": "8c417deb073328655117a93f045e77e9b808e84d584e648c6d7e360271ae8d07", "rules": [ "no-undef", "no-unused-vars", diff --git a/apps/measuretime/ChangeLog b/apps/measuretime/ChangeLog new file mode 100644 index 000000000..81fba8e15 --- /dev/null +++ b/apps/measuretime/ChangeLog @@ -0,0 +1 @@ +0.1: Initial release \ No newline at end of file diff --git a/apps/measuretime/README.md b/apps/measuretime/README.md new file mode 100644 index 000000000..78d04f30d --- /dev/null +++ b/apps/measuretime/README.md @@ -0,0 +1,7 @@ +# Measure Time + +Measure time in a fancy way. Inspired by a Watchface I had on my first Pebble Watch. + +Written by [prefectAtEarth](https://www.github.com/prefectAtEarth/) + +![](measuretime.png) \ No newline at end of file diff --git a/apps/measuretime/measuretime-icon.js b/apps/measuretime/measuretime-icon.js new file mode 100644 index 000000000..4592548a7 --- /dev/null +++ b/apps/measuretime/measuretime-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4n/AAIHB/fe8EHrvv333xVS221jnnlFC7//9NP997zXWjHGn+EGJsu9wAC0AHBgugq99C5d0kUq1WtoAHBgnaw8nC5d9mdwgEN7QHBxvQ5nhGwQXNiQHB19A41xC5dy3YXCwAHBwkqx3tI5d3AAV8L4UIDYRkBogADpTOQhWqAAZOLAAuoxAABfyYXXI4pKRO4oACqBHl0QXWAC8IF4QABwpHRkUilALHgutvwvMBY8NoEHKakCqtHR5gAH1FY7wUFcYS/LI5Fwd4r7IqXuJ4uUAYMK1QABKhEKIAQAC1kW7SnDAAUlPxnBiN9xEnu93vx6KAAeHyMdI5wAGox3OS5GAU4oAEoAXJhTXGfigAWhAvWX6QvcT5nog5HJF5QXLX5AAC0levwXId5cNoAvJhWqAAILHgVAhxHMQaZfFwoXQI5YALO5ZHPC6bXDAAmADqYARhBHXkUilC/oA=")) \ No newline at end of file diff --git a/apps/measuretime/measuretime.app.js b/apps/measuretime/measuretime.app.js new file mode 100644 index 000000000..c7865bffe --- /dev/null +++ b/apps/measuretime/measuretime.app.js @@ -0,0 +1,180 @@ +{ + require("Font7x11Numeric7Seg").add(Graphics); + g.setFont("7x11Numeric7Seg"); + g.setFontAlign(0, 0); + + const centerY = g.getHeight() / 2; //88 + const lineStart = 25; + const lineEndFull = 110; + const lineEndHalf = 90; + const lineEndQuarter = 70; + const lineEndDefault = 50; + + let drawTimeout; + + let queueDrawTime = function () { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function () { + drawTimeout = undefined; + drawTime(); + }, 60000 - (Date.now() % 60000)); + }; + + let drawCenterLine = function () { + // center line + g.drawLineAA(0, centerY, g.getWidth(), centerY); + // left decoration + var steps = [0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + var stepsReversed = steps.slice(); + stepsReversed.reverse(); + var polyLeftTop = []; + var polyLeftBottom = []; + var polyRightTop = []; + var polyRightBottom = []; + let xL = 0; + let xR = g.getWidth() - 1; + let yT = centerY - 13; + let yB = centerY + 13; + + for (let i = 0; i < steps.length; i++) { + xL += steps[i]; + xR -= steps[i]; + yT += stepsReversed[i]; + yB -= stepsReversed[i]; + + // Left Top + polyLeftTop.push(xL); + polyLeftTop.push(yT); + + // Left Bottom + polyLeftBottom.push(xL); + polyLeftBottom.push(yB); + + // Right Top + polyRightTop.push(xR); + polyRightTop.push(yT); + + // Right Bottom + polyRightBottom.push(xR); + polyRightBottom.push(yB); + } + + polyLeftTop.push(0, 88); + polyLeftBottom.push(0, 88); + polyRightTop.push(g.getWidth(), 88); + polyRightBottom.push(g.getWidth(), 88); + + g.fillPolyAA(polyLeftTop, true); + g.fillPolyAA(polyLeftBottom, true); + g.fillPolyAA(polyRightTop, true); + g.fillPolyAA(polyRightBottom, true); + }; + + let drawTime = function () { + g.clear(); + var d = new Date(); + var mins = d.getMinutes(); + + var offset = mins % 5; + var yTopLines = centerY - offset; + var topReached = false; + + var yBottomLines = centerY - offset + 5; + var bottomReached = false; + + drawCenterLine(); + + var lineEnd = lineEndDefault; + g.setFont("7x11Numeric7Seg", 2); + g.setFontAlign(0, 0); + + // gone + do { + switch (yTopLines - 88 + mins) { + case -60: + lineEnd = lineEndFull; + g.drawString(d.getHours() - 1, lineEnd + 10, yTopLines, true); + break; + case 0: + case 60: + lineEnd = lineEndFull; + g.drawString(d.getHours(), lineEnd + 10, yTopLines, true); + break; + case 45: + case -45: + case 15: + case -15: + case -75: + lineEnd = lineEndQuarter; + break; + case 30: + case -30: + lineEnd = lineEndHalf; + break; + default: + lineEnd = lineEndDefault; + } + g.drawLineAA(lineStart, yTopLines, lineEnd, yTopLines); + + yTopLines -= 5; + if (yTopLines < -4) { + topReached = true; + } + } while (!topReached); + + // upcoming + do { + switch (yBottomLines - 88 + mins) { + case 0: + case 60: + lineEnd = lineEndFull; + g.drawString(d.getHours() + 1, lineEnd + 10, yBottomLines, true); + break; + case 120: + lineEnd = lineEndFull; + g.drawString(d.getHours() + 2, lineEnd + 10, yBottomLines, true); + break; + case 15: + case 75: + case 135: + case 45: + case 105: + case 165: + lineEnd = lineEndQuarter; + break; + case 30: + case 90: + case 150: + lineEnd = lineEndHalf; + break; + default: + lineEnd = lineEndDefault; + } + g.drawLineAA(lineStart, yBottomLines, lineEnd, yBottomLines); + + yBottomLines += 5; + if (yBottomLines > 176) { + bottomReached = true; + } + } while (!bottomReached); + + queueDrawTime(); + }; + + + g.clear(); + drawTime(); + + Bangle.setUI( + { + mode: "clock", + remove: function () { + if (drawTimeout) clearTimeout(drawTimeout); + require("widget_utils").show(); + } + } + ); + + Bangle.loadWidgets(); + require("widget_utils").swipeOn(); +} diff --git a/apps/measuretime/measuretime.png b/apps/measuretime/measuretime.png new file mode 100644 index 000000000..67425e1dc Binary files /dev/null and b/apps/measuretime/measuretime.png differ diff --git a/apps/measuretime/metadata.json b/apps/measuretime/metadata.json new file mode 100644 index 000000000..4c0db8b32 --- /dev/null +++ b/apps/measuretime/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "measuretime", + "name": "Measure Time", + "version": "0.1", + "description": "Measure Time in a fancy way.", + "icon": "small_measuretime.png", + "screenshots": [{ "url": "measuretime.png" }], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + { "name": "measuretime.app.js", "url": "measuretime.app.js" }, + { "name": "measuretime.img", "url": "measuretime-icon.js", "evaluate": true } + ] +} diff --git a/apps/measuretime/small_measuretime.png b/apps/measuretime/small_measuretime.png new file mode 100644 index 000000000..74f476dad Binary files /dev/null and b/apps/measuretime/small_measuretime.png differ diff --git a/apps/measuretime/test.json b/apps/measuretime/test.json new file mode 100644 index 000000000..1b4123411 --- /dev/null +++ b/apps/measuretime/test.json @@ -0,0 +1,15 @@ +{ + "app" : "measuretime", + "tests" : [{ + "description": "Check memory usage after setUI", + "steps" : [ + {"t":"cmd", "js": "Bangle.loadWidgets()"}, + {"t":"cmd", "js": "eval(require('Storage').read('measuretime.app.js'))"}, + {"t":"cmd", "js": "Bangle.setUI()"}, + {"t":"saveMemoryUsage"}, + {"t":"cmd", "js": "eval(require('Storage').read('measuretime.app.js'))"}, + {"t":"cmd", "js":"Bangle.setUI()"}, + {"t":"checkMemoryUsage"} + ] + }] +} diff --git a/apps/schoolCalendar/fullcalendar/main.js b/apps/schoolCalendar/fullcalendar/main.js index 95650f472..a41e45c67 100644 --- a/apps/schoolCalendar/fullcalendar/main.js +++ b/apps/schoolCalendar/fullcalendar/main.js @@ -111,7 +111,7 @@ var FullCalendar = (function (exports) { ContextType.Provider = function () { var _this = this; var isNew = !this.getChildContext; - var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params + var children = origProvider.apply(this, arguments); if (isNew) { var subs_1 = []; this.shouldComponentUpdate = function (_props) { @@ -4688,14 +4688,14 @@ var FullCalendar = (function (exports) { var wrappedSuccess = function () { if (!isResolved) { isResolved = true; - success.apply(this, arguments); // eslint-disable-line prefer-rest-params + success.apply(this, arguments); } }; var wrappedFailure = function () { if (!isResolved) { isResolved = true; if (failure) { - failure.apply(this, arguments); // eslint-disable-line prefer-rest-params + failure.apply(this, arguments); } } }; @@ -5008,7 +5008,7 @@ var FullCalendar = (function (exports) { var createPortal = FullCalendarVDom.createPortal; var flushToDom = FullCalendarVDom.flushToDom; var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode; - /* eslint-enable */ + var ScrollResponder = /** @class */ (function () { function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) { @@ -5085,7 +5085,7 @@ var FullCalendar = (function (exports) { } PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) { if (this.debug) { - // eslint-disable-next-line no-console + console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state)); } return !compareObjs(this.props, nextProps, this.propEquality) || @@ -6613,7 +6613,7 @@ var FullCalendar = (function (exports) { var endMarker = framingRange.end; var instanceStarts = []; while (dayMarker < endMarker) { - var instanceStart + var instanceStart // if everyday, or this particular day-of-week = void 0; // if everyday, or this particular day-of-week @@ -11731,7 +11731,7 @@ var FullCalendar = (function (exports) { } dragging.emitter.on('pointerdown', this.handlePointerDown); dragging.emitter.on('dragstart', this.handleDragStart); - new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new + new ExternalElementDragging(dragging, settings.eventData); } ExternalDraggable.prototype.destroy = function () { this.dragging.destroy(); @@ -11833,7 +11833,7 @@ var FullCalendar = (function (exports) { if (typeof settings.mirrorSelector === 'string') { dragging.mirrorSelector = settings.mirrorSelector; } - new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new + new ExternalElementDragging(dragging, settings.eventData); } ThirdPartyDraggable.prototype.destroy = function () { this.dragging.destroy(); @@ -13605,7 +13605,7 @@ var FullCalendar = (function (exports) { if (!slatCoords) { return null; } - return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, + return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, // key doesn't matter. will only ever be one key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); }); }; diff --git a/apps/walkersclock/app.js b/apps/walkersclock/app.js index 5b83bf583..f78be61ca 100644 --- a/apps/walkersclock/app.js +++ b/apps/walkersclock/app.js @@ -8,7 +8,7 @@ * - two function menus at present * GPS Power = On/Off * GPS Display = Grid | Speed Alt - * when the modeline in CYAN use button BTN1 to switch between options + * when the modeline in CYAN use button BTN1 to switch between options * - display the current steps if one of the steps widgets is installed * - ensures that BTN2 requires a 1.5 second press in order to switch to the launcher * this is so you dont accidently switch out of the GPS/watch display with you coat sleeve @@ -65,14 +65,14 @@ let last_fix = { satellites: 0 }; -function drawTime() { +function drawTime() { var d = new Date(); var da = d.toString().split(" "); var time = da[4].substr(0,5); g.reset(); g.clearRect(0,Y_TIME, 239, Y_ACTIVITY - 1); - + g.setColor(1,1,1); // white g.setFontAlign(0, -1); @@ -83,7 +83,7 @@ function drawTime() { } else { g.setFont("Vector", 80); } - + g.drawString(time, g.getWidth()/2, Y_TIME); } @@ -93,19 +93,19 @@ function drawActivity() { clearActivityArea = true; prevSteps = steps; - + if (clearActivityArea) { g.clearRect(0, Y_ACTIVITY, 239, Y_MODELINE - 1); clearActivityArea = false; } - + if (!gpsPowerState) { g.setColor(0,255,0); // green g.setFont("Vector", 60); g.drawString(getSteps(), g.getWidth()/2, Y_ACTIVITY); return; } - + g.setFont("6x8", 3); g.setColor(1,1,1); g.setFontAlign(0, -1); @@ -130,10 +130,10 @@ function drawActivity() { let ref = to_map_ref(6, os.easting, os.northing); let speed; let activityStr = ""; - + if (age < 0) age = 0; g.setFontVector(40); - g.setColor(0xFFC0); + g.setColor(0xFFC0); switch(gpsDisplay) { case GDISP_OS: @@ -146,7 +146,7 @@ function drawActivity() { case GDISP_SPEED: speed = last_fix.speed; speed = speed.toFixed(1); - activityStr = speed + "kph"; + activityStr = speed + "kph"; break; case GDISP_ALT: activityStr = last_fix.alt + "m"; @@ -159,7 +159,7 @@ function drawActivity() { g.clearRect(0, Y_ACTIVITY, 239, Y_MODELINE - 1); g.drawString(activityStr, 120, Y_ACTIVITY); g.setFont("6x8",2); - g.setColor(1,1,1); + g.setColor(1,1,1); g.drawString(age, 120, Y_ACTIVITY + 46); } } @@ -167,7 +167,7 @@ function drawActivity() { function onTick() { if (!Bangle.isLCDOn()) return; - + if (gpsPowerState) { drawAll(); return; @@ -226,7 +226,7 @@ function drawInfo() { drawModeLine(str,col); return; } - + switch(infoMode) { case INFO_NONE: col = 0x0000; @@ -239,7 +239,7 @@ function drawInfo() { default: str = "Battery: " + E.getBattery() + "%"; } - + drawModeLine(str,col); } @@ -283,7 +283,7 @@ function changeInfoMode() { infoMode = INFO_NONE; clearActivityArea = true; return; - + case FN_MODE_GDISP: switch (gpsDisplay) { case GDISP_OS: @@ -304,7 +304,7 @@ function changeInfoMode() { break; } } - + switch(infoMode) { case INFO_NONE: if (stepsWidget() !== undefined) @@ -319,7 +319,7 @@ function changeInfoMode() { default: infoMode = INFO_NONE; } - + clearActivityArea = true; } @@ -351,7 +351,7 @@ function changeFunctionMode() { break; } } - + infoMode = INFO_NONE; // function mode overrides info mode } @@ -374,7 +374,7 @@ function processFix(fix) { gpsState = GPS_SATS; clearActivityArea = true; } - + if (fix.fix) { if (!last_fix.fix) { if (!(require('Storage').readJSON('setting.json',1)||{}).quiet) { @@ -401,7 +401,7 @@ function stepsWidget() { } return undefined; } - + /************* GPS / OSREF Code **************************/ @@ -413,10 +413,10 @@ function formatTime(now) { function timeSince(t) { var hms = t.split(":"); var now = new Date(); - + var sn = 3600*(now.getHours()) + 60*(now.getMinutes()) + 1*(now.getSeconds()); var st = 3600*(hms[0]) + 60*(hms[1]) + 1*(hms[2]); - + return (sn - st); } @@ -483,7 +483,7 @@ OsGridRef.latLongToOsGrid = function(point) { * */ function to_map_ref(digits, easting, northing) { - if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); // eslint-disable-line comma-spacing + if (![ 0,2,4,6,8,10,12,14,16 ].includes(Number(digits))) throw new RangeError(`invalid precision '${digits}'`); let e = easting; let n = northing; diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index e32ab36ba..728c934ea 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -1,4 +1,4 @@ -/* eslint-disable no-undef */ + const Setter = { NONE: "none", UPPER: 'upper', @@ -31,7 +31,7 @@ const upperLshape = isB1 ? { left: 210, bottom: 40, top: 210, - rectWidth: 30, + rectWidth: 30, cornerRoundness: 5, orientation: -1, color: '#f00' @@ -62,7 +62,7 @@ const centerBar = { minY: (upperLshape.bottom + upperLshape.top - (upperLshape.rectWidth*1.5))/2, maxY: (upperLshape.bottom + upperLshape.top + (upperLshape.rectWidth*1.5))/2, confidenceWidth: isB1 ? 10 : 8, - minX: isB1 ? 55 : upperLshape.rectWidth + 14, + minX: isB1 ? 55 : upperLshape.rectWidth + 14, maxX: isB1 ? 165 : Bangle.appRect.x2 - upperLshape.rectWidth - 14 }; diff --git a/package.json b/package.json index 619a4c482..57ecf5201 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "npm-watch": "^0.11.0" }, "scripts": { - "lint-apps": "node bin/sync-lint-exemptions.mjs && eslint ./apps", - "lint-modules": "eslint ./modules", + "lint-apps": "node bin/sync-lint-exemptions.mjs && eslint --max-warnings 0 ./apps", + "lint-modules": "eslint --max-warnings 0 ./modules", "test": "node bin/sanitycheck.js && npm run lint-apps && npm run lint-modules", "fix": "eslint --fix ./apps ./modules", "update-local-apps": "./bin/create_apps_json.sh apps.local.json",