Browse Source

Minor refactoring

pull/2729/head
Igor Kulikov 6 years ago
parent
commit
503bca902a
  1. 1320
      msa/js-executor/package-lock.json
  2. 580
      ui-ngx/package-lock.json
  3. 38
      ui-ngx/package.json
  4. 4
      ui-ngx/src/app/core/api/datasource-subcription.ts
  5. 4
      ui-ngx/src/app/core/api/datasource.service.ts
  6. 26
      ui-ngx/src/app/core/services/utils.service.ts
  7. 203
      ui-ngx/src/app/core/utils.ts
  8. 4
      ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts
  9. 4
      ui-ngx/src/app/modules/home/components/widget/lib/entities-hierarchy-widget.component.ts
  10. 4
      ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts
  11. 23
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  12. 6
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts
  13. 12
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts
  14. 175
      ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts
  15. 7
      ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts
  16. 7
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts
  17. 4
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts
  18. 2
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts
  19. 2
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts
  20. 28
      ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts
  21. 4
      ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts
  22. 3
      ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts
  23. 1
      ui-ngx/src/app/shared/pipe/public-api.ts
  24. 25
      ui-ngx/src/app/shared/pipe/template.pipe.ts
  25. 3
      ui-ngx/src/app/shared/shared.module.ts

1320
msa/js-executor/package-lock.json

File diff suppressed because it is too large

580
ui-ngx/package-lock.json

