Working on linter configurations (#3839)

* Fix different project configs

* Sorted out all eslint configurations

* Return package-lock file created with npm 7 (just in case of compatibility issues), prev was 8

* Changed based image to lts slim
main
Boris Sekachev 4 years ago committed by GitHub
parent b57467937a
commit 7bf415412a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
module.exports = { module.exports = {
root: true,
env: { env: {
node: true, node: true,
browser: true, browser: true,
@ -12,12 +13,43 @@ module.exports = {
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2018, ecmaVersion: 2018,
}, },
plugins: ['eslint-plugin-header'], ignorePatterns: [
extends: ['eslint:recommended', 'prettier'], '.eslintrc.js',
'lint-staged.config.js',
],
plugins: ['security', 'no-unsanitized', 'eslint-plugin-header', 'import'],
extends: [
'eslint:recommended', 'plugin:security/recommended', 'plugin:no-unsanitized/DOM',
'airbnb-base', 'plugin:import/errors', 'plugin:import/warnings',
'plugin:import/typescript',
],
rules: { rules: {
'header/header': [2, 'line', [{ 'header/header': [2, 'line', [{
pattern: ' {1}Copyright \\(C\\) (?:20\\d{2}-)?2021 Intel Corporation', pattern: ' {1}Copyright \\(C\\) (?:20\\d{2}-)?2021 Intel Corporation',
template: ' Copyright (C) 2021 Intel Corporation' template: ' Copyright (C) 2021 Intel Corporation'
}, '', ' SPDX-License-Identifier: MIT']], }, '', ' SPDX-License-Identifier: MIT']],
'no-plusplus': 0,
'no-continue': 0,
'no-console': 0,
'no-param-reassign': ['error', { 'props': false }],
'no-restricted-syntax': [0, { selector: 'ForOfStatement' }],
'no-await-in-loop': 0,
'indent': ['error', 4, { 'SwitchCase': 1 }],
'max-len': ['error', { code: 120, ignoreStrings: true }],
'func-names': 0,
'valid-typeof': 0,
'no-useless-constructor': 0, // sometimes constructor is necessary to generate right documentation in cvat-core
'quotes': ['error', 'single'],
'lines-between-class-members': 0,
'class-methods-use-this': 0,
'no-underscore-dangle': ['error', { allowAfterThis: true }],
'max-classes-per-file': 0,
'operator-linebreak': ['error', 'after'],
'newline-per-chained-call': 0,
'global-require': 0,
'arrow-parens': ['error', 'always'],
'security/detect-object-injection': 0, // the rule is relevant for user input data on the node.js environment
'import/order': ['error', {'groups': ['builtin', 'external', 'internal']}],
'import/prefer-default-export': 0, // works incorrect with interfaces
}, },
}; };

24
.gitignore vendored

@ -10,7 +10,6 @@
/profiles /profiles
/ssh/* /ssh/*
!/ssh/README.md !/ssh/README.md
node_modules
/Mask_RCNN/ /Mask_RCNN/
/letsencrypt-webroot/ /letsencrypt-webroot/
@ -21,9 +20,6 @@ __pycache__
._* ._*
.coverage .coverage
# Ignore development npm files
node_modules
# Ignore npm logs file # Ignore npm logs file
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
@ -46,4 +42,22 @@ yarn-error.log*
/site/public/ /site/public/
/site/resources/ /site/resources/
/site/node_modules/ /site/node_modules/
/site/tech-doc-hugo /site/tech-doc-hugo
# Ignore all the installed packages
node_modules
# Ignore all js dists
cvat-data/dist
cvat-core/dist
cvat-canvas/dist
cvat-canvas3d/dist
cvat-ui/dist
# produced by npm run docs in cvat-core
cvat-core/docs
# produced by npm run test in cvat-core
cvat-core/reports
# produced by prepare in the root package.json script
.husky

@ -1,4 +1,4 @@
FROM node:stretch AS cvat-ui FROM node:lts-slim AS cvat-ui
ARG http_proxy ARG http_proxy
ARG https_proxy ARG https_proxy

@ -2,48 +2,44 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
const globalConfig = require('../.eslintrc.js');
module.exports = { module.exports = {
env: { env: {
node: true, node: true,
}, },
ignorePatterns: [
'.eslintrc.js',
'webpack.config.js',
'node_modules/**',
'dist/**',
],
parserOptions: { parserOptions: {
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
ecmaVersion: 6, ecmaVersion: 6,
project: './tsconfig.json', project: './tsconfig.json',
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
}, },
plugins: ['@typescript-eslint', 'import'], plugins: ['@typescript-eslint'],
extends: [ extends: ['plugin:@typescript-eslint/recommended', 'airbnb-typescript/base'],
'plugin:@typescript-eslint/recommended',
'airbnb-typescript/base',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
],
ignorePatterns: ['.eslintrc.js'],
rules: { rules: {
...globalConfig.rules,
'@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/indent': ['warn', 4], '@typescript-eslint/indent': ['error', 4],
'no-plusplus': 0, '@typescript-eslint/lines-between-class-members': 0,
'no-restricted-syntax': [ '@typescript-eslint/no-explicit-any': [0],
0, '@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-types': [
'error',
{ {
selector: 'ForOfStatement', types: {
'{}': false, // TODO: try to fix with Record<string, unknown>
object: false, // TODO: try to fix with Record<string, unknown>
Function: false, // TODO: try to fix somehow
},
}, },
], ],
'max-len': ['error', { code: 120 }],
'no-continue': 0,
'func-names': 0,
'no-console': 0, // this rule deprecates console.log, console.warn etc. because 'it is not good in production code'
'lines-between-class-members': 0,
'import/prefer-default-export': 0, // works incorrect with interfaces
'newline-per-chained-call': 0, // makes code uglier
},
settings: {
'import/resolver': {
node: {
extensions: ['.ts', '.js', '.json'],
},
},
}, },
}; };

@ -1 +0,0 @@
dist

@ -172,9 +172,9 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
} else { } else {
// sign defines bypass direction // sign defines bypass direction
const landmarks = this.auxiliaryClicks; const landmarks = this.auxiliaryClicks;
const sign = Math.sign(landmarks[2] - landmarks[0]) const sign = Math.sign(landmarks[2] - landmarks[0]) *
* Math.sign(landmarks[1] - landmarks[0]) Math.sign(landmarks[1] - landmarks[0]) *
* Math.sign(landmarks[2] - landmarks[1]); Math.sign(landmarks[2] - landmarks[1]);
// go via a polygon and get vertices // go via a polygon and get vertices
// the first vertex has been already drawn // the first vertex has been already drawn
@ -198,10 +198,10 @@ export class AutoborderHandlerImpl implements AutoborderHandler {
// remove the latest cursor position from drawing array // remove the latest cursor position from drawing array
for (const wayPoint of way) { for (const wayPoint of way) {
const [_x, _y] = wayPoint const [pX, pY] = wayPoint
.split(',') .split(',')
.map((coordinate: string): number => +coordinate); .map((coordinate: string): number => +coordinate);
this.addPointToCurrentShape(_x, _y); this.addPointToCurrentShape(pX, pY);
} }
this.resetAuxiliaryShape(); this.resetAuxiliaryShape();

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -108,7 +108,7 @@ class CanvasImpl implements Canvas {
this.model.rotate(rotationAngle); this.model.rotate(rotationAngle);
} }
public focus(clientID: number, padding: number = 0): void { public focus(clientID: number, padding = 0): void {
this.model.focus(clientID, padding); this.model.focus(clientID, padding);
} }

@ -675,8 +675,8 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
} }
public isAbleToChangeFrame(): boolean { public isAbleToChangeFrame(): boolean {
const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode) const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode) ||
|| (this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number'); (this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number');
return !isUnable; return !isUnable;
} }

@ -164,8 +164,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
private onInteraction( private onInteraction(
shapes: InteractionResult[] | null, shapes: InteractionResult[] | null,
shapesUpdated: boolean = true, shapesUpdated = true,
isDone: boolean = false, isDone = false,
threshold: number | null = null, threshold: number | null = null,
): void { ): void {
const { zLayer } = this.controller; const { zLayer } = this.controller;
@ -514,8 +514,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Transform all text // Transform all text
for (const key in this.svgShapes) { for (const key in this.svgShapes) {
if ( if (
Object.prototype.hasOwnProperty.call(this.svgShapes, key) Object.prototype.hasOwnProperty.call(this.svgShapes, key) &&
&& Object.prototype.hasOwnProperty.call(this.svgTexts, key) Object.prototype.hasOwnProperty.call(this.svgTexts, key)
) { ) {
this.updateTextPosition(this.svgTexts[key], this.svgShapes[key]); this.updateTextPosition(this.svgTexts[key], this.svgShapes[key]);
} }
@ -740,9 +740,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
private selectize(value: boolean, shape: SVG.Element): void { private selectize(value: boolean, shape: SVG.Element): void {
const self = this; const mousedownHandler = (e: MouseEvent): void => {
function mousedownHandler(e: MouseEvent): void {
if (e.button !== 0) return; if (e.button !== 0) return;
e.preventDefault(); e.preventDefault();
@ -751,26 +749,26 @@ export class CanvasViewImpl implements CanvasView, Listener {
e.target, e.target,
); );
if (self.activeElement.clientID !== null) { if (this.activeElement.clientID !== null) {
const [state] = self.controller.objects.filter( const [state] = this.controller.objects.filter(
(_state: any): boolean => _state.clientID === self.activeElement.clientID, (_state: any): boolean => _state.clientID === this.activeElement.clientID,
); );
if (['polygon', 'polyline', 'points'].includes(state.shapeType)) { if (['polygon', 'polyline', 'points'].includes(state.shapeType)) {
if (e.altKey) { if (e.altKey) {
const { points } = state; const { points } = state;
self.onEditDone(state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2))); this.onEditDone(state, points.slice(0, pointID * 2).concat(points.slice(pointID * 2 + 2)));
} else if (e.shiftKey) { } else if (e.shiftKey) {
self.canvas.dispatchEvent( this.canvas.dispatchEvent(
new CustomEvent('canvas.editstart', { new CustomEvent('canvas.editstart', {
bubbles: false, bubbles: false,
cancelable: true, cancelable: true,
}), }),
); );
self.mode = Mode.EDIT; this.mode = Mode.EDIT;
self.deactivate(); this.deactivate();
self.editHandler.edit({ this.editHandler.edit({
enabled: true, enabled: true,
state, state,
pointID, pointID,
@ -778,37 +776,37 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
} }
} }
} };
function dblClickHandler(e: MouseEvent): void { const dblClickHandler = (e: MouseEvent): void => {
e.preventDefault(); e.preventDefault();
if (self.activeElement.clientID !== null) { if (this.activeElement.clientID !== null) {
const [state] = self.controller.objects.filter( const [state] = this.controller.objects.filter(
(_state: any): boolean => _state.clientID === self.activeElement.clientID, (_state: any): boolean => _state.clientID === this.activeElement.clientID,
); );
if (state.shapeType === 'cuboid') { if (state.shapeType === 'cuboid') {
if (e.shiftKey) { if (e.shiftKey) {
const points = self.translateFromCanvas( const points = this.translateFromCanvas(
pointsToNumberArray((e.target as any).parentElement.parentElement.instance.attr('points')), pointsToNumberArray((e.target as any).parentElement.parentElement.instance.attr('points')),
); );
self.onEditDone(state, points); this.onEditDone(state, points);
} }
} }
} }
} };
function contextMenuHandler(e: MouseEvent): void { const contextMenuHandler = (e: MouseEvent): void => {
const pointID = Array.prototype.indexOf.call( const pointID = Array.prototype.indexOf.call(
((e.target as HTMLElement).parentElement as HTMLElement).children, ((e.target as HTMLElement).parentElement as HTMLElement).children,
e.target, e.target,
); );
if (self.activeElement.clientID !== null) { if (this.activeElement.clientID !== null) {
const [state] = self.controller.objects.filter( const [state] = this.controller.objects.filter(
(_state: any): boolean => _state.clientID === self.activeElement.clientID, (_state: any): boolean => _state.clientID === this.activeElement.clientID,
); );
self.canvas.dispatchEvent( this.canvas.dispatchEvent(
new CustomEvent('canvas.contextmenu', { new CustomEvent('canvas.contextmenu', {
bubbles: false, bubbles: false,
cancelable: true, cancelable: true,
@ -821,12 +819,14 @@ export class CanvasViewImpl implements CanvasView, Listener {
); );
} }
e.preventDefault(); e.preventDefault();
} };
const getGeometry = (): Geometry => this.geometry;
if (value) { if (value) {
(shape as any).selectize(value, { (shape as any).selectize(value, {
deepSelect: true, deepSelect: true,
pointSize: (2 * consts.BASE_POINT_SIZE) / self.geometry.scale, pointSize: (2 * consts.BASE_POINT_SIZE) / this.geometry.scale,
rotationPoint: false, rotationPoint: false,
pointType(cx: number, cy: number): SVG.Circle { pointType(cx: number, cy: number): SVG.Circle {
const circle: SVG.Circle = this.nested const circle: SVG.Circle = this.nested
@ -836,12 +836,12 @@ export class CanvasViewImpl implements CanvasView, Listener {
.center(cx, cy) .center(cx, cy)
.attr({ .attr({
'fill-opacity': 1, 'fill-opacity': 1,
'stroke-width': consts.POINTS_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_STROKE_WIDTH / getGeometry().scale,
}); });
circle.on('mouseenter', (): void => { circle.on('mouseenter', (): void => {
circle.attr({ circle.attr({
'stroke-width': consts.POINTS_SELECTED_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_SELECTED_STROKE_WIDTH / getGeometry().scale,
}); });
circle.on('dblclick', dblClickHandler); circle.on('dblclick', dblClickHandler);
@ -852,7 +852,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
circle.on('mouseleave', (): void => { circle.on('mouseleave', (): void => {
circle.attr({ circle.attr({
'stroke-width': consts.POINTS_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_STROKE_WIDTH / getGeometry().scale,
}); });
circle.off('dblclick', dblClickHandler); circle.off('dblclick', dblClickHandler);
@ -989,8 +989,6 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.canvas.appendChild(this.content); this.canvas.appendChild(this.content);
this.canvas.appendChild(this.attachmentBoard); this.canvas.appendChild(this.attachmentBoard);
const self = this;
// Setup API handlers // Setup API handlers
this.autoborderHandler = new AutoborderHandlerImpl(this.content); this.autoborderHandler = new AutoborderHandlerImpl(this.content);
this.drawHandler = new DrawHandlerImpl( this.drawHandler = new DrawHandlerImpl(
@ -1033,25 +1031,24 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Setup event handlers // Setup event handlers
this.content.addEventListener('dblclick', (e: MouseEvent): void => { this.content.addEventListener('dblclick', (e: MouseEvent): void => {
self.controller.fit(); this.controller.fit();
e.preventDefault(); e.preventDefault();
}); });
this.content.addEventListener('mousedown', (event): void => { this.content.addEventListener('mousedown', (event): void => {
if ([0, 1].includes(event.button)) { if ([0, 1].includes(event.button)) {
if ( if (
[Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT].includes(this.mode) [Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT]
|| event.button === 1 .includes(this.mode) || event.button === 1 || event.altKey
|| event.altKey
) { ) {
self.controller.enableDrag(event.clientX, event.clientY); this.controller.enableDrag(event.clientX, event.clientY);
} }
} }
}); });
window.document.addEventListener('mouseup', (event): void => { window.document.addEventListener('mouseup', (event): void => {
if (event.which === 1 || event.which === 2) { if (event.which === 1 || event.which === 2) {
self.controller.disableDrag(); this.controller.disableDrag();
} }
}); });
@ -1059,7 +1056,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
if (event.ctrlKey) return; if (event.ctrlKey) return;
const { offset } = this.controller.geometry; const { offset } = this.controller.geometry;
const point = translateToSVG(this.content, [event.clientX, event.clientY]); const point = translateToSVG(this.content, [event.clientX, event.clientY]);
self.controller.zoom(point[0] - offset, point[1] - offset, event.deltaY > 0 ? -1 : 1); this.controller.zoom(point[0] - offset, point[1] - offset, event.deltaY > 0 ? -1 : 1);
this.canvas.dispatchEvent( this.canvas.dispatchEvent(
new CustomEvent('canvas.zoom', { new CustomEvent('canvas.zoom', {
bubbles: false, bubbles: false,
@ -1070,7 +1067,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
}); });
this.content.addEventListener('mousemove', (e): void => { this.content.addEventListener('mousemove', (e): void => {
self.controller.drag(e.clientX, e.clientY); this.controller.drag(e.clientX, e.clientY);
if (this.mode !== Mode.IDLE) return; if (this.mode !== Mode.IDLE) return;
if (e.ctrlKey || e.altKey) return; if (e.ctrlKey || e.altKey) return;
@ -1517,8 +1514,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
if ( if (
state.points.length !== drawnState.points.length state.points.length !== drawnState.points.length ||
|| state.points.some((p: number, id: number): boolean => p !== drawnState.points[id]) state.points.some((p: number, id: number): boolean => p !== drawnState.points[id])
) { ) {
const translatedPoints: number[] = this.translateToCanvas(state.points); const translatedPoints: number[] = this.translateToCanvas(state.points);
@ -1549,9 +1546,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
const drawnStateDescriptions = drawnState.descriptions; const drawnStateDescriptions = drawnState.descriptions;
if ( if (
drawnState.label.id !== state.label.id drawnState.label.id !== state.label.id ||
|| drawnStateDescriptions.length !== stateDescriptions.length drawnStateDescriptions.length !== stateDescriptions.length ||
|| drawnStateDescriptions.some((desc: string, id: number): boolean => desc !== stateDescriptions[id]) drawnStateDescriptions.some((desc: string, id: number): boolean => desc !== stateDescriptions[id])
) { ) {
// need to remove created text and create it again // need to remove created text and create it again
if (text) { if (text) {
@ -1800,10 +1797,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
const dy2 = (p1.y - p2.y) ** 2; const dy2 = (p1.y - p2.y) ** 2;
if (Math.sqrt(dx2 + dy2) >= delta) { if (Math.sqrt(dx2 + dy2) >= delta) {
const points = pointsToNumberArray( const points = pointsToNumberArray(
shape.attr('points') shape.attr('points') || `${shape.attr('x')},${shape.attr('y')} ` +
|| `${shape.attr('x')},${shape.attr('y')} ` `${shape.attr('x') + shape.attr('width')},` +
+ `${shape.attr('x') + shape.attr('width')},` `${shape.attr('y') + shape.attr('height')}`,
+ `${shape.attr('y') + shape.attr('height')}`,
).map((x: number): number => x - offset); ).map((x: number): number => x - offset);
this.drawnStates[state.clientID].points = points; this.drawnStates[state.clientID].points = points;
@ -1874,10 +1870,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
const { offset } = this.controller.geometry; const { offset } = this.controller.geometry;
const points = pointsToNumberArray( const points = pointsToNumberArray(
shape.attr('points') shape.attr('points') || `${shape.attr('x')},${shape.attr('y')} ` +
|| `${shape.attr('x')},${shape.attr('y')} ` `${shape.attr('x') + shape.attr('width')},` +
+ `${shape.attr('x') + shape.attr('width')},` `${shape.attr('y') + shape.attr('height')}`,
+ `${shape.attr('y') + shape.attr('height')}`,
).map((x: number): number => x - offset); ).map((x: number): number => x - offset);
this.drawnStates[state.clientID].points = points; this.drawnStates[state.clientID].points = points;
@ -1953,8 +1948,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Find the best place for a text // Find the best place for a text
let [clientX, clientY]: number[] = [box.x + box.width, box.y]; let [clientX, clientY]: number[] = [box.x + box.width, box.y];
if ( if (
clientX + ((text.node as any) as SVGTextElement).getBBox().width + consts.TEXT_MARGIN clientX + ((text.node as any) as SVGTextElement)
> this.canvas.offsetWidth .getBBox().width + consts.TEXT_MARGIN > this.canvas.offsetWidth
) { ) {
[clientX, clientY] = [box.x, box.y]; [clientX, clientY] = [box.x, box.y];
} }

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -14,8 +14,8 @@ const MIN_EDGE_LENGTH = 3;
const CUBOID_ACTIVE_EDGE_STROKE_WIDTH = 2.5; const CUBOID_ACTIVE_EDGE_STROKE_WIDTH = 2.5;
const CUBOID_UNACTIVE_EDGE_STROKE_WIDTH = 1.75; const CUBOID_UNACTIVE_EDGE_STROKE_WIDTH = 1.75;
const UNDEFINED_ATTRIBUTE_VALUE = '__undefined__'; const UNDEFINED_ATTRIBUTE_VALUE = '__undefined__';
const ARROW_PATH = 'M13.162 6.284L.682.524a.483.483 0 0 0-.574.134.477.477 0 ' const ARROW_PATH = 'M13.162 6.284L.682.524a.483.483 0 0 0-.574.134.477.477 0 ' +
+ '0 0-.012.59L4.2 6.72.096 12.192a.479.479 0 0 0 .585.724l12.48-5.76a.48.48 0 0 0 0-.872z'; '0 0-.012.59L4.2 6.72.096 12.192a.479.479 0 0 0 .585.724l12.48-5.76a.48.48 0 0 0 0-.872z';
const BASE_PATTERN_SIZE = 5; const BASE_PATTERN_SIZE = 5;
export default { export default {

@ -348,9 +348,8 @@ function setupCuboidPoints(points: Point[]): any[] {
let p3; let p3;
let p4; let p4;
const height = Math.abs(points[0].x - points[1].x) < Math.abs(points[1].x - points[2].x) const height = Math.abs(points[0].x - points[1].x) < Math.abs(points[1].x - points[2].x) ?
? Math.abs(points[1].y - points[0].y) Math.abs(points[1].y - points[0].y) : Math.abs(points[1].y - points[2].y);
: Math.abs(points[1].y - points[2].y);
// separate into left and right point // separate into left and right point
// we pick the first and third point because we know assume they will be on // we pick the first and third point because we know assume they will be on

@ -111,9 +111,9 @@ export class DrawHandlerImpl implements DrawHandler {
const findInersection = (p1: Point, p2: Point, p3: Point, p4: Point): number[] => { const findInersection = (p1: Point, p2: Point, p3: Point, p4: Point): number[] => {
const intersectionPoint = intersection(p1, p2, p3, p4); const intersectionPoint = intersection(p1, p2, p3, p4);
if ( if (
intersectionPoint intersectionPoint &&
&& isBetween(p1.x, p2.x, intersectionPoint.x) isBetween(p1.x, p2.x, intersectionPoint.x) &&
&& isBetween(p1.y, p2.y, intersectionPoint.y) isBetween(p1.y, p2.y, intersectionPoint.y)
) { ) {
return [intersectionPoint.x, intersectionPoint.y]; return [intersectionPoint.x, intersectionPoint.y];
} }
@ -149,8 +149,8 @@ export class DrawHandlerImpl implements DrawHandler {
if (resultPoints.length === 4) { if (resultPoints.length === 4) {
if ( if (
(p1.x === p2.x || Math.sign(resultPoints[0] - resultPoints[2]) !== Math.sign(p1.x - p2.x)) (p1.x === p2.x || Math.sign(resultPoints[0] - resultPoints[2]) !== Math.sign(p1.x - p2.x)) &&
&& (p1.y === p2.y || Math.sign(resultPoints[1] - resultPoints[3]) !== Math.sign(p1.y - p2.y)) (p1.y === p2.y || Math.sign(resultPoints[1] - resultPoints[3]) !== Math.sign(p1.y - p2.y))
) { ) {
[resultPoints[0], resultPoints[2]] = [resultPoints[2], resultPoints[0]]; [resultPoints[0], resultPoints[2]] = [resultPoints[2], resultPoints[0]];
[resultPoints[1], resultPoints[3]] = [resultPoints[3], resultPoints[1]]; [resultPoints[1], resultPoints[3]] = [resultPoints[3], resultPoints[1]];
@ -173,9 +173,9 @@ export class DrawHandlerImpl implements DrawHandler {
if (isLastPoint && (isPolyline || (isPolygon && shapePoints.length === 4))) { if (isLastPoint && (isPolyline || (isPolygon && shapePoints.length === 4))) {
break; break;
} }
const nextPoint = isLastPoint const nextPoint = isLastPoint ?
? { x: shapePoints[0], y: shapePoints[1] } { x: shapePoints[0], y: shapePoints[1] } :
: { x: shapePoints[i + 2], y: shapePoints[i + 3] }; { x: shapePoints[i + 2], y: shapePoints[i + 3] };
const intersectionPoints = findIntersectionsWithFrameBorders(curPoint, nextPoint, direction); const intersectionPoints = findIntersectionsWithFrameBorders(curPoint, nextPoint, direction);
if (intersectionPoints.length !== 0) { if (intersectionPoints.length !== 0) {
resultPoints.push(...intersectionPoints); resultPoints.push(...intersectionPoints);
@ -312,9 +312,9 @@ export class DrawHandlerImpl implements DrawHandler {
// We check if it is activated with remember function // We check if it is activated with remember function
if (this.drawInstance.remember('_paintHandler')) { if (this.drawInstance.remember('_paintHandler')) {
if ( if (
['polygon', 'polyline', 'points'].includes(this.drawData.shapeType) ['polygon', 'polyline', 'points'].includes(this.drawData.shapeType) ||
|| (this.drawData.shapeType === 'cuboid' (this.drawData.shapeType === 'cuboid' &&
&& this.drawData.cuboidDrawingMethod === CuboidDrawingMethod.CORNER_POINTS) this.drawData.cuboidDrawingMethod === CuboidDrawingMethod.CORNER_POINTS)
) { ) {
// Check for unsaved drawn shapes // Check for unsaved drawn shapes
this.drawInstance.draw('done'); this.drawInstance.draw('done');
@ -489,22 +489,22 @@ export class DrawHandlerImpl implements DrawHandler {
this.drawInstance.on('drawdone', (e: CustomEvent): void => { this.drawInstance.on('drawdone', (e: CustomEvent): void => {
const targetPoints = pointsToNumberArray((e.target as SVGElement).getAttribute('points')); const targetPoints = pointsToNumberArray((e.target as SVGElement).getAttribute('points'));
const { shapeType, redraw: clientID } = this.drawData; const { shapeType, redraw: clientID } = this.drawData;
const { points, box } = shapeType === 'cuboid' const { points, box } = shapeType === 'cuboid' ?
? this.getFinalCuboidCoordinates(targetPoints) this.getFinalCuboidCoordinates(targetPoints) :
: this.getFinalPolyshapeCoordinates(targetPoints); this.getFinalPolyshapeCoordinates(targetPoints);
this.release(); this.release();
if (this.canceled) return; if (this.canceled) return;
if ( if (
shapeType === 'polygon' shapeType === 'polygon' &&
&& (box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD (box.xbr - box.xtl) * (box.ybr - box.ytl) >= consts.AREA_THRESHOLD &&
&& points.length >= 3 * 2 points.length >= 3 * 2
) { ) {
this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp); this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp);
} else if ( } else if (
shapeType === 'polyline' shapeType === 'polyline' &&
&& (box.xbr - box.xtl >= consts.SIZE_THRESHOLD || box.ybr - box.ytl >= consts.SIZE_THRESHOLD) (box.xbr - box.xtl >= consts.SIZE_THRESHOLD || box.ybr - box.ytl >= consts.SIZE_THRESHOLD) &&
&& points.length >= 2 * 2 points.length >= 2 * 2
) { ) {
this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp); this.onDrawDone({ clientID, shapeType, points }, Date.now() - this.startTimestamp);
} else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') { } else if (shapeType === 'points' && (e.target as any).getAttribute('points') !== '0,0') {
@ -611,9 +611,9 @@ export class DrawHandlerImpl implements DrawHandler {
.split(/[,\s]/g) .split(/[,\s]/g)
.map((coord: string): number => +coord); .map((coord: string): number => +coord);
const { points } = this.drawData.initialState.shapeType === 'cuboid' const { points } = this.drawData.initialState.shapeType === 'cuboid' ?
? this.getFinalCuboidCoordinates(targetPoints) this.getFinalCuboidCoordinates(targetPoints) :
: this.getFinalPolyshapeCoordinates(targetPoints); this.getFinalPolyshapeCoordinates(targetPoints);
if (!e.detail.originalEvent.ctrlKey) { if (!e.detail.originalEvent.ctrlKey) {
this.release(); this.release();
@ -886,12 +886,12 @@ export class DrawHandlerImpl implements DrawHandler {
public configurate(configuration: Configuration): void { public configurate(configuration: Configuration): void {
this.configuration = configuration; this.configuration = configuration;
const isFillableRect = this.drawData const isFillableRect = this.drawData &&
&& this.drawData.shapeType === 'rectangle' this.drawData.shapeType === 'rectangle' &&
&& (this.drawData.rectDrawingMethod === RectDrawingMethod.CLASSIC || this.drawData.initialState); (this.drawData.rectDrawingMethod === RectDrawingMethod.CLASSIC || this.drawData.initialState);
const isFillableCuboid = this.drawData const isFillableCuboid = this.drawData &&
&& this.drawData.shapeType === 'cuboid' this.drawData.shapeType === 'cuboid' &&
&& (this.drawData.cuboidDrawingMethod === CuboidDrawingMethod.CLASSIC || this.drawData.initialState); (this.drawData.cuboidDrawingMethod === CuboidDrawingMethod.CLASSIC || this.drawData.initialState);
const isFilalblePolygon = this.drawData && this.drawData.shapeType === 'polygon'; const isFilalblePolygon = this.drawData && this.drawData.shapeType === 'polygon';
if (this.drawInstance && (isFillableRect || isFillableCuboid || isFilalblePolygon)) { if (this.drawInstance && (isFillableRect || isFillableCuboid || isFilalblePolygon)) {

@ -292,27 +292,28 @@ export class EditHandlerImpl implements EditHandler {
} }
private setupPoints(enabled: boolean): void { private setupPoints(enabled: boolean): void {
const self = this; const stopEdit = this.stopEdit.bind(this);
const stopEdit = self.stopEdit.bind(self); const getGeometry = (): Geometry => this.geometry;
const fill = this.editedShape.attr('fill') || 'inherit';
if (enabled) { if (enabled) {
(this.editedShape as any).selectize(true, { (this.editedShape as any).selectize(true, {
deepSelect: true, deepSelect: true,
pointSize: (2 * consts.BASE_POINT_SIZE) / self.geometry.scale, pointSize: (2 * consts.BASE_POINT_SIZE) / getGeometry().scale,
rotationPoint: false, rotationPoint: false,
pointType(cx: number, cy: number): SVG.Circle { pointType(cx: number, cy: number): SVG.Circle {
const circle: SVG.Circle = this.nested const circle: SVG.Circle = this.nested
.circle(this.options.pointSize) .circle(this.options.pointSize)
.stroke('black') .stroke('black')
.fill(self.editedShape.attr('fill') || 'inherit') .fill(fill)
.center(cx, cy) .center(cx, cy)
.attr({ .attr({
'stroke-width': consts.POINTS_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_STROKE_WIDTH / getGeometry().scale,
}); });
circle.node.addEventListener('mouseenter', (): void => { circle.node.addEventListener('mouseenter', (): void => {
circle.attr({ circle.attr({
'stroke-width': consts.POINTS_SELECTED_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_SELECTED_STROKE_WIDTH / getGeometry().scale,
}); });
circle.node.addEventListener('click', stopEdit); circle.node.addEventListener('click', stopEdit);
@ -321,7 +322,7 @@ export class EditHandlerImpl implements EditHandler {
circle.node.addEventListener('mouseleave', (): void => { circle.node.addEventListener('mouseleave', (): void => {
circle.attr({ circle.attr({
'stroke-width': consts.POINTS_STROKE_WIDTH / self.geometry.scale, 'stroke-width': consts.POINTS_STROKE_WIDTH / getGeometry().scale,
}); });
circle.node.removeEventListener('click', stopEdit); circle.node.removeEventListener('click', stopEdit);

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -96,11 +96,11 @@ export class GroupHandlerImpl implements GroupHandler {
const bbox = shape.bbox(); const bbox = shape.bbox();
const clientID = shape.attr('clientID'); const clientID = shape.attr('clientID');
if ( if (
bbox.x > box.xtl bbox.x > box.xtl &&
&& bbox.y > box.ytl bbox.y > box.ytl &&
&& bbox.x + bbox.width < box.xbr bbox.x + bbox.width < box.xbr &&
&& bbox.y + bbox.height < box.ybr bbox.y + bbox.height < box.ybr &&
&& !(clientID in this.highlightedShapes) !(clientID in this.highlightedShapes)
) { ) {
const objectState = this.getStates().filter( const objectState = this.getStates().filter(
(state: any): boolean => state.clientID === clientID, (state: any): boolean => state.clientID === clientID,

@ -363,12 +363,12 @@ export class InteractionHandlerImpl implements InteractionHandler {
private visualComponentsChanged(interactionData: InteractionData): boolean { private visualComponentsChanged(interactionData: InteractionData): boolean {
const allowedKeys = ['enabled', 'crosshair', 'enableThreshold', 'onChangeToolsBlockerState']; const allowedKeys = ['enabled', 'crosshair', 'enableThreshold', 'onChangeToolsBlockerState'];
if (Object.keys(interactionData).every((key: string): boolean => allowedKeys.includes(key))) { if (Object.keys(interactionData).every((key: string): boolean => allowedKeys.includes(key))) {
if (this.interactionData.enableThreshold !== undefined && interactionData.enableThreshold !== undefined if (this.interactionData.enableThreshold !== undefined && interactionData.enableThreshold !== undefined &&
&& this.interactionData.enableThreshold !== interactionData.enableThreshold) { this.interactionData.enableThreshold !== interactionData.enableThreshold) {
return true; return true;
} }
if (this.interactionData.crosshair !== undefined && interactionData.crosshair !== undefined if (this.interactionData.crosshair !== undefined && interactionData.crosshair !== undefined &&
&& this.interactionData.crosshair !== interactionData.crosshair) { this.interactionData.crosshair !== interactionData.crosshair) {
return true; return true;
} }
} }
@ -481,9 +481,9 @@ export class InteractionHandlerImpl implements InteractionHandler {
this.crosshair.scale(this.geometry.scale); this.crosshair.scale(this.geometry.scale);
} }
const shapesToBeScaled = this.currentInteractionShape const shapesToBeScaled = this.currentInteractionShape ?
? [...this.interactionShapes, this.currentInteractionShape] [...this.interactionShapes, this.currentInteractionShape] :
: [...this.interactionShapes]; [...this.interactionShapes];
for (const shape of shapesToBeScaled) { for (const shape of shapesToBeScaled) {
if (shape.type === 'circle') { if (shape.type === 'circle') {
if (shape.hasClass('cvat_canvas_removable_interaction_point')) { if (shape.hasClass('cvat_canvas_removable_interaction_point')) {

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -47,11 +47,11 @@ export class ZoomHandlerImpl implements ZoomHandler {
private getSelectionBox( private getSelectionBox(
event: MouseEvent, event: MouseEvent,
): { ): {
x: number; x: number;
y: number; y: number;
width: number; width: number;
height: number; height: number;
} { } {
const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]); const point = translateToSVG((this.canvas.node as any) as SVGSVGElement, [event.clientX, event.clientY]);
const stopSelectionPoint = { const stopSelectionPoint = {
x: point[0], x: point[0],

@ -2,6 +2,8 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
const globalConfig = require('../.eslintrc.js');
module.exports = { module.exports = {
env: { env: {
node: true, node: true,
@ -12,38 +14,32 @@ module.exports = {
project: './tsconfig.json', project: './tsconfig.json',
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
}, },
plugins: ['@typescript-eslint', 'import'], ignorePatterns: [
extends: [ '.eslintrc.js',
'plugin:@typescript-eslint/recommended', 'webpack.config.js',
'airbnb-typescript/base', 'node_modules/**',
'plugin:import/errors', 'dist/**',
'plugin:import/warnings',
'plugin:import/typescript',
], ],
ignorePatterns: ['.eslintrc.js'], plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended', 'airbnb-typescript/base'],
rules: { rules: {
...globalConfig.rules,
'@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/indent': ['warn', 4], '@typescript-eslint/indent': ['error', 4],
'no-plusplus': 0, '@typescript-eslint/lines-between-class-members': 0,
'no-restricted-syntax': [ '@typescript-eslint/no-explicit-any': [0],
0, '@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-types': [
'error',
{ {
selector: 'ForOfStatement', types: {
'{}': false, // TODO: try to fix with Record<string, unknown>
object: false, // TODO: try to fix with Record<string, unknown>
Function: false, // TODO: try to fix somehow
},
}, },
], ],
'max-len': ['error', { code: 120 }],
'no-continue': 0,
'func-names': 0,
'no-console': 0, // this rule deprecates console.log, console.warn etc. because 'it is not good in production code'
'lines-between-class-members': 0,
'import/prefer-default-export': 0, // works incorrect with interfaces
'newline-per-chained-call': 0, // makes code uglier
},
settings: {
'import/resolver': {
node: {
extensions: ['.ts', '.js', '.json'],
},
},
}, },
}; };

@ -1 +0,0 @@
dist

@ -1 +0,0 @@
webpack.config.js

@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation // Copyright (C) 2018-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -9,39 +9,25 @@ module.exports = {
es6: true, es6: true,
'jest/globals': true, 'jest/globals': true,
}, },
ignorePatterns: [
'.eslintrc.js',
'webpack.config.js',
'jest.config.js',
'jsdoc.config.js',
'src/3rdparty/**',
'node_modules/**',
'dist/**',
],
parserOptions: { parserOptions: {
parser: 'babel-eslint', parser: 'babel-eslint',
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2018, ecmaVersion: 2018,
}, },
plugins: ['security', 'jest', 'no-unsafe-innerhtml', 'no-unsanitized'], plugins: ['jest'],
extends: ['eslint:recommended', 'plugin:security/recommended', 'plugin:no-unsanitized/DOM', 'airbnb-base'],
rules: { rules: {
'no-await-in-loop': [0], 'jest/no-disabled-tests': 'warn',
'global-require': [0], 'jest/no-focused-tests': 'error',
'no-new': [0], 'jest/no-identical-title': 'error',
'class-methods-use-this': [0], 'jest/prefer-to-have-length': 'warn',
'no-restricted-properties': [ }
0,
{
object: 'Math',
property: 'pow',
},
],
'no-plusplus': [0],
'no-param-reassign': [0],
'no-underscore-dangle': ['error', { allowAfterThis: true }],
'no-restricted-syntax': [0, { selector: 'ForOfStatement' }],
'no-continue': [0],
'no-unsafe-innerhtml/no-unsafe-innerhtml': 1,
// This rule actual for user input data on the node.js environment mainly.
'security/detect-object-injection': 0,
indent: ['warn', 4],
'no-useless-constructor': 0,
'func-names': [0],
'valid-typeof': [0],
'no-console': [0],
'max-classes-per-file': [0],
'max-len': ['warn', { code: 120 }],
},
}; };

@ -1,5 +0,0 @@
docs
node_modules
reports
yarn.lock
dist

@ -1,4 +1,4 @@
// Copyright (C) 2019-2021 Intel Corporation // Copyright (C) 2019-2020 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT

@ -36,23 +36,23 @@
let shapeModel = null; let shapeModel = null;
switch (type) { switch (type) {
case 'rectangle': case 'rectangle':
shapeModel = new RectangleShape(shapeData, clientID, color, injection); shapeModel = new RectangleShape(shapeData, clientID, color, injection);
break; break;
case 'polygon': case 'polygon':
shapeModel = new PolygonShape(shapeData, clientID, color, injection); shapeModel = new PolygonShape(shapeData, clientID, color, injection);
break; break;
case 'polyline': case 'polyline':
shapeModel = new PolylineShape(shapeData, clientID, color, injection); shapeModel = new PolylineShape(shapeData, clientID, color, injection);
break; break;
case 'points': case 'points':
shapeModel = new PointsShape(shapeData, clientID, color, injection); shapeModel = new PointsShape(shapeData, clientID, color, injection);
break; break;
case 'cuboid': case 'cuboid':
shapeModel = new CuboidShape(shapeData, clientID, color, injection); shapeModel = new CuboidShape(shapeData, clientID, color, injection);
break; break;
default: default:
throw new DataError(`An unexpected type of shape "${type}"`); throw new DataError(`An unexpected type of shape "${type}"`);
} }
return shapeModel; return shapeModel;
@ -65,23 +65,23 @@
let trackModel = null; let trackModel = null;
switch (type) { switch (type) {
case 'rectangle': case 'rectangle':
trackModel = new RectangleTrack(trackData, clientID, color, injection); trackModel = new RectangleTrack(trackData, clientID, color, injection);
break; break;
case 'polygon': case 'polygon':
trackModel = new PolygonTrack(trackData, clientID, color, injection); trackModel = new PolygonTrack(trackData, clientID, color, injection);
break; break;
case 'polyline': case 'polyline':
trackModel = new PolylineTrack(trackData, clientID, color, injection); trackModel = new PolylineTrack(trackData, clientID, color, injection);
break; break;
case 'points': case 'points':
trackModel = new PointsTrack(trackData, clientID, color, injection); trackModel = new PointsTrack(trackData, clientID, color, injection);
break; break;
case 'cuboid': case 'cuboid':
trackModel = new CuboidTrack(trackData, clientID, color, injection); trackModel = new CuboidTrack(trackData, clientID, color, injection);
break; break;
default: default:
throw new DataError(`An unexpected type of track "${type}"`); throw new DataError(`An unexpected type of track "${type}"`);
} }
return trackModel; return trackModel;
@ -336,22 +336,20 @@
occluded: shape.occluded, occluded: shape.occluded,
outside: shape.outside, outside: shape.outside,
zOrder: shape.zOrder, zOrder: shape.zOrder,
attributes: updatedAttributes attributes: updatedAttributes ? Object.keys(attributes).reduce((accumulator, attrID) => {
? Object.keys(attributes).reduce((accumulator, attrID) => { accumulator.push({
accumulator.push({ spec_id: +attrID,
spec_id: +attrID, value: attributes[attrID],
value: attributes[attrID], });
});
return accumulator;
return accumulator; }, []) : [],
}, [])
: [],
}; };
} }
} else { } else {
throw new ArgumentError( throw new ArgumentError(
`Trying to merge unknown object type: ${object.constructor.name}. ` `Trying to merge unknown object type: ${object.constructor.name}. ` +
+ 'Only shapes and tracks are expected.', 'Only shapes and tracks are expected.',
); );
} }
} }
@ -584,8 +582,8 @@
this.flush = true; this.flush = true;
} else { } else {
// If inputs provided were wrong // If inputs provided were wrong
throw Error('Could not remove the annotations, please provide both inputs or' throw Error('Could not remove the annotations, please provide both inputs or' +
+ ' leave the inputs below empty to remove all the annotations from this job'); ' leave the inputs below empty to remove all the annotations from this job');
} }
} }

@ -253,8 +253,8 @@
for (const attribute of redoLabel.attributes) { for (const attribute of redoLabel.attributes) {
for (const oldAttribute of undoLabel.attributes) { for (const oldAttribute of undoLabel.attributes) {
if ( if (
attribute.name === oldAttribute.name attribute.name === oldAttribute.name &&
&& validateAttributeValue(undoAttributes[oldAttribute.id], attribute) validateAttributeValue(undoAttributes[oldAttribute.id], attribute)
) { ) {
this.attributes[attribute.id] = undoAttributes[oldAttribute.id]; this.attributes[attribute.id] = undoAttributes[oldAttribute.id];
} }
@ -919,13 +919,13 @@
if (!labelAttributes[attrID].mutable) { if (!labelAttributes[attrID].mutable) {
redoAttributes[attrID] = attributes[attrID]; redoAttributes[attrID] = attributes[attrID];
} else if (attributes[attrID] !== current.attributes[attrID]) { } else if (attributes[attrID] !== current.attributes[attrID]) {
mutableAttributesUpdated = mutableAttributesUpdated mutableAttributesUpdated = mutableAttributesUpdated ||
// not keyframe yet // not keyframe yet
|| !(frame in this.shapes) !(frame in this.shapes) ||
// keyframe, but without this attrID // keyframe, but without this attrID
|| !(attrID in this.shapes[frame].attributes) !(attrID in this.shapes[frame].attributes) ||
// keyframe with attrID, but with another value // keyframe with attrID, but with another value
|| this.shapes[frame].attributes[attrID] !== attributes[attrID]; this.shapes[frame].attributes[attrID] !== attributes[attrID];
} }
} }
let redoShape; let redoShape;
@ -1015,9 +1015,9 @@
const undoSource = this.source; const undoSource = this.source;
const redoSource = Source.MANUAL; const redoSource = Source.MANUAL;
const undoShape = wasKeyframe ? this.shapes[frame] : undefined; const undoShape = wasKeyframe ? this.shapes[frame] : undefined;
const redoShape = wasKeyframe const redoShape = wasKeyframe ?
? { ...this.shapes[frame], points } { ...this.shapes[frame], points } :
: { {
frame, frame,
points, points,
zOrder: current.zOrder, zOrder: current.zOrder,
@ -1044,9 +1044,9 @@
const undoSource = this.source; const undoSource = this.source;
const redoSource = Source.MANUAL; const redoSource = Source.MANUAL;
const undoShape = wasKeyframe ? this.shapes[frame] : undefined; const undoShape = wasKeyframe ? this.shapes[frame] : undefined;
const redoShape = wasKeyframe const redoShape = wasKeyframe ?
? { ...this.shapes[frame], outside } { ...this.shapes[frame], outside } :
: { {
frame, frame,
outside, outside,
zOrder: current.zOrder, zOrder: current.zOrder,
@ -1073,9 +1073,9 @@
const undoSource = this.source; const undoSource = this.source;
const redoSource = Source.MANUAL; const redoSource = Source.MANUAL;
const undoShape = wasKeyframe ? this.shapes[frame] : undefined; const undoShape = wasKeyframe ? this.shapes[frame] : undefined;
const redoShape = wasKeyframe const redoShape = wasKeyframe ?
? { ...this.shapes[frame], occluded } { ...this.shapes[frame], occluded } :
: { {
frame, frame,
occluded, occluded,
zOrder: current.zOrder, zOrder: current.zOrder,
@ -1102,9 +1102,9 @@
const undoSource = this.source; const undoSource = this.source;
const redoSource = Source.MANUAL; const redoSource = Source.MANUAL;
const undoShape = wasKeyframe ? this.shapes[frame] : undefined; const undoShape = wasKeyframe ? this.shapes[frame] : undefined;
const redoShape = wasKeyframe const redoShape = wasKeyframe ?
? { ...this.shapes[frame], zOrder } { ...this.shapes[frame], zOrder } :
: { {
frame, frame,
zOrder, zOrder,
occluded: current.occluded, occluded: current.occluded,
@ -1136,8 +1136,8 @@
const undoSource = this.source; const undoSource = this.source;
const redoSource = Source.MANUAL; const redoSource = Source.MANUAL;
const undoShape = wasKeyframe ? this.shapes[frame] : undefined; const undoShape = wasKeyframe ? this.shapes[frame] : undefined;
const redoShape = keyframe const redoShape = keyframe ?
? { {
frame, frame,
zOrder: current.zOrder, zOrder: current.zOrder,
points: current.points, points: current.points,
@ -1145,8 +1145,8 @@
occluded: current.occluded, occluded: current.occluded,
attributes: {}, attributes: {},
source: current.source, source: current.source,
} } :
: undefined; undefined;
this.source = Source.MANUAL; this.source = Source.MANUAL;
if (redoShape) { if (redoShape) {
@ -1264,17 +1264,13 @@
} }
throw new DataError( throw new DataError(
'No one left position or right position was found. ' 'No one left position or right position was found. ' +
+ `Interpolation impossible. Client ID: ${this.clientID}`, `Interpolation impossible. Client ID: ${this.clientID}`,
); );
} }
} }
class Tag extends Annotation { class Tag extends Annotation {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
}
// Method is used to export data to the server // Method is used to export data to the server
toJSON() { toJSON() {
return { return {
@ -1373,11 +1369,7 @@
} }
} }
class PolyShape extends Shape { class PolyShape extends Shape {}
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
}
}
class PolygonShape extends PolyShape { class PolygonShape extends PolyShape {
constructor(data, clientID, color, injection) { constructor(data, clientID, color, injection) {
@ -1431,12 +1423,12 @@
if ((xCross - x1) * (x2 - xCross) >= 0 && (yCross - y1) * (y2 - yCross) >= 0) { if ((xCross - x1) * (x2 - xCross) >= 0 && (yCross - y1) * (y2 - yCross) >= 0) {
// Cross point is on segment between p1(x1,y1) and p2(x2,y2) // Cross point is on segment between p1(x1,y1) and p2(x2,y2)
distances.push(Math.sqrt(Math.pow(x - xCross, 2) + Math.pow(y - yCross, 2))); distances.push(Math.sqrt((x - xCross) ** 2 + (y - yCross) ** 2));
} else { } else {
distances.push( distances.push(
Math.min( Math.min(
Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2)), Math.sqrt((x1 - x) ** 2 + (y1 - y) ** 2),
Math.sqrt(Math.pow(x2 - x, 2) + Math.pow(y2 - y, 2)), Math.sqrt((x2 - x) ** 2 + (y2 - y) ** 2),
), ),
); );
} }
@ -1473,8 +1465,8 @@
// Find the length of a perpendicular // Find the length of a perpendicular
// https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
distances.push( distances.push(
Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) /
/ Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)), Math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2),
); );
} else { } else {
// The link below works for lines (which have infinite length) // The link below works for lines (which have infinite length)
@ -1483,8 +1475,8 @@
// Instead we use just distance to the nearest point // Instead we use just distance to the nearest point
distances.push( distances.push(
Math.min( Math.min(
Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2)), Math.sqrt((x1 - x) ** 2 + (y1 - y) ** 2),
Math.sqrt(Math.pow(x2 - x, 2) + Math.pow(y2 - y, 2)), Math.sqrt((x2 - x) ** 2 + (y2 - y) ** 2),
), ),
); );
} }
@ -1507,7 +1499,7 @@
const x1 = points[i]; const x1 = points[i];
const y1 = points[i + 1]; const y1 = points[i + 1];
distances.push(Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2))); distances.push(Math.sqrt((x1 - x) ** 2 + (y1 - y) ** 2));
} }
return Math.min.apply(null, distances); return Math.min.apply(null, distances);
@ -1558,10 +1550,10 @@
lowerHull.pop(); lowerHull.pop();
if ( if (
upperHull.length === 1 upperHull.length === 1 &&
&& lowerHull.length === 1 lowerHull.length === 1 &&
&& upperHull[0].x === lowerHull[0].x upperHull[0].x === lowerHull[0].x &&
&& upperHull[0].y === lowerHull[0].y upperHull[0].y === lowerHull[0].y
) return upperHull; ) return upperHull;
return upperHull.concat(lowerHull); return upperHull.concat(lowerHull);
} }
@ -1579,11 +1571,11 @@
return makeHullPresorted(newPoints); return makeHullPresorted(newPoints);
} }
static contain(points, x, y) { static contain(shapePoints, x, y) {
function isLeft(P0, P1, P2) { function isLeft(P0, P1, P2) {
return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y); return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y);
} }
points = CuboidShape.makeHull(points); const points = CuboidShape.makeHull(shapePoints);
let wn = 0; let wn = 0;
for (let i = 0; i < points.length; i += 1) { for (let i = 0; i < points.length; i += 1) {
const p1 = points[`${i}`]; const p1 = points[`${i}`];
@ -1620,13 +1612,13 @@
const p2 = points[i + 1] || points[0]; const p2 = points[i + 1] || points[0];
// perpendicular from point to straight length // perpendicular from point to straight length
const distance = Math.abs((p2.y - p1.y) * x - (p2.x - p1.x) * y + p2.x * p1.y - p2.y * p1.x) const distance = Math.abs((p2.y - p1.y) * x - (p2.x - p1.x) * y + p2.x * p1.y - p2.y * p1.x) /
/ Math.sqrt(Math.pow(p2.y - p1.y, 2) + Math.pow(p2.x - p1.x, 2)); Math.sqrt((p2.y - p1.y) ** 2 + (p2.x - p1.x) ** 2);
// check if perpendicular belongs to the straight segment // check if perpendicular belongs to the straight segment
const a = Math.pow(p1.x - x, 2) + Math.pow(p1.y - y, 2); const a = (p1.x - x) ** 2 + (p1.y - y) ** 2;
const b = Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2); const b = (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2;
const c = Math.pow(p2.x - x, 2) + Math.pow(p2.y - y, 2); const c = (p2.x - x) ** 2 + (p2.y - y) ** 2;
if (distance < minDistance && a + b - c >= 0 && c + b - a >= 0) { if (distance < minDistance && a + b - c >= 0 && c + b - a >= 0) {
minDistance = distance; minDistance = distance;
} }
@ -1658,10 +1650,6 @@
} }
class PolyTrack extends Track { class PolyTrack extends Track {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
}
interpolatePosition(leftPosition, rightPosition, offset) { interpolatePosition(leftPosition, rightPosition, offset) {
if (offset === 0) { if (offset === 0) {
return { return {

@ -187,12 +187,10 @@
return indexes; return indexes;
} }
async save(onUpdate) { async save(onUpdateArg) {
if (typeof onUpdate !== 'function') { const onUpdate = typeof onUpdateArg === 'function' ? onUpdateArg : (message) => {
onUpdate = (message) => { console.log(message);
console.log(message); };
};
}
const exported = this.collection.export(); const exported = this.collection.export();
const { flush } = this.collection; const { flush } = this.collection;

@ -267,7 +267,8 @@
return projects; return projects;
}; };
cvat.projects.searchNames.implementation = async (search, limit) => serverProxy.projects.searchNames(search, limit); cvat.projects.searchNames
.implementation = async (search, limit) => serverProxy.projects.searchNames(search, limit);
cvat.cloudStorages.get.implementation = async (filter) => { cvat.cloudStorages.get.implementation = async (filter) => {
checkFilter(filter, { checkFilter(filter, {

@ -821,7 +821,7 @@ function build() {
const implementAPI = require('./api-implementation'); const implementAPI = require('./api-implementation');
Math.clamp = function (value, min, max) { Math.clamp = function clamp(value, min, max) {
return Math.min(Math.max(value, min), max); return Math.min(Math.max(value, min), max);
}; };

@ -75,8 +75,8 @@
if (!(value instanceof instance)) { if (!(value instanceof instance)) {
if (value !== undefined) { if (value !== undefined) {
throw new ArgumentError( throw new ArgumentError(
`"${name}" is expected to be ${instance.name}, but ` `"${name}" is expected to be ${instance.name}, but ` +
+ `"${value.constructor.name}" has been got`, `"${value.constructor.name}" has been got`,
); );
} }

@ -158,8 +158,8 @@
const onDecodeAll = async (frameNumber) => { const onDecodeAll = async (frameNumber) => {
if ( if (
frameDataCache[this.tid].activeChunkRequest frameDataCache[this.tid].activeChunkRequest &&
&& chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber
) { ) {
const callbackArray = frameDataCache[this.tid].activeChunkRequest.callbacks; const callbackArray = frameDataCache[this.tid].activeChunkRequest.callbacks;
for (let i = callbackArray.length - 1; i >= 0; --i) { for (let i = callbackArray.length - 1; i >= 0; --i) {
@ -177,8 +177,8 @@
const rejectRequestAll = () => { const rejectRequestAll = () => {
if ( if (
frameDataCache[this.tid].activeChunkRequest frameDataCache[this.tid].activeChunkRequest &&
&& chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber chunkNumber === frameDataCache[this.tid].activeChunkRequest.chunkNumber
) { ) {
for (const r of frameDataCache[this.tid].activeChunkRequest.callbacks) { for (const r of frameDataCache[this.tid].activeChunkRequest.callbacks) {
r.reject(r.frameNumber); r.reject(r.frameNumber);
@ -236,10 +236,10 @@
const activeRequest = frameDataCache[this.tid].activeChunkRequest; const activeRequest = frameDataCache[this.tid].activeChunkRequest;
if (!provider.isChunkCached(start, stop)) { if (!provider.isChunkCached(start, stop)) {
if ( if (
!activeRequest !activeRequest ||
|| (activeRequest (activeRequest &&
&& activeRequest.completed activeRequest.completed &&
&& activeRequest.chunkNumber !== chunkNumber) activeRequest.chunkNumber !== chunkNumber)
) { ) {
if (activeRequest && activeRequest.rejectRequestAll) { if (activeRequest && activeRequest.rejectRequestAll) {
activeRequest.rejectRequestAll(); activeRequest.rejectRequestAll();
@ -305,10 +305,10 @@
} }
} else { } else {
if ( if (
this.number % chunkSize > chunkSize / 4 this.number % chunkSize > chunkSize / 4 &&
&& provider.decodedBlocksCacheSize > 1 provider.decodedBlocksCacheSize > 1 &&
&& this.decodeForward this.decodeForward &&
&& !provider.isNextChunkExists(this.number) !provider.isNextChunkExists(this.number)
) { ) {
const nextChunkNumber = Math.floor(this.number / chunkSize) + 1; const nextChunkNumber = Math.floor(this.number / chunkSize) + 1;
if (nextChunkNumber * chunkSize < this.stopFrame) { if (nextChunkNumber * chunkSize < this.stopFrame) {
@ -421,8 +421,8 @@
.data() .data()
.then(() => { .then(() => {
if ( if (
!(chunkIdx in this._requestedChunks) !(chunkIdx in this._requestedChunks) ||
|| !this._requestedChunks[chunkIdx].requestedFrames.has(requestedFrame) !this._requestedChunks[chunkIdx].requestedFrames.has(requestedFrame)
) { ) {
reject(chunkIdx); reject(chunkIdx);
} else { } else {
@ -531,10 +531,10 @@
delete this._buffer[frameNumber]; delete this._buffer[frameNumber];
const cachedFrames = this.cachedFrames(); const cachedFrames = this.cachedFrames();
if ( if (
fillBuffer fillBuffer &&
&& !this._activeFillBufferRequest !this._activeFillBufferRequest &&
&& this._size > this._chunkSize this._size > this._chunkSize &&
&& cachedFrames.length < (this._size * 3) / 4 cachedFrames.length < (this._size * 3) / 4
) { ) {
const maxFrame = cachedFrames ? Math.max(...cachedFrames) : frameNumber; const maxFrame = cachedFrames ? Math.max(...cachedFrames) : frameNumber;
if (maxFrame < this._stopFrame) { if (maxFrame < this._stopFrame) {
@ -560,8 +560,8 @@
clear() { clear() {
for (const chunkIdx in this._requestedChunks) { for (const chunkIdx in this._requestedChunks) {
if ( if (
Object.prototype.hasOwnProperty.call(this._requestedChunks, chunkIdx) Object.prototype.hasOwnProperty.call(this._requestedChunks, chunkIdx) &&
&& this._requestedChunks[chunkIdx].reject this._requestedChunks[chunkIdx].reject
) { ) {
this._requestedChunks[chunkIdx].reject('not needed'); this._requestedChunks[chunkIdx].reject('not needed');
} }
@ -648,8 +648,8 @@
const meta = await serverProxy.frames.getMeta(taskID); const meta = await serverProxy.frames.getMeta(taskID);
const mean = meta.frames.reduce((a, b) => a + b.width * b.height, 0) / meta.frames.length; const mean = meta.frames.reduce((a, b) => a + b.width * b.height, 0) / meta.frames.length;
const stdDev = Math.sqrt( const stdDev = Math.sqrt(
meta.frames.map((x) => Math.pow(x.width * x.height - mean, 2)).reduce((a, b) => a + b) meta.frames.map((x) => (x.width * x.height - mean) ** 2).reduce((a, b) => a + b) /
/ meta.frames.length, meta.frames.length,
); );
// limit of decoded frames cache by 2GB // limit of decoded frames cache by 2GB

@ -147,8 +147,8 @@
data.attributes = []; data.attributes = [];
if ( if (
Object.prototype.hasOwnProperty.call(initialData, 'attributes') Object.prototype.hasOwnProperty.call(initialData, 'attributes') &&
&& Array.isArray(initialData.attributes) Array.isArray(initialData.attributes)
) { ) {
for (const attrData of initialData.attributes) { for (const attrData of initialData.attributes) {
data.attributes.push(new Attribute(attrData)); data.attributes.push(new Attribute(attrData));

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -143,9 +143,10 @@ class LogWithWorkingTime extends Log {
Log.prototype.validatePayload.call(this); Log.prototype.validatePayload.call(this);
if ( if (
!('working_time' in this.payload) !(
|| !typeof this.payload.working_time === 'number' 'working_time' in this.payload) ||
|| this.payload.working_time < 0 !typeof this.payload.working_time === 'number' ||
this.payload.working_time < 0
) { ) {
const message = ` const message = `
The field "working_time" is required for ${this.type} log. It must be a number not less than 0 The field "working_time" is required for ${this.type} log. It must be a number not less than 0

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -38,8 +38,8 @@ class LoggerStorage {
lastLog: null, lastLog: null,
ignore(previousLog, currentPayload) { ignore(previousLog, currentPayload) {
return ( return (
currentPayload.object_id === previousLog.payload.object_id currentPayload.object_id === previousLog.payload.object_id &&
&& currentPayload.id === previousLog.payload.id currentPayload.id === previousLog.payload.id
); );
}, },
}; };

@ -101,7 +101,12 @@ class MLModel {
} }
/** /**
* @param {(event:string)=>void} onChangeToolsBlockerState Set canvas onChangeToolsBlockerState callback * @callback onRequestStatusChange
* @param {string} event
* @global
*/
/**
* @param {onRequestStatusChange} onRequestStatusChange Set canvas onChangeToolsBlockerState callback
* @returns {void} * @returns {void}
*/ */
set onChangeToolsBlockerState(onChangeToolsBlockerState) { set onChangeToolsBlockerState(onChangeToolsBlockerState) {

@ -196,8 +196,8 @@ const { Source } = require('./enums');
data.points = [...points]; data.points = [...points];
} else { } else {
throw new ArgumentError( throw new ArgumentError(
'Points are expected to be an array ' 'Points are expected to be an array ' +
+ `but got ${ `but got ${
typeof points === 'object' ? points.constructor.name : typeof points typeof points === 'object' ? points.constructor.name : typeof points
}`, }`,
); );
@ -341,11 +341,11 @@ const { Source } = require('./enums');
set: (attributes) => { set: (attributes) => {
if (typeof attributes !== 'object') { if (typeof attributes !== 'object') {
throw new ArgumentError( throw new ArgumentError(
'Attributes are expected to be an object ' 'Attributes are expected to be an object ' +
+ `but got ${ `but got ${
typeof attributes === 'object' typeof attributes === 'object' ?
? attributes.constructor.name attributes.constructor.name :
: typeof attributes typeof attributes
}`, }`,
); );
} }
@ -368,8 +368,8 @@ const { Source } = require('./enums');
get: () => [...data.descriptions], get: () => [...data.descriptions],
set: (descriptions) => { set: (descriptions) => {
if ( if (
!Array.isArray(descriptions) !Array.isArray(descriptions) ||
|| descriptions.some((description) => typeof description !== 'string') descriptions.some((description) => typeof description !== 'string')
) { ) {
throw new ArgumentError( throw new ArgumentError(
`Descriptions are expected to be an array of strings but got ${data.descriptions}`, `Descriptions are expected to be an array of strings but got ${data.descriptions}`,
@ -414,8 +414,8 @@ const { Source } = require('./enums');
this.points = serialized.points; this.points = serialized.points;
} }
if ( if (
Array.isArray(serialized.descriptions) Array.isArray(serialized.descriptions) &&
&& serialized.descriptions.every((desc) => typeof desc === 'string') serialized.descriptions.every((desc) => typeof desc === 'string')
) { ) {
this.descriptions = serialized.descriptions; this.descriptions = serialized.descriptions;
} }

@ -1,4 +1,4 @@
// Copyright (C) 2019-2020 Intel Corporation // Copyright (C) 2019-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -74,9 +74,9 @@
traverse(plugin[key], api[key]); traverse(plugin[key], api[key]);
} }
} else if ( } else if (
['enter', 'leave'].includes(key) ['enter', 'leave'].includes(key) &&
&& typeof api === 'function' typeof api === 'function' &&
&& typeof (plugin[key] === 'function') typeof (plugin[key] === 'function')
) { ) {
decorator.callback = api; decorator.callback = api;
decorator[key] = plugin[key]; decorator[key] = plugin[key];

@ -134,9 +134,9 @@
return response.data; return response.data;
} }
async function share(directory) { async function share(directoryArg) {
const { backendAPI } = config; const { backendAPI } = config;
directory = encodeURIComponent(directory); const directory = encodeURIComponent(directoryArg);
let response = null; let response = null;
try { try {
@ -1143,7 +1143,8 @@
const closureId = Date.now(); const closureId = Date.now();
predictAnnotations.latestRequest.id = closureId; predictAnnotations.latestRequest.id = closureId;
const predicate = () => !predictAnnotations.latestRequest.fetching || predictAnnotations.latestRequest.id !== closureId; const predicate = () => !predictAnnotations.latestRequest.fetching ||
predictAnnotations.latestRequest.id !== closureId;
if (predictAnnotations.latestRequest.fetching) { if (predictAnnotations.latestRequest.fetching) {
waitFor(5, predicate).then(() => { waitFor(5, predicate).then(() => {
if (predictAnnotations.latestRequest.id !== closureId) { if (predictAnnotations.latestRequest.id !== closureId) {

@ -37,8 +37,12 @@
return result; return result;
}, },
async clear(reload = false, startframe = undefined, endframe = undefined, delTrackKeyframesOnly = true) { async clear(
const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.clear, reload, startframe, endframe, delTrackKeyframesOnly); reload = false, startframe = undefined, endframe = undefined, delTrackKeyframesOnly = true,
) {
const result = await PluginRegistry.apiWrapper.call(
this, prototype.annotations.clear, reload, startframe, endframe, delTrackKeyframesOnly,
);
return result; return result;
}, },
@ -1721,17 +1725,17 @@
for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { for (const [field, isUpdated] of Object.entries(this.__updatedFields)) {
if (isUpdated) { if (isUpdated) {
switch (field) { switch (field) {
case 'status': case 'status':
jobData.status = this.status; jobData.status = this.status;
break; break;
case 'assignee': case 'assignee':
jobData.assignee_id = this.assignee ? this.assignee.id : null; jobData.assignee_id = this.assignee ? this.assignee.id : null;
break; break;
case 'reviewer': case 'reviewer':
jobData.reviewer_id = this.reviewer ? this.reviewer.id : null; jobData.reviewer_id = this.reviewer ? this.reviewer.id : null;
break; break;
default: default:
break; break;
} }
} }
} }
@ -1897,7 +1901,9 @@
return result; return result;
}; };
Job.prototype.annotations.clear.implementation = async function (reload, startframe, endframe, delTrackKeyframesOnly) { Job.prototype.annotations.clear.implementation = async function (
reload, startframe, endframe, delTrackKeyframesOnly,
) {
const result = await clearAnnotations(this, reload, startframe, endframe, delTrackKeyframesOnly); const result = await clearAnnotations(this, reload, startframe, endframe, delTrackKeyframesOnly);
return result; return result;
}; };
@ -1996,26 +2002,26 @@
for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { for (const [field, isUpdated] of Object.entries(this.__updatedFields)) {
if (isUpdated) { if (isUpdated) {
switch (field) { switch (field) {
case 'assignee': case 'assignee':
taskData.assignee_id = this.assignee ? this.assignee.id : null; taskData.assignee_id = this.assignee ? this.assignee.id : null;
break; break;
case 'name': case 'name':
taskData.name = this.name; taskData.name = this.name;
break; break;
case 'bug_tracker': case 'bug_tracker':
taskData.bug_tracker = this.bugTracker; taskData.bug_tracker = this.bugTracker;
break; break;
case 'subset': case 'subset':
taskData.subset = this.subset; taskData.subset = this.subset;
break; break;
case 'project_id': case 'project_id':
taskData.project_id = this.projectId; taskData.project_id = this.projectId;
break; break;
case 'labels': case 'labels':
taskData.labels = [...this._internalData.labels.map((el) => el.toJSON())]; taskData.labels = [...this._internalData.labels.map((el) => el.toJSON())];
break; break;
default: default:
break; break;
} }
} }
} }

@ -640,44 +640,44 @@ describe('Feature: clear annotations', () => {
test('clear annotations in a task', async () => { test('clear annotations in a task', async () => {
const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const task = (await window.cvat.tasks.get({ id: 100 }))[0];
let annotations = await task.annotations.get(0); let annotations = await task.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
await task.annotations.clear(); await task.annotations.clear();
annotations = await task.annotations.get(0); annotations = await task.annotations.get(0);
expect(annotations.length).toBe(0); expect(annotations).toHaveLength(0);
}); });
test('clear annotations in a job', async () => { test('clear annotations in a job', async () => {
const job = (await window.cvat.jobs.get({ jobID: 100 }))[0]; const job = (await window.cvat.jobs.get({ jobID: 100 }))[0];
let annotations = await job.annotations.get(0); let annotations = await job.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
await job.annotations.clear(); await job.annotations.clear();
annotations = await job.annotations.get(0); annotations = await job.annotations.get(0);
expect(annotations.length).toBe(0); expect(annotations).toHaveLength(0);
}); });
test('clear annotations with reload in a task', async () => { test('clear annotations with reload in a task', async () => {
const task = (await window.cvat.tasks.get({ id: 100 }))[0]; const task = (await window.cvat.tasks.get({ id: 100 }))[0];
let annotations = await task.annotations.get(0); let annotations = await task.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
annotations[0].occluded = true; annotations[0].occluded = true;
await annotations[0].save(); await annotations[0].save();
expect(task.annotations.hasUnsavedChanges()).toBe(true); expect(task.annotations.hasUnsavedChanges()).toBe(true);
await task.annotations.clear(true); await task.annotations.clear(true);
annotations = await task.annotations.get(0); annotations = await task.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
expect(task.annotations.hasUnsavedChanges()).toBe(false); expect(task.annotations.hasUnsavedChanges()).toBe(false);
}); });
test('clear annotations with reload in a job', async () => { test('clear annotations with reload in a job', async () => {
const job = (await window.cvat.jobs.get({ jobID: 100 }))[0]; const job = (await window.cvat.jobs.get({ jobID: 100 }))[0];
let annotations = await job.annotations.get(0); let annotations = await job.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
annotations[0].occluded = true; annotations[0].occluded = true;
await annotations[0].save(); await annotations[0].save();
expect(job.annotations.hasUnsavedChanges()).toBe(true); expect(job.annotations.hasUnsavedChanges()).toBe(true);
await job.annotations.clear(true); await job.annotations.clear(true);
annotations = await job.annotations.get(0); annotations = await job.annotations.get(0);
expect(annotations.length).not.toBe(0); expect(annotations).not.toHaveLength(0);
expect(job.annotations.hasUnsavedChanges()).toBe(false); expect(job.annotations.hasUnsavedChanges()).toBe(false);
}); });
@ -714,16 +714,16 @@ describe('Feature: select object', () => {
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.RECTANGLE); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.RECTANGLE);
result = await task.annotations.select(annotations, 1415, 765); result = await task.annotations.select(annotations, 1415, 765);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON);
expect(result.state.points.length).toBe(10); expect(result.state.points).toHaveLength(10);
result = await task.annotations.select(annotations, 1083, 543); result = await task.annotations.select(annotations, 1083, 543);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POINTS); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POINTS);
expect(result.state.points.length).toBe(16); expect(result.state.points).toHaveLength(16);
result = await task.annotations.select(annotations, 613, 811); result = await task.annotations.select(annotations, 613, 811);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON);
expect(result.state.points.length).toBe(94); expect(result.state.points).toHaveLength(94);
result = await task.annotations.select(annotations, 600, 900); result = await task.annotations.select(annotations, 600, 900);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.CUBOID); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.CUBOID);
expect(result.state.points.length).toBe(16); expect(result.state.points).toHaveLength(16);
}); });
test('select object in a job', async () => { test('select object in a job', async () => {
@ -737,10 +737,10 @@ describe('Feature: select object', () => {
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.RECTANGLE); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.RECTANGLE);
result = await job.annotations.select(annotations, 1490, 237); result = await job.annotations.select(annotations, 1490, 237);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.POLYGON);
expect(result.state.points.length).toBe(94); expect(result.state.points).toHaveLength(94);
result = await job.annotations.select(annotations, 600, 900); result = await job.annotations.select(annotations, 600, 900);
expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.CUBOID); expect(result.state.shapeType).toBe(window.cvat.enums.ObjectShape.CUBOID);
expect(result.state.points.length).toBe(16); expect(result.state.points).toHaveLength(16);
}); });
test('trying to select from not object states', async () => { test('trying to select from not object states', async () => {

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -69,7 +69,6 @@ const plugin = {
}, },
}; };
async function test() { async function test() {
await window.cvat.plugins.register(plugin); await window.cvat.plugins.register(plugin);
await window.cvat.server.login('admin', 'nimda760'); await window.cvat.server.login('admin', 'nimda760');

@ -99,7 +99,7 @@ describe('Feature: save a project', () => {
const labelsLength = result[0].labels.length; const labelsLength = result[0].labels.length;
const newLabel = new window.cvat.classes.Label({ const newLabel = new window.cvat.classes.Label({
name: "My boss's car", name: 'My boss\'s car',
attributes: [ attributes: [
{ {
default_value: 'false', default_value: 'false',
@ -119,7 +119,7 @@ describe('Feature: save a project', () => {
}); });
expect(result[0].labels).toHaveLength(labelsLength + 1); expect(result[0].labels).toHaveLength(labelsLength + 1);
const appendedLabel = result[0].labels.filter((el) => el.name === "My boss's car"); const appendedLabel = result[0].labels.filter((el) => el.name === 'My boss\'s car');
expect(appendedLabel).toHaveLength(1); expect(appendedLabel).toHaveLength(1);
expect(appendedLabel[0].attributes).toHaveLength(1); expect(appendedLabel[0].attributes).toHaveLength(1);
expect(appendedLabel[0].attributes[0].name).toBe('parked'); expect(appendedLabel[0].attributes[0].name).toBe('parked');

@ -115,7 +115,7 @@ describe('Feature: save a task', () => {
const labelsLength = result[0].labels.length; const labelsLength = result[0].labels.length;
const newLabel = new window.cvat.classes.Label({ const newLabel = new window.cvat.classes.Label({
name: "My boss's car", name: 'My boss\'s car',
attributes: [ attributes: [
{ {
default_value: 'false', default_value: 'false',
@ -135,7 +135,7 @@ describe('Feature: save a task', () => {
}); });
expect(result[0].labels).toHaveLength(labelsLength + 1); expect(result[0].labels).toHaveLength(labelsLength + 1);
const appendedLabel = result[0].labels.filter((el) => el.name === "My boss's car"); const appendedLabel = result[0].labels.filter((el) => el.name === 'My boss\'s car');
expect(appendedLabel).toHaveLength(1); expect(appendedLabel).toHaveLength(1);
expect(appendedLabel[0].attributes).toHaveLength(1); expect(appendedLabel[0].attributes).toHaveLength(1);
expect(appendedLabel[0].attributes[0].name).toBe('parked'); expect(appendedLabel[0].attributes[0].name).toBe('parked');
@ -149,7 +149,7 @@ describe('Feature: save a task', () => {
name: 'New Task', name: 'New Task',
labels: [ labels: [
{ {
name: "My boss's car", name: 'My boss\'s car',
attributes: [ attributes: [
{ {
default_value: 'false', default_value: 'false',

@ -1,2 +0,0 @@
**/3rdparty/*.js
webpack.config.js

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -8,36 +8,5 @@ module.exports = {
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2018, ecmaVersion: 2018,
}, },
plugins: ['security', 'no-unsanitized', 'no-unsafe-innerhtml'], ignorePatterns: ['.eslintrc.js', 'webpack.config.js', 'src/3rdparty/**', 'node_modules/**', 'dist/**'],
extends: ['eslint:recommended', 'plugin:security/recommended', 'plugin:no-unsanitized/DOM', 'airbnb-base'],
rules: {
'no-await-in-loop': [0],
'global-require': [0],
'no-new': [0],
'class-methods-use-this': [0],
'no-restricted-properties': [
0,
{
object: 'Math',
property: 'pow',
},
],
'no-plusplus': [0],
'no-param-reassign': [0],
'no-underscore-dangle': ['error', { allowAfterThis: true }],
'no-restricted-syntax': [0, { selector: 'ForOfStatement' }],
'no-continue': [0],
'no-unsafe-innerhtml/no-unsafe-innerhtml': 1,
// This rule actual for user input data on the node.js environment mainly.
'security/detect-object-injection': 0,
indent: ['warn', 4],
'no-useless-constructor': 0,
'func-names': [0],
'valid-typeof': [0],
'no-console': [0],
'max-classes-per-file': [0],
'max-len': ['error', { code: 120 }],
quotes: ['error', 'single'],
'operator-linebreak': ['error', 'after'],
},
}; };

@ -1 +0,0 @@
dist

@ -313,13 +313,14 @@ class FrameProvider {
const createImageBitmap = async function (blob) { const createImageBitmap = async function (blob) {
return new Promise((resolve) => { return new Promise((resolve) => {
const img = document.createElement('img'); const img = document.createElement('img');
img.addEventListener('load', function () { img.addEventListener('load', function loadListener() {
resolve(this); resolve(this);
}); });
img.src = URL.createObjectURL(blob); img.src = URL.createObjectURL(blob);
}); });
}; };
// eslint-disable-next-line
event.data.data = await createImageBitmap(event.data.data); event.data.data = await createImageBitmap(event.data.data);
} }

@ -2,6 +2,8 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
const globalConfig = require('../.eslintrc.js');
module.exports = { module.exports = {
env: { env: {
node: true, node: true,
@ -12,38 +14,22 @@ module.exports = {
project: './tsconfig.json', project: './tsconfig.json',
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
}, },
plugins: ['@typescript-eslint', 'import'], ignorePatterns: [
extends: [ '.eslintrc.js',
'plugin:@typescript-eslint/recommended', 'webpack.config.js',
'airbnb-typescript', 'node_modules/**',
'plugin:import/errors', 'dist/**',
'plugin:import/warnings',
'plugin:import/typescript',
], ],
ignorePatterns: ['.eslintrc.js'], plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended', 'airbnb-typescript'],
rules: { rules: {
'@typescript-eslint/indent': ['warn', 4], ...globalConfig.rules,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/indent': ['error', 4],
'@typescript-eslint/lines-between-class-members': 0, '@typescript-eslint/lines-between-class-members': 0,
'react/static-property-placement': ['error', 'static public field'],
'react/jsx-indent': ['warn', 4],
'react/jsx-indent-props': ['warn', 4],
'react/jsx-props-no-spreading': 0,
'implicit-arrow-linebreak': 0,
'jsx-quotes': ['error', 'prefer-single'],
'arrow-parens': ['error', 'always'],
'@typescript-eslint/no-explicit-any': [0], '@typescript-eslint/no-explicit-any': [0],
'@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }], '@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }],
'no-restricted-syntax': [0, { selector: 'ForOfStatement' }],
'no-plusplus': [0],
'lines-between-class-members': [0],
'react/no-did-update-set-state': 0, // https://github.com/airbnb/javascript/issues/1875
quotes: ['error', 'single'],
'max-len': ['error', { code: 120, ignoreStrings: true }],
'func-names': ['warn', 'never'],
'operator-linebreak': ['error', 'after'],
'react/require-default-props': 'off',
'react/no-unused-prop-types': 'off',
'react/no-array-index-key': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-types': [ '@typescript-eslint/ban-types': [
'error', 'error',
@ -55,18 +41,22 @@ module.exports = {
}, },
}, },
], ],
'import/order': [
'error', 'react/no-did-update-set-state': 0, // https://github.com/airbnb/javascript/issues/1875
{ 'react/require-default-props': 'off',
'groups': ['builtin', 'external', 'internal'], 'react/no-unused-prop-types': 'off',
} 'react/no-array-index-key': 'off',
] 'react/static-property-placement': ['error', 'static public field'],
}, 'react/jsx-indent': ['warn', 4],
settings: { 'react/jsx-indent-props': ['warn', 4],
'import/resolver': { 'react/jsx-props-no-spreading': 0,
node: { 'jsx-quotes': ['error', 'prefer-single'],
paths: ['src', `${__dirname}/src`],
},
},
}, },
// settings: {
// 'import/resolver': {
// node: {
// paths: ['src', `${__dirname}/src`],
// },
// },
// },
}; };

@ -1,8 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
/node_modules
/dist
/build
/yarn.lock
.eslintcache

@ -637,18 +637,17 @@ export function getPredictionsAsync(): ThunkAction {
return; return;
} }
annotations = annotations.map( annotations = annotations.map(
(data: any): any => (data: any): any => new cvat.classes.ObjectState({
new cvat.classes.ObjectState({ shapeType: data.type,
shapeType: data.type, label: job.task.labels.filter((label: any): boolean => label.id === data.label)[0],
label: job.task.labels.filter((label: any): boolean => label.id === data.label)[0], points: data.points,
points: data.points, objectType: ObjectType.SHAPE,
objectType: ObjectType.SHAPE, frame,
frame, occluded: false,
occluded: false, source: 'auto',
source: 'auto', attributes: {},
attributes: {}, zOrder: curZOrder,
zOrder: curZOrder, }),
}),
); );
dispatch({ dispatch({

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -51,8 +51,9 @@ export const authActions = {
changePassword: () => createAction(AuthActionTypes.CHANGE_PASSWORD), changePassword: () => createAction(AuthActionTypes.CHANGE_PASSWORD),
changePasswordSuccess: () => createAction(AuthActionTypes.CHANGE_PASSWORD_SUCCESS), changePasswordSuccess: () => createAction(AuthActionTypes.CHANGE_PASSWORD_SUCCESS),
changePasswordFailed: (error: any) => createAction(AuthActionTypes.CHANGE_PASSWORD_FAILED, { error }), changePasswordFailed: (error: any) => createAction(AuthActionTypes.CHANGE_PASSWORD_FAILED, { error }),
switchChangePasswordDialog: (showChangePasswordDialog: boolean) => switchChangePasswordDialog: (showChangePasswordDialog: boolean) => (
createAction(AuthActionTypes.SWITCH_CHANGE_PASSWORD_DIALOG, { showChangePasswordDialog }), createAction(AuthActionTypes.SWITCH_CHANGE_PASSWORD_DIALOG, { showChangePasswordDialog })
),
requestPasswordReset: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET), requestPasswordReset: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET),
requestPasswordResetSuccess: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_SUCCESS), requestPasswordResetSuccess: () => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_SUCCESS),
requestPasswordResetFailed: (error: any) => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_FAILED, { error }), requestPasswordResetFailed: (error: any) => createAction(AuthActionTypes.REQUEST_PASSWORD_RESET_FAILED, { error }),
@ -60,11 +61,12 @@ export const authActions = {
resetPasswordSuccess: () => createAction(AuthActionTypes.RESET_PASSWORD_SUCCESS), resetPasswordSuccess: () => createAction(AuthActionTypes.RESET_PASSWORD_SUCCESS),
resetPasswordFailed: (error: any) => createAction(AuthActionTypes.RESET_PASSWORD_FAILED, { error }), resetPasswordFailed: (error: any) => createAction(AuthActionTypes.RESET_PASSWORD_FAILED, { error }),
loadServerAuthActions: () => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS), loadServerAuthActions: () => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS),
loadServerAuthActionsSuccess: (allowChangePassword: boolean, allowResetPassword: boolean) => loadServerAuthActionsSuccess: (allowChangePassword: boolean, allowResetPassword: boolean) => (
createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_SUCCESS, { createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_SUCCESS, {
allowChangePassword, allowChangePassword,
allowResetPassword, allowResetPassword,
}), })
),
loadServerAuthActionsFailed: (error: any) => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_FAILED, { error }), loadServerAuthActionsFailed: (error: any) => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_FAILED, { error }),
}; };

@ -25,16 +25,15 @@ export const boundariesActions = {
minZ: number, minZ: number,
maxZ: number, maxZ: number,
colors: string[], colors: string[],
) => ) => createAction(BoundariesActionTypes.RESET_AFTER_ERROR, {
createAction(BoundariesActionTypes.RESET_AFTER_ERROR, { job,
job, states,
states, frameNumber,
frameNumber, frameData,
frameData, minZ,
minZ, maxZ,
maxZ, colors,
colors, }),
}),
throwResetError: () => createAction(BoundariesActionTypes.THROW_RESET_ERROR), throwResetError: () => createAction(BoundariesActionTypes.THROW_RESET_ERROR),
}; };

@ -35,53 +35,68 @@ export enum CloudStorageActionTypes {
} }
const cloudStoragesActions = { const cloudStoragesActions = {
updateCloudStoragesGettingQuery: (query: Partial<CloudStoragesQuery>) => updateCloudStoragesGettingQuery: (query: Partial<CloudStoragesQuery>) => (
createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGES_GETTING_QUERY, { query }), createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGES_GETTING_QUERY, { query })
),
getCloudStorages: () => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGES), getCloudStorages: () => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGES),
getCloudStoragesSuccess: ( getCloudStoragesSuccess: (
array: any[], array: any[],
count: number, count: number,
query: Partial<CloudStoragesQuery>, query: Partial<CloudStoragesQuery>,
) => ) => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_SUCCESS, {
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_SUCCESS, { array,
array, count,
count, query,
query, }),
}), getCloudStoragesFailed: (error: any, query: Partial<CloudStoragesQuery>) => (
getCloudStoragesFailed: (error: any, query: Partial<CloudStoragesQuery>) => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_FAILED, { error, query })
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_FAILED, { error, query }), ),
deleteCloudStorage: (cloudStorageID: number) => deleteCloudStorage: (cloudStorageID: number) => (
createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE, { cloudStorageID }), createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE, { cloudStorageID })
deleteCloudStorageSuccess: (cloudStorageID: number) => ),
createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE_SUCCESS, { cloudStorageID }), deleteCloudStorageSuccess: (cloudStorageID: number) => (
deleteCloudStorageFailed: (error: any, cloudStorageID: number) => createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE_SUCCESS, { cloudStorageID })
createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE_FAILED, { error, cloudStorageID }), ),
deleteCloudStorageFailed: (error: any, cloudStorageID: number) => (
createAction(CloudStorageActionTypes.DELETE_CLOUD_STORAGE_FAILED, { error, cloudStorageID })
),
createCloudStorage: () => createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE), createCloudStorage: () => createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE),
createCloudStorageSuccess: (cloudStorageID: number) => createCloudStorageSuccess: (cloudStorageID: number) => (
createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE_SUCCESS, { cloudStorageID }), createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE_SUCCESS, { cloudStorageID })
createCloudStorageFailed: (error: any) => ),
createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE_FAILED, { error }), createCloudStorageFailed: (error: any) => (
createAction(CloudStorageActionTypes.CREATE_CLOUD_STORAGE_FAILED, { error })
),
updateCloudStorage: () => createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE, {}), updateCloudStorage: () => createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE, {}),
updateCloudStorageSuccess: (cloudStorage: CloudStorage) => updateCloudStorageSuccess: (cloudStorage: CloudStorage) => (
createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE_SUCCESS, { cloudStorage }), createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE_SUCCESS, { cloudStorage })
updateCloudStorageFailed: (cloudStorage: CloudStorage, error: any) => ),
createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE_FAILED, { cloudStorage, error }), updateCloudStorageFailed: (cloudStorage: CloudStorage, error: any) => (
createAction(CloudStorageActionTypes.UPDATE_CLOUD_STORAGE_FAILED, { cloudStorage, error })
),
loadCloudStorageContent: () => createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT), loadCloudStorageContent: () => createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT),
loadCloudStorageContentSuccess: (cloudStorageID: number, content: any) => loadCloudStorageContentSuccess: (cloudStorageID: number, content: any) => (
createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT_SUCCESS, { cloudStorageID, content }), createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT_SUCCESS, { cloudStorageID, content })
loadCloudStorageContentFailed: (cloudStorageID: number, error: any) => ),
createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT_FAILED, { cloudStorageID, error }), loadCloudStorageContentFailed: (cloudStorageID: number, error: any) => (
createAction(CloudStorageActionTypes.LOAD_CLOUD_STORAGE_CONTENT_FAILED, { cloudStorageID, error })
),
getCloudStorageStatus: (id: number) => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS, { id }), getCloudStorageStatus: (id: number) => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS, { id }),
getCloudStorageStatusSuccess: (cloudStorageID: number, status: string) => getCloudStorageStatusSuccess: (cloudStorageID: number, status: string) => (
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS_SUCCESS, { cloudStorageID, status }), createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS_SUCCESS, { cloudStorageID, status })
getCloudStorageStatusFailed: (cloudStorageID: number, error: any) => ),
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS_FAILED, { cloudStorageID, error }), getCloudStorageStatusFailed: (cloudStorageID: number, error: any) => (
getCloudStoragePreiew: (cloudStorageID: number) => createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_STATUS_FAILED, { cloudStorageID, error })
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW, { cloudStorageID }), ),
getCloudStoragePreiewSuccess: (cloudStorageID: number, preview: string) => getCloudStoragePreiew: (cloudStorageID: number) => (
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW_SUCCESS, { cloudStorageID, preview }), createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW, { cloudStorageID })
getCloudStoragePreiewFailed: (cloudStorageID: number, error: any) => ),
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW_FAILED, { cloudStorageID, error }), getCloudStoragePreiewSuccess: (cloudStorageID: number, preview: string) => (
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW_SUCCESS, { cloudStorageID, preview })
),
getCloudStoragePreiewFailed: (cloudStorageID: number, error: any) => (
createAction(CloudStorageActionTypes.GET_CLOUD_STORAGE_PREVIEW_FAILED, { cloudStorageID, error })
),
}; };
export type CloudStorageActions = ActionUnion<typeof cloudStoragesActions>; export type CloudStorageActions = ActionUnion<typeof cloudStoragesActions>;

@ -15,16 +15,19 @@ export enum ExportActionTypes {
export const exportActions = { export const exportActions = {
openExportModal: (instance: any) => createAction(ExportActionTypes.OPEN_EXPORT_MODAL, { instance }), openExportModal: (instance: any) => createAction(ExportActionTypes.OPEN_EXPORT_MODAL, { instance }),
closeExportModal: () => createAction(ExportActionTypes.CLOSE_EXPORT_MODAL), closeExportModal: () => createAction(ExportActionTypes.CLOSE_EXPORT_MODAL),
exportDataset: (instance: any, format: string) => exportDataset: (instance: any, format: string) => (
createAction(ExportActionTypes.EXPORT_DATASET, { instance, format }), createAction(ExportActionTypes.EXPORT_DATASET, { instance, format })
exportDatasetSuccess: (instance: any, format: string) => ),
createAction(ExportActionTypes.EXPORT_DATASET_SUCCESS, { instance, format }), exportDatasetSuccess: (instance: any, format: string) => (
exportDatasetFailed: (instance: any, format: string, error: any) => createAction(ExportActionTypes.EXPORT_DATASET_SUCCESS, { instance, format })
),
exportDatasetFailed: (instance: any, format: string, error: any) => (
createAction(ExportActionTypes.EXPORT_DATASET_FAILED, { createAction(ExportActionTypes.EXPORT_DATASET_FAILED, {
instance, instance,
format, format,
error, error,
}), })
),
}; };
export const exportDatasetAsync = ( export const exportDatasetAsync = (

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -15,10 +15,11 @@ export enum FormatsActionTypes {
const formatsActions = { const formatsActions = {
getFormats: () => createAction(FormatsActionTypes.GET_FORMATS), getFormats: () => createAction(FormatsActionTypes.GET_FORMATS),
getFormatsSuccess: (annotationFormats: any) => getFormatsSuccess: (annotationFormats: any) => (
createAction(FormatsActionTypes.GET_FORMATS_SUCCESS, { createAction(FormatsActionTypes.GET_FORMATS_SUCCESS, {
annotationFormats, annotationFormats,
}), })
),
getFormatsFailed: (error: any) => createAction(FormatsActionTypes.GET_FORMATS_FAILED, { error }), getFormatsFailed: (error: any) => createAction(FormatsActionTypes.GET_FORMATS_FAILED, { error }),
}; };

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -22,44 +22,48 @@ export enum ModelsActionTypes {
export const modelsActions = { export const modelsActions = {
getModels: () => createAction(ModelsActionTypes.GET_MODELS), getModels: () => createAction(ModelsActionTypes.GET_MODELS),
getModelsSuccess: (models: Model[]) => getModelsSuccess: (models: Model[]) => createAction(ModelsActionTypes.GET_MODELS_SUCCESS, {
createAction(ModelsActionTypes.GET_MODELS_SUCCESS, { models,
models, }),
}), getModelsFailed: (error: any) => createAction(ModelsActionTypes.GET_MODELS_FAILED, {
getModelsFailed: (error: any) => error,
createAction(ModelsActionTypes.GET_MODELS_FAILED, { }),
error,
}),
fetchMetaFailed: (error: any) => createAction(ModelsActionTypes.FETCH_META_FAILED, { error }), fetchMetaFailed: (error: any) => createAction(ModelsActionTypes.FETCH_META_FAILED, { error }),
getInferenceStatusSuccess: (taskID: number, activeInference: ActiveInference) => getInferenceStatusSuccess: (taskID: number, activeInference: ActiveInference) => (
createAction(ModelsActionTypes.GET_INFERENCE_STATUS_SUCCESS, { createAction(ModelsActionTypes.GET_INFERENCE_STATUS_SUCCESS, {
taskID, taskID,
activeInference, activeInference,
}), })
getInferenceStatusFailed: (taskID: number, error: any) => ),
getInferenceStatusFailed: (taskID: number, error: any) => (
createAction(ModelsActionTypes.GET_INFERENCE_STATUS_FAILED, { createAction(ModelsActionTypes.GET_INFERENCE_STATUS_FAILED, {
taskID, taskID,
error, error,
}), })
startInferenceFailed: (taskID: number, error: any) => ),
startInferenceFailed: (taskID: number, error: any) => (
createAction(ModelsActionTypes.START_INFERENCE_FAILED, { createAction(ModelsActionTypes.START_INFERENCE_FAILED, {
taskID, taskID,
error, error,
}), })
cancelInferenceSuccess: (taskID: number) => ),
cancelInferenceSuccess: (taskID: number) => (
createAction(ModelsActionTypes.CANCEL_INFERENCE_SUCCESS, { createAction(ModelsActionTypes.CANCEL_INFERENCE_SUCCESS, {
taskID, taskID,
}), })
cancelInferenceFailed: (taskID: number, error: any) => ),
cancelInferenceFailed: (taskID: number, error: any) => (
createAction(ModelsActionTypes.CANCEL_INFERENCE_FAILED, { createAction(ModelsActionTypes.CANCEL_INFERENCE_FAILED, {
taskID, taskID,
error, error,
}), })
),
closeRunModelDialog: () => createAction(ModelsActionTypes.CLOSE_RUN_MODEL_DIALOG), closeRunModelDialog: () => createAction(ModelsActionTypes.CLOSE_RUN_MODEL_DIALOG),
showRunModelDialog: (taskInstance: any) => showRunModelDialog: (taskInstance: any) => (
createAction(ModelsActionTypes.SHOW_RUN_MODEL_DIALOG, { createAction(ModelsActionTypes.SHOW_RUN_MODEL_DIALOG, {
taskInstance, taskInstance,
}), })
),
}; };
export type ModelsActions = ActionUnion<typeof modelsActions>; export type ModelsActions = ActionUnion<typeof modelsActions>;

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -32,14 +32,17 @@ export enum ReviewActionTypes {
} }
export const reviewActions = { export const reviewActions = {
initializeReviewSuccess: (reviewInstance: any, frame: number) => initializeReviewSuccess: (reviewInstance: any, frame: number) => (
createAction(ReviewActionTypes.INITIALIZE_REVIEW_SUCCESS, { reviewInstance, frame }), createAction(ReviewActionTypes.INITIALIZE_REVIEW_SUCCESS, { reviewInstance, frame })
),
initializeReviewFailed: (error: any) => createAction(ReviewActionTypes.INITIALIZE_REVIEW_FAILED, { error }), initializeReviewFailed: (error: any) => createAction(ReviewActionTypes.INITIALIZE_REVIEW_FAILED, { error }),
createIssue: () => createAction(ReviewActionTypes.CREATE_ISSUE, {}), createIssue: () => createAction(ReviewActionTypes.CREATE_ISSUE, {}),
startIssue: (position: number[]) => startIssue: (position: number[]) => (
createAction(ReviewActionTypes.START_ISSUE, { position: cvat.classes.Issue.hull(position) }), createAction(ReviewActionTypes.START_ISSUE, { position: cvat.classes.Issue.hull(position) })
finishIssueSuccess: (frame: number, issue: any) => ),
createAction(ReviewActionTypes.FINISH_ISSUE_SUCCESS, { frame, issue }), finishIssueSuccess: (frame: number, issue: any) => (
createAction(ReviewActionTypes.FINISH_ISSUE_SUCCESS, { frame, issue })
),
finishIssueFailed: (error: any) => createAction(ReviewActionTypes.FINISH_ISSUE_FAILED, { error }), finishIssueFailed: (error: any) => createAction(ReviewActionTypes.FINISH_ISSUE_FAILED, { error }),
cancelIssue: () => createAction(ReviewActionTypes.CANCEL_ISSUE), cancelIssue: () => createAction(ReviewActionTypes.CANCEL_ISSUE),
commentIssue: (issueId: number) => createAction(ReviewActionTypes.COMMENT_ISSUE, { issueId }), commentIssue: (issueId: number) => createAction(ReviewActionTypes.COMMENT_ISSUE, { issueId }),

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -17,11 +17,12 @@ export enum ShareActionTypes {
const shareActions = { const shareActions = {
loadShareData: () => createAction(ShareActionTypes.LOAD_SHARE_DATA), loadShareData: () => createAction(ShareActionTypes.LOAD_SHARE_DATA),
loadShareDataSuccess: (values: ShareFileInfo[], directory: string) => loadShareDataSuccess: (values: ShareFileInfo[], directory: string) => (
createAction(ShareActionTypes.LOAD_SHARE_DATA_SUCCESS, { createAction(ShareActionTypes.LOAD_SHARE_DATA_SUCCESS, {
values, values,
directory, directory,
}), })
),
loadShareDataFailed: (error: any) => createAction(ShareActionTypes.LOAD_SHARE_DATA_FAILED, { error }), loadShareDataFailed: (error: any) => createAction(ShareActionTypes.LOAD_SHARE_DATA_FAILED, { error }),
}; };

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -16,10 +16,12 @@ export enum UserAgreementsActionTypes {
const userAgreementsActions = { const userAgreementsActions = {
getUserAgreements: () => createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS), getUserAgreements: () => createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS),
getUserAgreementsSuccess: (userAgreements: UserAgreement[]) => getUserAgreementsSuccess: (userAgreements: UserAgreement[]) => (
createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_SUCCESS, userAgreements), createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_SUCCESS, userAgreements)
getUserAgreementsFailed: (error: any) => ),
createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_FAILED, { error }), getUserAgreementsFailed: (error: any) => (
createAction(UserAgreementsActionTypes.GET_USER_AGREEMENTS_FAILED, { error })
),
}; };
export type UserAgreementsActions = ActionUnion<typeof userAgreementsActions>; export type UserAgreementsActions = ActionUnion<typeof userAgreementsActions>;

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -113,11 +113,10 @@ export default function (state: ReviewState = defaultState, action: any): Review
Array.from( Array.from(
new Set( new Set(
[...state.latestComments, issue.comments[0].message].filter( [...state.latestComments, issue.comments[0].message].filter(
(message: string): boolean => (message: string): boolean => ![
![ consts.QUICK_ISSUE_INCORRECT_POSITION_TEXT,
consts.QUICK_ISSUE_INCORRECT_POSITION_TEXT, consts.QUICK_ISSUE_INCORRECT_ATTRIBUTE_TEXT,
consts.QUICK_ISSUE_INCORRECT_ATTRIBUTE_TEXT, ].includes(message),
].includes(message),
), ),
), ),
).slice(-consts.LATEST_COMMENTS_SHOWN_QUICK_ISSUE), ).slice(-consts.LATEST_COMMENTS_SHOWN_QUICK_ISSUE),

@ -36,7 +36,7 @@ export default function createRootReducer(): Reducer {
shortcuts: shortcutsReducer, shortcuts: shortcutsReducer,
userAgreements: userAgreementsReducer, userAgreements: userAgreementsReducer,
review: reviewReducer, review: reviewReducer,
export: exportReducer, export: exportReducer,
cloudStorages: cloudStoragesReducer, cloudStorages: cloudStoragesReducer,
}); });
} }

@ -11,12 +11,14 @@ const os = platform.os ? platform.os.toString() : 'unknown';
let platformNotificationShown = window.localStorage.getItem('platformNotiticationShown') !== null; let platformNotificationShown = window.localStorage.getItem('platformNotiticationShown') !== null;
let featuresNotificationShown = window.localStorage.getItem('featuresNotificationShown') !== null; let featuresNotificationShown = window.localStorage.getItem('featuresNotificationShown') !== null;
export function platformInfo(): { interface PlatformInfo {
engine: string; engine: string;
name: string; name: string;
version: string; version: string;
os: string; os: string;
} { }
export function platformInfo(): PlatformInfo {
return { return {
engine, engine,
name, name,

@ -12,11 +12,6 @@ function makePattern(extension) {
module.exports = (stagedFiles) => { module.exports = (stagedFiles) => {
const eslintExtensions = ['ts', 'tsx', 'js'].map(makePattern); const eslintExtensions = ['ts', 'tsx', 'js'].map(makePattern);
const prettierExtensions = ['html', 'css', 'scss', 'json', 'yaml', 'yml', 'md']
.map(makePattern)
.concat(eslintExtensions);
const prettierFiles = micromatch(stagedFiles, prettierExtensions);
const eslintFiles = micromatch(stagedFiles, eslintExtensions); const eslintFiles = micromatch(stagedFiles, eslintExtensions);
const cvatData = containsInPath('/cvat-data/', eslintFiles); const cvatData = containsInPath('/cvat-data/', eslintFiles);
@ -27,7 +22,6 @@ module.exports = (stagedFiles) => {
const mapping = {}; const mapping = {};
const commands = []; const commands = [];
mapping['prettier --write '] = prettierFiles.join(' ');
mapping['npm run precommit:cvat-ui -- '] = cvatUI.join(' '); mapping['npm run precommit:cvat-ui -- '] = cvatUI.join(' ');
mapping['npm run precommit:cvat-data -- '] = cvatData.join(' '); mapping['npm run precommit:cvat-data -- '] = cvatData.join(' ');
mapping['npm run precommit:cvat-core -- '] = cvatCore.join(' '); mapping['npm run precommit:cvat-core -- '] = cvatCore.join(' ');

47812
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -41,15 +41,12 @@
"eslint-config-airbnb": "^18.0.1", "eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "14.2.1", "eslint-config-airbnb-base": "14.2.1",
"eslint-config-airbnb-typescript": "^12.0.0", "eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-cypress": "^2.11.2", "eslint-plugin-cypress": "^2.11.2",
"eslint-plugin-header": "^3.1.0", "eslint-plugin-header": "^3.1.0",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.0", "eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-no-unsafe-innerhtml": "^1.0.16",
"eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-no-unsanitized": "^3.0.2",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.21.5", "eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-security": "^1.4.0", "eslint-plugin-security": "^1.4.0",
@ -61,7 +58,6 @@
"nyc": "^15.1.0", "nyc": "^15.1.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"prettier": "2.1.2",
"react-svg-loader": "^3.0.3", "react-svg-loader": "^3.0.3",
"remark-cli": "^9.0.0", "remark-cli": "^9.0.0",
"remark-frontmatter": "^3.0.0", "remark-frontmatter": "^3.0.0",
@ -99,10 +95,10 @@
"cp": "cp -r cvat-ui_cov/* cvat-ui && cp -r cvat-canvas_cov/* cvat-canvas && cp -r cvat-data_cov/* cvat-data && cp -r cvat-core_cov/* cvat-core", "cp": "cp -r cvat-ui_cov/* cvat-ui && cp -r cvat-canvas_cov/* cvat-canvas && cp -r cvat-data_cov/* cvat-data && cp -r cvat-core_cov/* cvat-core",
"rm": "rm -rf cvat-ui_cov cvat-canvas_cov cvat-data_cov cvat-core_cov", "rm": "rm -rf cvat-ui_cov cvat-canvas_cov cvat-data_cov cvat-core_cov",
"prepare": "husky install && rm .husky/pre-commit; npx husky add .husky/pre-commit \"npx lint-staged\"", "prepare": "husky install && rm .husky/pre-commit; npx husky add .husky/pre-commit \"npx lint-staged\"",
"precommit:cvat-data": "cd cvat-ui && eslint --fix", "precommit:cvat-data": "cd cvat-data && eslint --fix",
"precommit:cvat-core": "cd cvat-ui && eslint --fix", "precommit:cvat-core": "cd cvat-core && eslint --fix",
"precommit:cvat-canvas": "cd cvat-ui && eslint --fix", "precommit:cvat-canvas": "cd cvat-canvas && eslint --fix",
"precommit:cvat-canvas3d": "cd cvat-ui && eslint --fix", "precommit:cvat-canvas3d": "cd cvat-canvas3d && eslint --fix",
"precommit:cvat-ui": "cd cvat-ui && eslint --fix", "precommit:cvat-ui": "cd cvat-ui && eslint --fix",
"build:cvat-ui": "npm run build --workspace=cvat-ui", "build:cvat-ui": "npm run build --workspace=cvat-ui",
"build:cvat-canvas": "npm run build --workspace=cvat-canvas", "build:cvat-canvas": "npm run build --workspace=cvat-canvas",

Loading…
Cancel
Save