@ -40,21 +40,21 @@
}
},
"@angular-devkit/build-angular": {
"version": "0.901.3",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.3.tgz",
"integrity": "sha512-0ivl+rxiFWY/cWpAhflaJfUmTGNRZn3m4gyt0YNFyHh7oJcwKFVpd9lxJAM4t47Xfyj0ICpTL99UBi4aeo3lEg==",
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.4.tgz",
"integrity": "sha512-Vod4bc6d38fuvqauIDQxKMe9hKW9m4QNzPKxEc+Dv5Xkv95WaGzkbUVu8M8t4E//sDDMpmcPdYOXSdR27WBi2Q==",
"dev": true,
"requires": {
"@angular-devkit/architect": "0.901.3",
"@angular-devkit/build-optimizer": "0.901.3",
"@angular-devkit/build-webpack": "0.901.3",
"@angular-devkit/core": "9.1.3",
"@angular-devkit/architect": "0.901.4",
"@angular-devkit/build-optimizer": "0.901.4",
"@angular-devkit/build-webpack": "0.901.4",
"@angular-devkit/core": "9.1.4",
"@babel/core": "7.9.0",
"@babel/generator": "7.9.3",
"@babel/preset-env": "7.9.0",
"@babel/template": "7.8.6",
"@jsdevtools/coverage-istanbul-loader": "3.0.3",
"@ngtools/webpack": "9.1.3",
"@ngtools/webpack": "9.1.4",
"ajv": "6.12.0",
"autoprefixer": "9.7.4",
"babel-loader": "8.0.6",
@ -108,6 +108,29 @@
"worker-plugin": "4.0.2"
},
"dependencies": {
"@angular-devkit/architect": {
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.4.tgz",
"integrity": "sha512-w4RMj7eLhUSh70HUy5tW4EXjLQFXk0Lfr9WiSy5gvPGp+zzYxknI+Wn4Xid1wU/WS+4tuMv5nJIaNaH2sABESQ==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.4",
"rxjs": "6.5.4"
}
},
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"core-js": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz",
@ -138,9 +161,9 @@
}
},
"@angular-devkit/build-optimizer": {
"version": "0.901.3",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.3.tgz",
"integrity": "sha512-fLRiQ1egH1qsmj5GMJ4ZWawtUYLwpIz1hKJ3WwAIFEFJF2+CDWhO1feUaXZRxPf5qwoj8S+8cSWjdcnKLf/mBw==",
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.4.tgz",
"integrity": "sha512-iDMlNRwd8ICMBKnycfw55hdnL5kCiqUjQn+aK/4uOMJMz49tiYMNJAaznXX2BFKmYSmbapKjEbzx9yMYRi9Y7w==",
"dev": true,
"requires": {
"loader-utils": "2.0.0",
@ -159,16 +182,39 @@
}
},
"@angular-devkit/build-webpack": {
"version": "0.901.3",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.3.tgz",
"integrity": "sha512-tZOiVNCrKaEAo7SuyXPpOoaPy/pbX70G8NFtyhKvoGt5dPbgybWTlibACyzOciBI9wUlGSaJiGPZzKTgL4O5OA==",
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.4.tgz",
"integrity": "sha512-YBOufI4TGAtIDCS6erFygYJX/fkd8xwI58d+7iFIBmtIJC4/fpGjX6qkHMCBgh8HXAkEPSORBCYQn9O44J1ZXQ==",
"dev": true,
"requires": {
"@angular-devkit/architect": "0.901.3",
"@angular-devkit/core": "9.1.3",
"@angular-devkit/architect": "0.901.4",
"@angular-devkit/core": "9.1.4",
"rxjs": "6.5.4"
},
"dependencies": {
"@angular-devkit/architect": {
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.4.tgz",
"integrity": "sha512-w4RMj7eLhUSh70HUy5tW4EXjLQFXk0Lfr9WiSy5gvPGp+zzYxknI+Wn4Xid1wU/WS+4tuMv5nJIaNaH2sABESQ==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.4",
"rxjs": "6.5.4"
}
},
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
@ -205,16 +251,29 @@
}
},
"@angular-devkit/schematics": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.3.tgz",
"integrity": "sha512-nNRoQPqoin5jzLKmTabIPLSqVw2Zjnk78XC4AhAM7rSisWMsZ6pw5+BNDITiKfq0LkSXfOs0DoJV/Vr9mLkn/A==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.4.tgz",
"integrity": "sha512-RAbdnUEZ3JTLmWSBiXT5trsVx8Fi72fxN9CiRaluM09Cytg6BUc1wC5XCO0YPvhI400+3Ro1nwjPXezjg7LXzQ==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.3",
"@angular-devkit/core": "9.1.4",
"ora": "4.0.3",
"rxjs": "6.5.4"
},
"dependencies": {
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
@ -227,29 +286,29 @@
}
},
"@angular/animations": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.3.tgz",
"integrity": "sha512-QTQZSnXxr9SCgrN2SZsTMzS/UldrZ65y6Kuqs9yyghNc694eMbabgiPdeegjvcKlDhVPCN2x9Bjfb1vXPOfdvQ=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.4.tgz",
"integrity": "sha512-gMo/DbCm5BDArladMAeC7/75T2DvhLr4CSUGJt/P/aimTEG2ywoAALs3pzwSSe4qxrHiR0OIksVW3l4km3iXEw=="
},
"@angular/cdk": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.1.tgz",
"integrity": "sha512-aSG1UNPszkSnpNuDCNd7ZgT29oQ8vqHPmoqjvJI0JkEv3i6uEs5tRuhWl3TK39wDNuwdlq0AY47XTa/0Ppb5RQ==",
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.2.tgz",
"integrity": "sha512-VNd+KuMN6cBcy4/8OyMxqYaxdjPP6IyCqIVijB2JREkc5Sg4VWmPgx2L3rHt/DzjsVBVRgx35uqOMymDezG3jQ==",
"requires": {
"parse5": "^5.0.0"
}
},
"@angular/cli": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.1.3.tgz",
"integrity": "sha512-/7yHOuiyMgpcoBuADPrF4Eo9VDysA57fsyrMlOH2WZmKdsjW032StS9EIOue5RNQ7y0DwrtgtnkjbpZ6nYo3Pw==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.1.4.tgz",
"integrity": "sha512-H9MqoT4zyIv+Yo3cvRVkzafWGHsqt7jUvtvGwMHIDMTfEX+Q8yiYlDLL6WM3Eb6/hDmLcRGC/GI495sKS1z5qA==",
"dev": true,
"requires": {
"@angular-devkit/architect": "0.901.3",
"@angular-devkit/core": "9.1.3",
"@angular-devkit/schematics": "9.1.3",
"@schematics/angular": "9.1.3",
"@schematics/update": "0.901.3",
"@angular-devkit/architect": "0.901.4",
"@angular-devkit/core": "9.1.4",
"@angular-devkit/schematics": "9.1.4",
"@schematics/angular": "9.1.4",
"@schematics/update": "0.901.4",
"@yarnpkg/lockfile": "1.1.0",
"ansi-colors": "4.1.1",
"debug": "4.1.1",
@ -267,12 +326,44 @@
"uuid": "7.0.2"
},
"dependencies": {
"@angular-devkit/architect": {
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.4.tgz",
"integrity": "sha512-w4RMj7eLhUSh70HUy5tW4EXjLQFXk0Lfr9WiSy5gvPGp+zzYxknI+Wn4Xid1wU/WS+4tuMv5nJIaNaH2sABESQ==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.4",
"rxjs": "6.5.4"
}
},
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
},
"semver": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz",
@ -288,19 +379,19 @@
}
},
"@angular/common": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.3.tgz",
"integrity": "sha512-OGrd/x+WoceskeJWZI3ur+KqVoBHn2kmbg57RyJ8Ng/BkdDVYiXzQ/UvvX1WYGH/YzmiiVdlnVq55xkHkzGaXw=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.4.tgz",
"integrity": "sha512-JvCoCWVbx0tF7l/0WTi24ui/mc2SElyVSNchR4VK/FViARnkvnSBdI/Ef5QWXrsPyKU4PYBtnWWgyxRspH+FBA=="
},
"@angular/compiler": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.3.tgz",
"integrity": "sha512-NTqGZUwwdm/RIG1rWPIqQwNyyRcPOmNlv+t1KpydFtycpTut0lAh0shiu57h83Cl2LgaFV4veyiAAtNmxFmqXA=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.4.tgz",
"integrity": "sha512-B+f3lviFNEJtL9V9exSKYPSz2Ddb6dxgPzQR7GSjGikDo+fKMtC1PjNwgJooS9gavhQx30uwkEEMIPYQbM6nNA=="
},
"@angular/compiler-cli": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.1.3.tgz",
"integrity": "sha512-FqDPmEbJQmzzxqF08CJfqT9XKJFPYdyZuFFStKkJEZ5s1JrjrBlgQSqdF0qp5jWNsjTB87USLHC5zAlzJtMKxQ==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.1.4.tgz",
"integrity": "sha512-n3PzqNnPD7s/AF9mv5CnarK0sgfoq4txFncHjJWBSltuTQoz6BDZyjuEdqsSLUvgAZPeLsmohemOzEE38HYHZA==",
"dev": true,
"requires": {
"canonical-path": "1.0.0",
@ -501,9 +592,9 @@
}
},
"@angular/core": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.3.tgz",
"integrity": "sha512-r+GyeCuBw9SUBzpPWhKxzTOkNYotYp3gANSWndihLC9P6W5T8Hfyg8uYcxKy7L42bpx8eXZOXFq91cioVwZtqA=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.4.tgz",
"integrity": "sha512-ND240vncmVD2KVe/KSQU3d/DxxoRipFg1+jFOFZGt0n0orCBHk/V1fu9iaG1sRyldL0+rCQ+fTI+1N4DTmMnxA=="
},
"@angular/flex-layout": {
"version": "9.0.0-beta.29",
@ -511,35 +602,35 @@
"integrity": "sha512-93sxR+kYfYMOdnlWL0Q77FZ428gg8XnBu0YZm6GsCdkw/vLggIT/G1ZAqHlCPIODt6pxmCJ5KXh4ShvniIYDsA=="
},
"@angular/forms": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.3.tgz",
"integrity": "sha512-t3BexN5EHgCK6q0R04AuyNb6ZUP6sd9fJ+ER98yWws3HXV6FT+J5IB7dVnhelLoU1GTnql4TJSS+LTVradKZ7g=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.4.tgz",
"integrity": "sha512-Njt+pMLfPBchL0/ayIjJqXL6ZfM4Ccvf7KO1wS1HMzh3QlmfNa0JSgc4pfrbRJAMN9g7V/FYLyKejs1bJZkenA=="
},
"@angular/language-service": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.1.3.tgz",
"integrity": "sha512-mcZDO6C2BpDinMjDeMAdohTefpFxNu/S0JEqewYQIQ8TXtKm77xDPUdNdNb4qD4zYW+c46f7UXNMX/tbYCicQw==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.1.4.tgz",
"integrity": "sha512-eyVxxiegdb4ESdFGfkuDN+YfUbOVHRQLjIl6ACFJQDNHzVXzbmuqpyr5hIJANIVady103/7+dqRxxJo1DdIdTQ==",
"dev": true
},
"@angular/material": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.1.tgz",
"integrity": "sha512-nqn/0Eg04DxwnkRGSM1xnmGgtfHYOBcEPbFeTu8c1qAbjFEozd6tpw4y6dQrCCL/JLNIRQPsxsUsVnKeWDF/4Q=="
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.2.tgz",
"integrity": "sha512-gdQiMJ6PtW/5fd+0mglHFyzxULDCBGjn9RTET3sUq2rkc9+jBXr4OvnsUyBWSnqqv97XqotVDIx5JgE4/YX/Rw=="
},
"@angular/platform-browser": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.3.tgz",
"integrity": "sha512-ts6b7QBp4+UpuQS0Eb+FOT4MZVPUwWtWH4iIfBILJaG/0Bk4jHZeXuLFcpgeZkwMNCZEt9f0JrhnHfvuLCez5g=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.4.tgz",
"integrity": "sha512-mBCHfTl+5tQfaUiGlDujP7mFBzovFc54Zi2kcCE8DSdSSVQ2TPBo6hXa6y2cL3hJPFZzQ7mC4ORFrsGADhHn/w=="
},
"@angular/platform-browser-dynamic": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.3.tgz",
"integrity": "sha512-9U8PkBflnQtKIZ4t0AqYUaKLg7Kx1BvJ1D/S8FZo/V5kBJK6NkGVu58XddWVc+dtO3V+vCC/VLG7fb2PMf/V5g=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.4.tgz",
"integrity": "sha512-YtVbnxyS6FU7xNpA6A95tmSfrB8+WC7OH3mbP8M9NaGk0OYz8B/JOe1HByP4JRpEGCvBtXdJ2NSW/MpLIT8SiQ=="
},
"@angular/router": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.3.tgz",
"integrity": "sha512-NmOazeJ2WVT5eTyNHXYxBRAHic6i6Ku5DgsGWBgjUIR/Qmwb/i/xpagbA9WQQZ2OrGbp4ICEYgGkikeIrlQLPA=="
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.4.tgz",
"integrity": "sha512-yUyjCgG2P2Jh8MvoyC6yirmAtx1Qe7MKLuLvsa9WOB571QNEcNLTYMfAMHUKsQTcE/+o984QyLlneoibgI9wFA=="
},
"@auth0/angular-jwt": {
"version": "4.0.0",
@ -559,12 +650,12 @@
}
},
"@babel/compat-data": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz",
"integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz",
"integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==",
"dev": true,
"requires": {
"browserslist": "^4.9.1",
"browserslist": "^4.11.1",
"invariant": "^2.2.4",
"semver": "^5.5.0"
}
@ -641,13 +732,13 @@
}
},
"@babel/helper-compilation-targets": {
"version": "7.8.7",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz",
"integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz",
"integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.8.6",
"browserslist": "^4.9.1",
"@babel/compat-data": "^7.9.6",
"browserslist": "^4.11.1",
"invariant": "^2.2.4",
"levenary": "^1.1.1",
"semver": "^5.5.0"
@ -785,15 +876,69 @@
}
},
"@babel/helper-replace-supers": {
"version": "7.8.6",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz",
"integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz",
"integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==",
"dev": true,
"requires": {
"@babel/helper-member-expression-to-functions": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/traverse": "^7.8.6",
"@babel/types": "^7.8.6"
"@babel/traverse": "^7.9.6",
"@babel/types": "^7.9.6"
},
"dependencies": {
"@babel/generator": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
"dev": true,
"requires": {
"@babel/types": "^7.9.6",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/parser": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
"dev": true
},
"@babel/traverse": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.9.6",
"@babel/helper-function-name": "^7.9.5",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.9.6",
"@babel/types": "^7.9.6",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.9.5",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
}
},
"@babel/helper-simple-access": {
@ -834,14 +979,68 @@
}
},
"@babel/helpers": {
"version": "7.9.2",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz",
"integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz",
"integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==",
"dev": true,
"requires": {
"@babel/template": "^7.8.3",
"@babel/traverse": "^7.9.0",
"@babel/types": "^7.9.0"
"@babel/traverse": "^7.9.6",
"@babel/types": "^7.9.6"
},
"dependencies": {
"@babel/generator": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
"dev": true,
"requires": {
"@babel/types": "^7.9.6",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/parser": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
"dev": true
},
"@babel/traverse": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.9.6",
"@babel/helper-function-name": "^7.9.5",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.9.6",
"@babel/types": "^7.9.6",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.9.5",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
}
},
"@babel/highlight": {
@ -913,9 +1112,9 @@
}
},
"@babel/plugin-proposal-object-rest-spread": {
"version": "7.9.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz",
"integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz",
"integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
@ -1174,38 +1373,38 @@
}
},
"@babel/plugin-transform-modules-amd": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz",
"integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz",
"integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.9.0",
"@babel/helper-plugin-utils": "^7.8.3",
"babel-plugin-dynamic-import-node": "^2.3.0"
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-commonjs": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz",
"integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz",
"integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.9.0",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-simple-access": "^7.8.3",
"babel-plugin-dynamic-import-node": "^2.3.0"
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-systemjs": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz",
"integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz",
"integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==",
"dev": true,
"requires": {
"@babel/helper-hoist-variables": "^7.8.3",
"@babel/helper-module-transforms": "^7.9.0",
"@babel/helper-plugin-utils": "^7.8.3",
"babel-plugin-dynamic-import-node": "^2.3.0"
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-umd": {
@ -1572,14 +1771,14 @@
"integrity": "sha512-Eqy2vuhgTY+BeqjOiXBBmbGPRC4HTa4nBSo9NcyZ8Z0MoaKo9YCbqC4CNCEPYqRbJeDUeBwfejnHR94eVMB2cw=="
},
"@material-ui/core": {
"version": "4.9.12",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.9.12.tgz",
"integrity": "sha512-JtRm1iNw3PRg+bzULS1uRKhdIJ2jhKO3/5ptO6kTADARsv5KmhzMbM+PYmVS09qm9Yu3ilwka4dYrtjqea53Lw==",
"version": "4.9.13",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.9.13.tgz",
"integrity": "sha512-GEXNwUr+laZ0N+F1efmHB64Fyg+uQIRXLqbSejg3ebSXgLYNpIjnMOPRfWdu4rICq0dAIgvvNXGkKDMcf3AMpA==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/react-transition-group": "^4.3.0",
"@material-ui/styles": "^4.9.10",
"@material-ui/system": "^4.9.10",
"@material-ui/styles": "^4.9.13",
"@material-ui/system": "^4.9.13",
"@material-ui/types": "^5.0.1",
"@material-ui/utils": "^4.9.12",
"@types/react-transition-group": "^4.2.0",
@ -1631,15 +1830,15 @@
}
},
"@material-ui/styles": {
"version": "4.9.10",
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.10.tgz",
"integrity": "sha512-EXIXlqVyFDnjXF6tj72y6ZxiSy+mHtrsCo3Srkm3XUeu3Z01aftDBy7ZSr3TQ02gXHTvDSBvegp3Le6p/tl7eA==",
"version": "4.9.13",
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.13.tgz",
"integrity": "sha512-lWlXJanBdHQ18jW/yphedRokHcvZD1GdGzUF/wQxKDsHwDDfO45ZkAxuSBI202dG+r1Ph483Z3pFykO2obeSRA==",
"requires": {
"@babel/runtime": "^7.4.4",
"@emotion/hash": "^0.8.0",
"@material-ui/types": "^5.0.1",
"@material-ui/utils": "^4.9.6",
"clsx": "^1.0.2",
"clsx": "^1.0.4",
"csstype": "^2.5.2",
"hoist-non-react-statics": "^3.3.2",
"jss": "^10.0.3",
@ -1654,9 +1853,9 @@
}
},
"@material-ui/system": {
"version": "4.9.10",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.10.tgz",
"integrity": "sha512-E+t0baX2TBZk6ALm8twG6objpsxLdMM4MDm1++LMt2m7CetCAEc3aIAfDaprk4+tm5hFT1Cah5dRWk8EeIFQYw==",
"version": "4.9.13",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.13.tgz",
"integrity": "sha512-6AlpvdW6KJJ5bF1Xo2OD13sCN8k+nlL36412/bWnWZOKIfIMo/Lb8c8d1DOIaT/RKWxTEUaWnKZjabVnA3eZjA==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.9.6",
@ -1694,17 +1893,30 @@
"integrity": "sha512-KDvuNBxfTgDHjESiouEoPXq8GCUYbHnA+jOs8MzzwVDmxNLeZuDy3amaVzKv9Q5nncI6mNGcXOzTKWzapET8Sw=="
},
"@ngtools/webpack": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.3.tgz",
"integrity": "sha512-yQ7LHqICC1Xf4E4Jw1jDCAJHYwPX7T7mRFxMd+R/0EBDcz1XBSh85+vnVs2PoJHVH+8ONOEkZKKSjABe1CZUvg==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.4.tgz",
"integrity": "sha512-CDlQzMnWraxf/dT3G5L+0N0VniWHWdzjLRP8pWBoyV0xlzWS1yL/lj8Mas2jEIuaUxZ8bi29mE7xa8prqewtBQ==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.3",
"@angular-devkit/core": "9.1.4",
"enhanced-resolve": "4.1.1",
"rxjs": "6.5.4",
"webpack-sources": "1.4.3"
},
"dependencies": {
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
@ -1738,23 +1950,47 @@
}
},
"@schematics/angular": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.1.3.tgz",
"integrity": "sha512-3vxrPyvcIWvyWgbx/fpeQvMThXlmcnHTXVn2dpTcE2BzstAYdG17W3qouhvmlqd6m28orxkKKiZaJYMNTtnV/A==",
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.1.4.tgz",
"integrity": "sha512-7nbiYBRgXc+f0sa5iXTcF6/VMy/Xq0wyKKnDFiLCb2aFYR7EXRHWF2GuwDIg2bvFugLuCBDoNnXeddLE1TXGWg==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.3",
"@angular-devkit/schematics": "9.1.3"
"@angular-devkit/core": "9.1.4",
"@angular-devkit/schematics": "9.1.4"
},
"dependencies": {
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
}
}
},
"@schematics/update": {
"version": "0.901.3",
"resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.901.3.tgz",
"integrity": "sha512-kwfc9LMMi6ryN2oiat9vTqGMK1jKwI1c45Nm1xala35nsbQSQ12qeL3MrVmnSCeI14+cinFUbp8mWI9/3M+/Lg==",
"version": "0.901.4",
"resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.901.4.tgz",
"integrity": "sha512-jCtZY2Fbj502gKN5gdu1brnRy/ssyzTrWm69Ty73V+t8uL7nLr+/hny/VBJ8CiQnKQvxcgVl1xgvI1cXzpysVA==",
"dev": true,
"requires": {
"@angular-devkit/core": "9.1.3",
"@angular-devkit/schematics": "9.1.3",
"@angular-devkit/core": "9.1.4",
"@angular-devkit/schematics": "9.1.4",
"@yarnpkg/lockfile": "1.1.0",
"ini": "1.3.5",
"npm-package-arg": "^8.0.0",
@ -1764,6 +2000,19 @@
"semver-intersect": "1.4.0"
},
"dependencies": {
"@angular-devkit/core": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz",
"integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==",
"dev": true,
"requires": {
"ajv": "6.12.0",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.5.4",
"source-map": "0.7.3"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
@ -1846,9 +2095,9 @@
}
},
"@types/jquery": {
"version": "3.3.36",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.36.tgz",
"integrity": "sha512-jHL8J5y5fJ0+C9zCTkeOvX4zqRnPug3r6JhAqAYl2YyBCYHiXTbZSH0MRCpayZADed5TigPjH92dEKczUFT2TQ==",
"version": "3.3.38",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.38.tgz",
"integrity": "sha512-nkDvmx7x/6kDM5guu/YpXkGZ/Xj/IwGiLDdKM99YA5Vag7pjGyTJ8BNUh/6hxEn/sEu5DKtyRgnONJ7EmOoKrA==",
"requires": {
"@types/sizzle": "*"
}
@ -3223,9 +3472,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001048",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz",
"integrity": "sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg==",
"version": "1.0.30001051",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001051.tgz",
"integrity": "sha512-sw8UUnTlRevawTMZKN7vpfwSjCBVoiMPlYd8oT2VwNylyPCBdMAUmLGUApnYYTtIm5JXsQegUAY7GPHqgfDzjw==",
"dev": true
},
"canonical-path": {
@ -4873,9 +5122,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.3.421",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.421.tgz",
"integrity": "sha512-ogxgmvHGfDuLA+GtgfK0jkFWlBb4MCZK2U1MM+l98sf4U3Ixtrfw1iC9w4mQqNvo+lHgM4pR62TqoT4QrvKJCw==",
"version": "1.3.428",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.428.tgz",
"integrity": "sha512-u3+5jEfgLKq/hGO96YfAoOAM1tgFnRDTCD5mLuev44tttcXix+INtVegAkmGzUcfDsnzkPt51XXurXZLLwXt0w==",
"dev": true
},
"elliptic": {
@ -6084,13 +6333,33 @@
}
},
"hash-base": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
"integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
"dev": true,
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
}
}
},
"hash.js": {
@ -6900,10 +7169,13 @@
"dev": true
},
"is-wsl": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
"integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==",
"dev": true
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"requires": {
"is-docker": "^2.0.0"
}
},
"isarray": {
"version": "1.0.0",
@ -7172,9 +7444,9 @@
}
},
"jquery": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
"integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ=="
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
"integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
},
"jquery.terminal": {
"version": "2.15.4",
@ -9777,9 +10049,9 @@
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portfinder": {
"version": "1.0.25",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
"integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
"version": "1.0.26",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
"integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==",
"dev": true,
"requires": {
"async": "^2.6.2",
@ -10942,9 +11214,9 @@
}
},
"rc-select": {
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-10.2.4.tgz",
"integrity": "sha512-PtfAHQRXof5gX1qEYQc8GIgroajtzU3mcMGbqM1aE1jqaZ4r+p0GJy3rabXoNANsKH7jUV5+zYJb5VhTxj2vmQ==",
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-10.2.5.tgz",
"integrity": "sha512-E5cdq+8kuTMdvDUmVXGdlHb4D0Effj/Xu988kUWSoALJtEAAdnUbuCJGhu04ehWtKMotGN5I9qlkLR4OdiLrgg==",
"requires": {
"classnames": "2.x",
"rc-animate": "^2.10.0",
@ -14526,9 +14798,9 @@
}
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
"integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==",
"dev": true
},
"mkdirp": {

38
ui-ngx/package.json

@ -13,24 +13,24 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^9.1.2",
"@angular/cdk": "^9.1.3",
"@angular/common": "^9.1.2",
"@angular/compiler": "^9.1.2",
"@angular/core": "^9.1.2",
"@angular/animations": "^9.1.4",
"@angular/cdk": "^9.2.2",
"@angular/common": "^9.1.4",
"@angular/compiler": "^9.1.4",
"@angular/core": "^9.1.4",
"@angular/flex-layout": "^9.0.0-beta.29",
"@angular/forms": "^9.1.2",
"@angular/material": "^9.2.1",
"@angular/platform-browser": "^9.1.2",
"@angular/platform-browser-dynamic": "^9.1.2",
"@angular/router": "^9.1.2",
"@angular/forms": "^9.1.4",
"@angular/material": "^9.2.2",
"@angular/platform-browser": "^9.1.4",
"@angular/platform-browser-dynamic": "^9.1.4",
"@angular/router": "^9.1.4",
"@auth0/angular-jwt": "^4.0.0",
"@date-io/date-fns": "^2.6.1",
"@flowjs/flow.js": "^2.14.0",
"@flowjs/ngx-flow": "^0.4.3",
"@juggle/resize-observer": "^3.1.3",
"@mat-datetimepicker/core": "^4.1.0",
"@material-ui/core": "^4.9.11",
"@material-ui/core": "^4.9.13",
"@material-ui/icons": "^4.9.1",
"@material-ui/pickers": "^3.2.10",
"@ngrx/effects": "^9.1.0",
@ -50,7 +50,7 @@
"flot": "git://github.com/thingsboard/flot.git#0.9-work",
"flot.curvedlines": "git://github.com/MichaelZinsmaier/CurvedLines.git#master",
"font-awesome": "^4.7.0",
"jquery": "^3.5.0",
"jquery": "^3.5.1",
"jquery.terminal": "^2.15.4",
"js-beautify": "^1.11.0",
"json-schema-defaults": "^0.4.0",
@ -75,7 +75,7 @@
"objectpath": "^2.0.0",
"prop-types": "^15.7.2",
"raphael": "^2.3.0",
"rc-select": "^10.2.4",
"rc-select": "^10.2.5",
"react": "^16.13.1",
"react-ace": "^8.1.0",
"react-dom": "^16.13.1",
@ -95,21 +95,21 @@
},
"devDependencies": {
"@angular-builders/custom-webpack": "^9.1.0",
"@angular-devkit/build-angular": "^0.901.1",
"@angular/cli": "^9.1.1",
"@angular/compiler-cli": "^9.1.2",
"@angular/language-service": "^9.1.2",
"@angular-devkit/build-angular": "^0.901.4",
"@angular/cli": "^9.1.4",
"@angular/compiler-cli": "^9.1.4",
"@angular/language-service": "^9.1.4",
"@types/canvas-gauges": "^2.1.2",
"@types/flot": "^0.0.31",
"@types/jasmine": "^3.5.10",
"@types/jasminewd2": "^2.0.8",
"@types/jquery": "^3.3.35",
"@types/jquery": "^3.3.38",
"@types/js-beautify": "^1.8.2",
"@types/jstree": "^3.3.39",
"@types/jszip": "^3.1.7",
"@types/leaflet": "^1.5.12",
"@types/leaflet-polylinedecorator": "^1.6.0",
"@types/leaflet-markercluster": "^1.0.3",
"@types/leaflet-polylinedecorator": "^1.6.0",
"@types/lodash": "^4.14.150",
"@types/raphael": "^2.3.0",
"@types/react": "^16.9.34",

4
ui-ngx/src/app/core/api/datasource-subcription.ts

@ -28,7 +28,7 @@ import {
} from '@shared/models/telemetry/telemetry.models';
import { DatasourceListener } from './datasource.service';
import { AggregationType, SubscriptionTimewindow, YEAR } from '@shared/models/time/time.models';
import { deepClone, isDefinedAndNotNull, isObject } from '@core/utils';
import { deepClone, isDefinedAndNotNull, isObject, objectHashCode } from '@core/utils';
import { UtilsService } from '@core/services/utils.service';
import { EntityType } from '@shared/models/entity-type.models';
import { DataAggregator } from '@core/api/data-aggregator';
@ -120,7 +120,7 @@ export class DatasourceSubscription {
data: []
};
} else {
key = String(this.utils.objectHashCode(dataKey));
key = String(objectHashCode(dataKey));
this.datasourceData[key] = {
data: []
};

4
ui-ngx/src/app/core/api/datasource.service.ts

@ -25,7 +25,7 @@ import {
DatasourceSubscriptionOptions,
SubscriptionDataKey
} from '@core/api/datasource-subcription';
import { deepClone } from '@core/utils';
import { deepClone, objectHashCode } from '@core/utils';
export interface DatasourceListener {
subscriptionType: widgetType;
@ -79,7 +79,7 @@ export class DatasourceService {
datasourceSubscriptionOptions.entityType = listener.entityType;
datasourceSubscriptionOptions.entityId = listener.entityId;
}
listener.datasourceSubscriptionKey = this.utils.objectHashCode(datasourceSubscriptionOptions);
listener.datasourceSubscriptionKey = objectHashCode(datasourceSubscriptionOptions);
let subscription: DatasourceSubscription;
if (this.subscriptions[listener.datasourceSubscriptionKey]) {
subscription = this.subscriptions[listener.datasourceSubscriptionKey];

26
ui-ngx/src/app/core/services/utils.service.ts

@ -163,32 +163,6 @@ export class UtilsService {
return obj;
}
public hashCode(str: string): number {
let hash = 0;
let i: number;
let char: number;
if (str.length === 0) {
return hash;
}
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
// tslint:disable-next-line:no-bitwise
hash = ((hash << 5) - hash) + char;
// tslint:disable-next-line:no-bitwise
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
public objectHashCode(obj: any): number {
let hash = 0;
if (obj) {
const str = JSON.stringify(obj);
hash = this.hashCode(str);
}
return hash;
}
public processWidgetException(exception: any): ExceptionData {
const data = this.parseException(exception, -6);
if (this.widgetEditMode) {

203
ui-ngx/src/app/core/utils.ts

@ -15,11 +15,10 @@
///
import _ from 'lodash';
import { Observable, Observer, of, Subject } from 'rxjs';
import { finalize, map, share } from 'rxjs/operators';
import { Observable, Subject } from 'rxjs';
import { finalize, share } from 'rxjs/operators';
import base64js from 'base64-js';
import { Datasource } from '@app/shared/models/widget.models';
import { FormattedData } from '@app/modules/home/components/widget/lib/maps/map-models';
export function onParentScrollOrWindowResize(el: Node): Observable<Event> {
const scrollSubject = new Subject<Event>();
@ -33,7 +32,7 @@ export function onParentScrollOrWindowResize(el: Node): Observable<Event> {
scrollParentNode.addEventListener('scroll', eventListenerObject);
});
window.addEventListener('resize', eventListenerObject);
const shared = scrollSubject.pipe(
return scrollSubject.pipe(
finalize(() => {
scrollParentNodes.forEach((scrollParentNode) => {
scrollParentNode.removeEventListener('scroll', eventListenerObject);
@ -42,18 +41,13 @@ export function onParentScrollOrWindowResize(el: Node): Observable<Event> {
}),
share()
);
return shared;
}
export function isLocalUrl(url: string): boolean {
const parser = document.createElement('a');
parser.href = url;
const host = parser.hostname;
if (host === 'localhost' || host === '127.0.0.1') {
return true;
} else {
return false;
}
return host === 'localhost' || host === '127.0.0.1';
}
export function animatedScroll(element: HTMLElement, scrollTop: number, delay?: number) {
@ -68,8 +62,7 @@ export function animatedScroll(element: HTMLElement, scrollTop: number, delay?:
element.scrollTop = to;
} else {
currentTime += increment;
const val = easeInOut(currentTime, start, remaining, duration);
element.scrollTop = val;
element.scrollTop = easeInOut(currentTime, start, remaining, duration);
if (currentTime < duration) {
setTimeout(animateScroll, increment);
}
@ -118,7 +111,7 @@ export function formatValue(value: any, dec?: number, units?: string, showZeroDe
formatted = formatted.toFixed(dec);
}
if (!showZeroDecimals) {
formatted = (Number(formatted) * 1);
formatted = (Number(formatted));
}
formatted = formatted.toString();
if (isDefined(units) && units.length > 0) {
@ -154,15 +147,13 @@ export function deleteNullProperties(obj: any) {
export function objToBase64(obj: any): string {
const json = JSON.stringify(obj);
const encoded = utf8Encode(json);
const b64Encoded: string = base64js.fromByteArray(encoded);
return b64Encoded;
return base64js.fromByteArray(encoded);
}
export function base64toObj(b64Encoded: string): any {
const encoded: Uint8Array | number[] = base64js.toByteArray(b64Encoded);
const json = utf8Decode(encoded);
const obj = JSON.parse(json);
return obj;
return JSON.parse(json);
}
function utf8Encode(str: string): Uint8Array | number[] {
@ -223,11 +214,13 @@ function scrollParents(node: Node): Node[] {
return scrollParentNodes;
}
function hashCode(str) {
export function hashCode(str: string): number {
let hash = 0;
let i;
let char;
if (str.length === 0) return hash;
let i: number;
let char: number;
if (str.length === 0) {
return hash;
}
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
// tslint:disable-next-line:no-bitwise
@ -238,6 +231,15 @@ function hashCode(str) {
return hash;
}
export function objectHashCode(obj: any): number {
let hash = 0;
if (obj) {
const str = JSON.stringify(obj);
hash = hashCode(str);
}
return hash;
}
function easeInOut(
currentTime: number,
startTime: number,
@ -433,29 +435,8 @@ export function getDescendantProp(obj: any, path: string): any {
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
}
export function imageLoader(imageUrl: string): Observable<HTMLImageElement> {
return new Observable((observer: Observer<HTMLImageElement>) => {
const image = new Image();
image.style.position = 'absolute';
image.style.left = '-99999px';
image.style.top = '-99999px';
image.onload = () => {
observer.next(image);
document.body.removeChild(image);
observer.complete();
};
image.onerror = err => {
observer.error(err);
document.body.removeChild(image);
observer.complete();
};
document.body.appendChild(image)
image.src = imageUrl;
});
}
export function createLabelFromDatasource(datasource: Datasource, pattern: string) {
const varsRegex = /\$\{([^}]*)\}/g;
const varsRegex = /\${([^}]*)}/g;
let label = pattern;
if (!datasource) {
return label;
@ -482,142 +463,6 @@ export function createLabelFromDatasource(datasource: Datasource, pattern: strin
return label;
}
const imageAspectMap = {};
export function aspectCache(imageUrl: string): Observable<number> {
if (imageUrl?.length) {
const hash = hashCode(imageUrl);
let aspect = imageAspectMap[hash];
if (aspect) {
return of(aspect);
}
else return imageLoader(imageUrl).pipe(map(image => {
aspect = image.width / image.height;
imageAspectMap[hash] = aspect;
return aspect;
}))
}
}
export function parseArray(input: any[]): any[] {
return _(input).groupBy(el => el?.datasource?.entityName)
.values().value().map((entityArray, dsIndex) =>
entityArray[0].data.map((el, i) => {
const obj = {
entityName: entityArray[0]?.datasource?.entityName,
$datasource: entityArray[0]?.datasource,
dsIndex,
time: el[0],
deviceType: null
};
entityArray.filter(el => el.data.length).forEach(entity => {
obj[entity?.dataKey?.label] = entity?.data[i][1];
obj[entity?.dataKey?.label + '|ts'] = entity?.data[0][0];
if (entity?.dataKey?.label === 'type') {
obj.deviceType = entity?.data[0][1];
}
});
return obj;
})
);
}
export function parseData(input: any[]): FormattedData[] {
return _(input).groupBy(el => el?.datasource?.entityName)
.values().value().map((entityArray, i) => {
const obj = {
entityName: entityArray[0]?.datasource?.entityName,
$datasource: entityArray[0]?.datasource as Datasource,
dsIndex: i,
deviceType: null
};
entityArray.filter(el => el.data.length).forEach(el => {
obj[el?.dataKey?.label] = el?.data[0][1];
obj[el?.dataKey?.label + '|ts'] = el?.data[0][0];
if (el?.dataKey?.label === 'type') {
obj.deviceType = el?.data[0][1];
}
});
return obj;
});
}
export function safeExecute(func: Function, params = []) {
let res = null;
if (func && typeof (func) === 'function') {
try {
res = func(...params);
}
catch (err) {
console.log('error in external function:', err);
res = null;
}
}
return res;
}
export function parseFunction(source: any, params: string[] = ['def']): Function {
let res = null;
if (source?.length) {
try {
res = new Function(...params, source);
}
catch (err) {
res = null;
}
}
return res;
}
export function parseTemplate(template: string, data: { $datasource?: Datasource, [key: string]: any },
translateFn?: (key: string) => string) {
let res = '';
try {
if (template.match(/<link-act/g)) {
template = template.replace(/<link-act/g, '<a').replace(/link-act>/g, 'a>')
.replace(/name=(\'|")(.*?)(\'|")/g, `class='tb-custom-action' id='$2'`);
}
if (translateFn) {
template = translateFn(template);
}
template = createLabelFromDatasource(data.$datasource, template);
const formatted = template.match(/\$\{([^}]*)\:\d*\}/g);
if (formatted)
formatted.forEach(value => {
const [variable, digits] = value.replace('${', '').replace('}', '').split(':');
data[variable] = padValue(data[variable], +digits);
if (data[variable] === 'NaN') data[variable] = '';
template = template.replace(value, '${' + variable + '}');
});
const variables = template.match(/\$\{.*?\}/g);
if (variables) {
variables.forEach(variable => {
variable = variable.replace('${', '').replace('}', '');
if (!data[variable])
data[variable] = '';
})
}
const compiled = _.template(template);
res = compiled(data);
}
catch (ex) {
console.log(ex, template)
}
return res;
}
export let parseWithTranslation = {
translate(): string {
throw console.error('Translate not assigned');
},
parseTemplate(template: string, data: object, forceTranslate = false): string {
return parseTemplate(forceTranslate ? this.translate(template) : template, data, this?.translate);
},
setTranslate(translateFn: (key: string, defaultTranslation?: string) => string) {
this.translate = translateFn;
}
}
export function padValue(val: any, dec: number): string {
let strVal;
let n;

4
ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts

@ -33,7 +33,7 @@ import { Datasource, WidgetActionDescriptor, WidgetConfig } from '@shared/models
import { IWidgetSubscription } from '@core/api/widget-api.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { deepClone, isDefined, isNumber, createLabelFromDatasource } from '@core/utils';
import { deepClone, isDefined, isNumber, createLabelFromDatasource, hashCode } from '@core/utils';
import cssjs from '@core/css/css';
import { PageLink } from '@shared/models/page/page-link';
import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order';
@ -304,7 +304,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
const cssString = constructTableCssString(this.widgetConfig);
const cssParser = new cssjs();
cssParser.testMode = false;
const namespace = 'alarms-table-' + this.utils.hashCode(cssString);
const namespace = 'alarms-table-' + hashCode(cssString);
cssParser.cssPreviewNamespace = namespace;
cssParser.createStyleElement(namespace, cssString);
$(this.elementRef.nativeElement).addClass(namespace);

4
ui-ngx/src/app/modules/home/components/widget/lib/entities-hierarchy-widget.component.ts

@ -37,7 +37,7 @@ import {
import { BaseData } from '@shared/models/base-data';
import { EntityId } from '@shared/models/id/entity-id';
import { EntityType } from '@shared/models/entity-type.models';
import { deepClone } from '@core/utils';
import { deepClone, hashCode } from '@core/utils';
import {
defaultNodeIconFunction,
defaultNodeOpenedFunction,
@ -186,7 +186,7 @@ export class EntitiesHierarchyWidgetComponent extends PageComponent implements O
const cssString = constructTableCssString(this.widgetConfig);
const cssParser = new cssjs();
cssParser.testMode = false;
const namespace = 'entities-hierarchy-' + this.utils.hashCode(cssString);
const namespace = 'entities-hierarchy-' + hashCode(cssString);
cssParser.cssPreviewNamespace = namespace;
cssParser.createStyleElement(namespace, cssString);
$(this.elementRef.nativeElement).addClass(namespace);

4
ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts

@ -39,7 +39,7 @@ import {
import { IWidgetSubscription } from '@core/api/widget-api.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { deepClone, isDefined, isNumber, createLabelFromDatasource } from '@core/utils';
import { deepClone, isDefined, isNumber, createLabelFromDatasource, hashCode } from '@core/utils';
import cssjs from '@core/css/css';
import { PageLink } from '@shared/models/page/page-link';
import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order';
@ -226,7 +226,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
const cssString = constructTableCssString(this.widgetConfig);
const cssParser = new cssjs();
cssParser.testMode = false;
const namespace = 'entities-table-' + this.utils.hashCode(cssString);
const namespace = 'entities-table-' + hashCode(cssString);
cssParser.cssPreviewNamespace = namespace;
cssParser.createStyleElement(namespace, cssString);
$(this.elementRef.nativeElement).addClass(namespace);

23
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts

@ -14,19 +14,26 @@
/// limitations under the License.
///
import L, { LatLngTuple, LatLngBounds, Point, MarkerClusterGroupOptions, markerClusterGroup } from 'leaflet';
import L, { LatLngBounds, LatLngTuple, markerClusterGroup, MarkerClusterGroupOptions } from 'leaflet';
import 'leaflet-providers';
import 'leaflet.markercluster/dist/leaflet.markercluster';
import { MapSettings, MarkerSettings, FormattedData, UnitedMapSettings, PolygonSettings, PolylineSettings } from './map-models';
import {
FormattedData,
MapSettings,
MarkerSettings,
PolygonSettings,
PolylineSettings,
UnitedMapSettings
} from './map-models';
import { Marker } from './markers';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
import { Polyline } from './polyline';
import { Polygon } from './polygon';
import { DatasourceData } from '@app/shared/models/widget.models';
import { safeExecute } from '@app/core/utils';
import { safeExecute } from '@home/components/widget/lib/maps/maps-utils';
export default abstract class LeafletMap {
@ -38,13 +45,11 @@ export default abstract class LeafletMap {
map$: BehaviorSubject<L.Map> = new BehaviorSubject(null);
ready$: Observable<L.Map> = this.map$.pipe(filter(map => !!map));
options: UnitedMapSettings;
isMarketCluster: boolean;
bounds: L.LatLngBounds;
newMarker: L.Marker;
datasources: FormattedData[];
markersCluster;
constructor(public $container: HTMLElement, options: UnitedMapSettings) {
protected constructor(public $container: HTMLElement, options: UnitedMapSettings) {
this.options = options;
}
@ -125,7 +130,7 @@ export default abstract class LeafletMap {
addMarker.setPosition('topright')
}
L.Control.AddMarker = L.Control.extend({
onAdd(map) {
onAdd() {
const img = L.DomUtil.create('img') as any;
img.src = `assets/add_location.svg`;
img.style.width = '32px';
@ -138,7 +143,7 @@ export default abstract class LeafletMap {
draggableImg.on('dragend', dragListener)
return img;
},
onRemove(map) {
onRemove() {
},
dragMarker: this.dragMarker
} as any);
@ -166,7 +171,7 @@ export default abstract class LeafletMap {
this.datasources = dataSources;
}
public saveMarkerLocation(e) {
public saveMarkerLocation(_e) {
}

6
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts

@ -14,7 +14,7 @@
/// limitations under the License.
///
import { LatLngTuple, LeafletMouseEvent } from 'leaflet';
import { LatLngTuple } from 'leaflet';
import { Datasource } from '@app/shared/models/widget.models';
export type GenericFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string;
@ -116,7 +116,7 @@ export type PolygonSettings = {
autocloseTooltip: boolean;
tooltipFunction: GenericFunction;
showTooltipAction: string;
tooltipAction: object;
tooltipAction: { [name: string]: actionsHandler };
tooltipPattern: string;
useTooltipFunction: boolean;
polygonClick: { [name: string]: actionsHandler };
@ -152,6 +152,6 @@ export interface HistorySelectSettings {
buttonColor: string;
}
export type actionsHandler = ($event: Event | LeafletMouseEvent, datasource: Datasource) => void;
export type actionsHandler = ($event: Event, datasource: Datasource) => void;
export type UnitedMapSettings = MapSettings & PolygonSettings & MarkerSettings & PolylineSettings;

12
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts

@ -31,11 +31,10 @@ import {
} from './schemes';
import { MapWidgetStaticInterface, MapWidgetInterface } from './map-widget.interface';
import { OpenStreetMap, TencentMap, GoogleMap, HEREMap, ImageMap } from './providers';
import { parseFunction, parseArray, parseData, parseWithTranslation } from '@core/utils';
import { initSchema, addToSchema, mergeSchemes, addCondition, addGroupInfo } from '@core/schema-utils';
import { of, Subject } from 'rxjs';
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
import { getDefCenterPosition } from './maps-utils';
import { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils';
import { JsonSettingsSchema, WidgetActionDescriptor, DatasourceType, widgetType, Datasource } from '@shared/models/widget.models';
import { EntityId } from '@shared/models/id/entity-id';
import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models';
@ -138,7 +137,7 @@ export class MapWidgetController implements MapWidgetInterface {
else return '';
}
getDescriptors(name: string): { [name: string]: ($event: Event) => void } {
getDescriptors(name: string): { [name: string]: ($event: Event, datasource: Datasource) => void } {
const descriptors = this.ctx.actionsApi.getActionDescriptors(name);
const actions = {};
descriptors.forEach(descriptor => {
@ -150,9 +149,10 @@ export class MapWidgetController implements MapWidgetInterface {
onInit() {
}
private onCustomAction(descriptor: WidgetActionDescriptor, $event: any, entityInfo: Datasource) {
if ($event && $event.stopPropagation) {
$event?.stopPropagation();
private onCustomAction(descriptor: WidgetActionDescriptor, $event: Event, entityInfo: Datasource) {
if ($event) {
$event.preventDefault();
$event.stopPropagation();
}
const { entityId, entityName, entityLabel, entityType } = entityInfo;
this.ctx.actionsApi.handleWidgetAction($event, descriptor, {

175
ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts

@ -15,8 +15,12 @@
///
import L from 'leaflet';
import { MarkerSettings, PolygonSettings, PolylineSettings } from './map-models';
import { FormattedData, MarkerSettings, PolygonSettings, PolylineSettings } from './map-models';
import { Datasource } from '@app/shared/models/widget.models';
import _ from 'lodash';
import { Observable, Observer, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createLabelFromDatasource, hashCode, padValue } from '@core/utils';
export function createTooltip(target: L.Layer,
settings: MarkerSettings | PolylineSettings | PolygonSettings,
@ -49,7 +53,7 @@ export function createTooltip(target: L.Layer,
export function getRatio(firsMoment: number, secondMoment: number, intermediateMoment: number): number {
return (intermediateMoment - firsMoment) / (secondMoment - firsMoment);
};
}
export function findAngle(startPoint, endPoint) {
let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude);
@ -65,3 +69,170 @@ export function getDefCenterPosition(position) {
return position;
return [0, 0];
}
const imageAspectMap = {};
function imageLoader(imageUrl: string): Observable<HTMLImageElement> {
return new Observable((observer: Observer<HTMLImageElement>) => {
const image = new Image();
image.style.position = 'absolute';
image.style.left = '-99999px';
image.style.top = '-99999px';
image.onload = () => {
observer.next(image);
document.body.removeChild(image);
observer.complete();
};
image.onerror = err => {
observer.error(err);
document.body.removeChild(image);
observer.complete();
};
document.body.appendChild(image)
image.src = imageUrl;
});
}
export function aspectCache(imageUrl: string): Observable<number> {
if (imageUrl?.length) {
const hash = hashCode(imageUrl);
let aspect = imageAspectMap[hash];
if (aspect) {
return of(aspect);
}
else return imageLoader(imageUrl).pipe(map(image => {
aspect = image.width / image.height;
imageAspectMap[hash] = aspect;
return aspect;
}))
}
}
function parseTemplate(template: string, data: { $datasource?: Datasource, [key: string]: any },
translateFn?: (key: string) => string) {
let res = '';
try {
if (template.match(/<link-act/g)) {
template = template.replace(/<link-act/g, '<a href="#"').replace(/link-act>/g, 'a>')
.replace(/name=(['"])(.*?)(['"])/g, `class='tb-custom-action' id='$2'`);
}
if (translateFn) {
template = translateFn(template);
}
template = createLabelFromDatasource(data.$datasource, template);
const formatted = template.match(/\${([^}]*):\d*}/g);
if (formatted)
formatted.forEach(value => {
const [variable, digits] = value.replace('${', '').replace('}', '').split(':');
data[variable] = padValue(data[variable], +digits);
if (data[variable] === 'NaN') data[variable] = '';
template = template.replace(value, '${' + variable + '}');
});
const variables = template.match(/\${.*?}/g);
if (variables) {
variables.forEach(variable => {
variable = variable.replace('${', '').replace('}', '');
if (!data[variable])
data[variable] = '';
})
}
const compiled = _.template(template);
res = compiled(data);
}
catch (ex) {
console.log(ex, template)
}
return res;
}
type TranslateFunc = (key: string, defaultTranslation?: string) => string;
export const parseWithTranslation = {
translateFn: null,
translate(key: string, defaultTranslation?: string): string {
if (this.translateFn) {
return this.translateFn(key, defaultTranslation);
} else {
throw console.error('Translate not assigned');
}
},
parseTemplate(template: string, data: object, forceTranslate = false): string {
return parseTemplate(forceTranslate ? this.translate(template) : template, data, this.translate.bind(this));
},
setTranslate(translateFn: TranslateFunc) {
this.translateFn = translateFn;
}
}
export function parseData(input: any[]): FormattedData[] {
return _(input).groupBy(el => el?.datasource?.entityName)
.values().value().map((entityArray, i) => {
const obj = {
entityName: entityArray[0]?.datasource?.entityName,
$datasource: entityArray[0]?.datasource as Datasource,
dsIndex: i,
deviceType: null
};
entityArray.filter(el => el.data.length).forEach(el => {
obj[el?.dataKey?.label] = el?.data[0][1];
obj[el?.dataKey?.label + '|ts'] = el?.data[0][0];
if (el?.dataKey?.label === 'type') {
obj.deviceType = el?.data[0][1];
}
});
return obj;
});
}
export function parseArray(input: any[]): any[] {
return _(input).groupBy(el => el?.datasource?.entityName)
.values().value().map((entityArray, dsIndex) =>
entityArray[0].data.map((el, i) => {
const obj = {
entityName: entityArray[0]?.datasource?.entityName,
$datasource: entityArray[0]?.datasource,
dsIndex,
time: el[0],
deviceType: null
};
entityArray.filter(e => e.data.length).forEach(entity => {
obj[entity?.dataKey?.label] = entity?.data[i][1];
obj[entity?.dataKey?.label + '|ts'] = entity?.data[0][0];
if (entity?.dataKey?.label === 'type') {
obj.deviceType = entity?.data[0][1];
}
});
return obj;
})
);
}
export function parseFunction(source: any, params: string[] = ['def']): (...args: any[]) => any {
let res = null;
if (source?.length) {
try {
res = new Function(...params, source);
}
catch (err) {
res = null;
}
}
return res;
}
export function safeExecute(func: (...args: any[]) => any, params = []) {
let res = null;
if (func && typeof (func) === 'function') {
try {
res = func(...params);
}
catch (err) {
console.log('error in external function:', err);
res = null;
}
}
return res;
}

7
ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts

@ -14,10 +14,9 @@
/// limitations under the License.
///
import { aspectCache, parseWithTranslation, safeExecute } from '@app/core/utils';
import L, { LeafletMouseEvent } from 'leaflet';
import { FormattedData, MarkerSettings } from './map-models';
import { createTooltip } from './maps-utils';
import { aspectCache, createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
import tinycolor from 'tinycolor2';
export class Marker {
@ -50,7 +49,7 @@ export class Marker {
this.leafletMarker.on('click', (event: LeafletMouseEvent) => {
for (const action in this.settings.markerClick) {
if (typeof (this.settings.markerClick[action]) === 'function') {
this.settings.markerClick[action](event, this.data.$datasource);
this.settings.markerClick[action](event.originalEvent, this.data.$datasource);
}
}
});
@ -184,4 +183,4 @@ export class Marker {
setMarkerPosition(latLng) {
this.leafletMarker.setLatLng(latLng);
}
}
}

7
ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts

@ -15,10 +15,9 @@
///
import L, { LatLngExpression, LatLngTuple, LeafletMouseEvent } from 'leaflet';
import { createTooltip } from './maps-utils';
import { PolygonSettings, FormattedData } from './map-models';
import { createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
import { PolygonSettings } from './map-models';
import { DatasourceData } from '@app/shared/models/widget.models';
import { safeExecute, parseWithTranslation } from '@app/core/utils';
export class Polygon {
@ -46,7 +45,7 @@ export class Polygon {
this.leafletPoly.on('click', (event: LeafletMouseEvent) => {
for (const action in this.settings.polygonClick) {
if (typeof (this.settings.polygonClick[action]) === 'function') {
this.settings.polygonClick[action](event, polyData.datasource);
this.settings.polygonClick[action](event.originalEvent, polyData.datasource);
}
}
});

4
ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts

@ -17,8 +17,8 @@
import L, { PolylineDecoratorOptions } from 'leaflet';
import 'leaflet-polylinedecorator';
import { safeExecute } from '@app/core/utils';
import { PolylineSettings } from './map-models';
import { safeExecute } from '@home/components/widget/lib/maps/maps-utils';
export class Polyline {
@ -95,4 +95,4 @@ export class Polyline {
setPolylineLatLngs(latLngs) {
this.leafletPoly.setLatLngs(latLngs);
}
}
}

2
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts

@ -29,7 +29,7 @@ export class GoogleMap extends LeafletMap {
super($container, options);
this.loadGoogle(() => {
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
const roads = (L.gridLayer as any).googleMutant({
(L.gridLayer as any).googleMutant({
type: options?.gmDefaultMapType || 'roadmap'
}).addTo(map);
super.setMap(map);

2
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts

@ -17,9 +17,9 @@
import L, { LatLngLiteral, LatLngBounds, LatLngTuple } from 'leaflet';
import LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models';
import { aspectCache, parseFunction } from '@app/core/utils';
import { Observable } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';
import { aspectCache, parseFunction } from '@home/components/widget/lib/maps/maps-utils';
const maxZoom = 4;// ?

28
ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts

@ -558,32 +558,6 @@ export const markerClusteringSettingsSchema =
]
};
export const markerClusteringSettingsSchemaGoogle =
{
schema: {
title: 'Marker Clustering Configuration Google',
type: 'object',
properties: {
gridSize: {
title: 'Maximum radius that a cluster will cover in pixels',
type: 'number',
default: 60
},
minimumClusterSize: {
title: 'The minimum number of markers in a cluster',
type: 'number'
}
},
required: []
},
form: [
'gridSize',
'minimumClusterSize'
]
};
export const markerClusteringSettingsSchemaLeaflet =
{
schema: {
@ -1271,4 +1245,4 @@ export const tripAnimationSchema = {
}
]
}]
}
}

4
ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts

@ -40,7 +40,7 @@ import {
} from '@shared/models/widget.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { isDefined, isNumber } from '@core/utils';
import { hashCode, isDefined, isNumber } from '@core/utils';
import cssjs from '@core/css/css';
import { PageLink } from '@shared/models/page/page-link';
import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order';
@ -230,7 +230,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
const cssParser = new cssjs();
cssParser.testMode = false;
const namespace = 'ts-table-' + this.utils.hashCode(cssString);
const namespace = 'ts-table-' + hashCode(cssString);
cssParser.cssPreviewNamespace = namespace;
cssParser.createStyleElement(namespace, cssString);
$(this.elementRef.nativeElement).addClass(namespace);

3
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts

@ -22,12 +22,11 @@ import { interpolateOnPointSegment } from 'leaflet-geometryutil';
import { AfterViewInit, ChangeDetectorRef, Component, Input, OnInit, SecurityContext, ViewChild } from '@angular/core';
import { MapWidgetController, TbMapWidgetV2 } from '../lib/maps/map-widget2';
import { MapProviders } from '../lib/maps/map-models';
import { parseArray, parseWithTranslation, safeExecute, parseTemplate } from '@app/core/utils';
import { initSchema, addToSchema, addGroupInfo } from '@app/core/schema-utils';
import { tripAnimationSchema } from '../lib/maps/schemes';
import { DomSanitizer } from '@angular/platform-browser';
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
import { findAngle, getRatio } from '../lib/maps/maps-utils';
import { findAngle, getRatio, parseArray, parseWithTranslation, safeExecute } from '../lib/maps/maps-utils';
import { JsonSettingsSchema, WidgetConfig } from '@shared/models/widget.models';
import moment from 'moment';

1
ui-ngx/src/app/shared/pipe/public-api.ts

@ -20,4 +20,3 @@ export * from './keyboard-shortcut.pipe';
export * from './milliseconds-to-time-string.pipe';
export * from './nospace.pipe';
export * from './truncate.pipe';
export * from './template.pipe';

25
ui-ngx/src/app/shared/pipe/template.pipe.ts

@ -1,25 +0,0 @@
///
/// Copyright © 2016-2020 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Pipe, PipeTransform } from '@angular/core';
import { parseTemplate, parseWithTranslation } from '@app/core/utils';
@Pipe({ name: 'tbParseTemplate' })
export class TbTemplatePipe implements PipeTransform {
transform(template, data): string {
return parseWithTranslation.parseTemplate(template, data);
}
}

3
ui-ngx/src/app/shared/shared.module.ts

@ -131,7 +131,6 @@ import { LedLightComponent } from '@shared/components/led-light.component';
import { TbJsonToStringDirective } from '@shared/components/directives/tb-json-to-string.directive';
import { JsonObjectEditDialogComponent } from '@shared/components/dialog/json-object-edit-dialog.component';
import { HistorySelectorComponent } from './components/time/history-selector/history-selector.component';
import { TbTemplatePipe } from '@shared/pipe/template.pipe';
import { EntityGatewaySelectComponent } from '@shared/components/entity/entity-gateway-select.component';
import { QueueTypeListComponent } from '@shared/components/queue/queue-type-list.component';
@ -215,7 +214,6 @@ import { QueueTypeListComponent } from '@shared/components/queue/queue-type-list
HighlightPipe,
TruncatePipe,
TbJsonPipe,
TbTemplatePipe,
KeyboardShortcutPipe,
TbJsonToStringDirective,
JsonObjectEditDialogComponent,
@ -377,7 +375,6 @@ import { QueueTypeListComponent } from '@shared/components/queue/queue-type-list
HighlightPipe,
TruncatePipe,
TbJsonPipe,
TbTemplatePipe,
KeyboardShortcutPipe,
TranslateModule,
JsonObjectEditDialogComponent,

Loading…
Cancel
Save