diff --git a/CHANGELOG.md b/CHANGELOG.md index a69637c..034da76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,13 @@ _v6.0.3_ - Fix strconv.Atoi: invalid syntax for dirwatch type sdrtrunk. - Fix the new version available dialog opening more than once. +_v6.0.4_ + +- Fix wrong time calculation in prune scheduler. +- More fix on the SQL_BUSY error (issue #67). +- Support files (certs, db, ini) are now created in the same folder as the executable, if the folder is writable, or under a `Rdio Scanner` folder in the user's home folder. +- Some code refactoring. + ## Version 5.2 - Change to how the server reports version. diff --git a/COMPILING.md b/COMPILING.md new file mode 100644 index 0000000..ccb375a --- /dev/null +++ b/COMPILING.md @@ -0,0 +1,35 @@ +# How to compile + +The official version of [Rdio Scanner](https://github.com/chuot/rdio-scanner) is compiled on a PC using the current version of Fedora Workstation. You should have no problem building on another platform as long as the prerequisites are available and installed. + +## Install the prerequisites + +Your os distribution may have all of the following prerequisites available in its own package repository. Make sure, however, that they are at the latest version. This is especially not the case with Ubuntu and its Node.js. + +- latest version of git ([here](https://git-scm.com/downloads)) +- latest version of gnu make ([here](https://www.gnu.org/software/make/)) +- latest long-term support version of Node.js ([here](https://nodejs.org/en/)) +- latest version of Go ([here](https://go.dev/dl/)) +- latest version of Pandoc with pandoc-pdf ([here](https://pandoc.org/installing.html)) +- latest version of Info-Zip ([here](http://infozip.sourceforge.net/)) + +## Compile the app + +Clone the official repository on your computer and start the build process. + + git clone https://github.com/chuot/rdio-scanner.git + cd rdio-scanner + make + +When finished, you will find the precompiled versions for various platforms in the `dist` folder. + + rdio-scanner-darwin-amd64-v6.0.4.zip + rdio-scanner-darwin-arm64-v6.0.4.zip + rdio-scanner-freebsd-amd64-v6.0.4.zip + rdio-scanner-linux-386-v6.0.4.zip + rdio-scanner-linux-amd64-v6.0.4.zip + rdio-scanner-linux-arm64-v6.0.4.zip + rdio-scanner-linux-arm-v6.0.4.zip + rdio-scanner-windows-amd64-v6.0.4.zip + +**Happy Rdio scanning !** \ No newline at end of file diff --git a/Makefile b/Makefile index 72e1887..309319d 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,8 @@ ################################################################################ app := rdio-scanner -ver := 6.0.3 +date := 2021/12/08 +ver := 6.0.4 client := $(wildcard client/*.json client/*.ts) server := $(wildcard server/*.go) @@ -25,7 +26,7 @@ build = @cd server && GOOS=$(1) GOARCH=$(2) go build -o ../dist/$(1)-$(2)/$(3) pandoc = @test -d dist/$(1)-$(2) || mkdir -p dist/$(1)-$(2) && pandoc -f markdown -o dist/$(1)-$(2)/$(3) --resource-path docs:docs/platforms $(4) docs/webapp.md CHANGELOG.md zip = @cd dist/$(1)-$(2) && zip -q ../$(app)-$(1)-$(2)-v$(ver).zip * && cd .. && rm -fr $(1)-$(2) -.PHONY: all clean dist setver +.PHONY: all clean dist sed .PHONY: darwin darwin-amd64 darwin-arm64 .PHONY: freebsd freebsd-amd64 .PHONY: linux linux-386 linux-amd64 linux-arm linux-arm64 @@ -38,10 +39,11 @@ clean: dist: darwin freebsd linux windows -setver: - @sed -i -re "s/^(\s*\"version\":).*$$/\1 \"$(ver)\"/" client/package.json - @sed -i -re "s/^(const\s+Version\s+=).*$$/\1 \"$(ver)\"/" server/version.go - @sed -i -re "s/v[0-9]\.[0-9]\.[0-9]/v$(ver)/" docs/platforms/*.md +sed: + @sed -i -re "s|^(\s*\"version\":).*$$|\1 \"$(ver)\"|" client/package.json + @sed -i -re "s|^(const\s+Version\s+=).*$$|\1 \"$(ver)\"|" server/version.go + @sed -i -re "s|v[0-9]\.[0-9]\.[0-9]|v$(ver)|" COMPILING.md docs/platforms/*.md + @sed -i -re "s|[0-9]{4}/[0-9]{2}/[0-9]{2}|$(date)|" docs/platforms/*.md webapp: server/webapp/index.html diff --git a/client/package-lock.json b/client/package-lock.json index 85a855b..0716d5a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,39 +1,39 @@ { "name": "rdio-scanner", - "version": "6.0.0", + "version": "6.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "rdio-scanner", - "version": "6.0.0", + "version": "6.0.4", "license": "LICENSE", "dependencies": { - "@angular/animations": "^13.0.2", - "@angular/cdk": "^13.0.2", - "@angular/common": "~13.0.2", - "@angular/compiler": "~13.0.2", - "@angular/core": "~13.0.2", - "@angular/forms": "~13.0.2", - "@angular/material": "^13.0.2", - "@angular/platform-browser": "~13.0.2", - "@angular/platform-browser-dynamic": "~13.0.2", - "@angular/router": "^13.0.2", - "@angular/service-worker": "^13.0.2", + "@angular/animations": "^13.0.3", + "@angular/cdk": "^13.0.3", + "@angular/common": "~13.0.3", + "@angular/compiler": "~13.0.3", + "@angular/core": "~13.0.3", + "@angular/forms": "~13.0.3", + "@angular/material": "^13.0.3", + "@angular/platform-browser": "~13.0.3", + "@angular/platform-browser-dynamic": "~13.0.3", + "@angular/router": "^13.0.3", + "@angular/service-worker": "^13.0.3", "rxjs": "~7.4.0", "tslib": "^2.3.1", "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "~13.0.3", - "@angular/cli": "^13.0.3", - "@angular/compiler-cli": "~13.0.2", - "@types/node": "~16.11.11", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", + "@angular-devkit/build-angular": "~13.0.4", + "@angular/cli": "^13.0.4", + "@angular/compiler-cli": "~13.0.3", + "@types/node": "~16.11.12", + "@typescript-eslint/eslint-plugin": "^5.6.0", + "@typescript-eslint/parser": "^5.6.0", "ajv-keywords": "^5.1.0", - "eslint": "^8.3.0", - "npm-check-updates": "^12.0.2", + "eslint": "^8.4.1", + "npm-check-updates": "^12.0.3", "ts-node": "~10.4.0", "typescript": "~4.4.4" }, @@ -55,12 +55,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1300.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1300.3.tgz", - "integrity": "sha512-XY3sjRLk06Q+uAU0BePuIWcK1n3Jr0ksNV0ACNAct+MnI3QFfPPaYA/Tdhp9uWobuZ4lUrL0drc2uppNu0wKmA==", + "version": "0.1300.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1300.4.tgz", + "integrity": "sha512-COW2W6rI9D69QEXGc/MyTbJY9gT+u8yMTpONpIjopd+KoSK/q2wGr0RleUf7XSCunZCs0SRI7z3Pw1EAdQCP7Q==", "dev": true, "dependencies": { - "@angular-devkit/core": "13.0.3", + "@angular-devkit/core": "13.0.4", "rxjs": "6.6.7" }, "engines": { @@ -88,15 +88,15 @@ "dev": true }, "node_modules/@angular-devkit/build-angular": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.0.3.tgz", - "integrity": "sha512-5KFsknpnq3mc0KwcIDjvmqB3trz5cMt48dB0nrc23zkFI9v4hkpalc/OEg/H3G93K0c9g6dcyxmHkNfsU1+CHw==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.0.4.tgz", + "integrity": "sha512-GYAxQTI0YkjVKciepwliMugUDjgXlmePG80LL2FCVQYnSM6r2uAI3dF8vX8fREZIRpBpDuTtUIohCRr1X5Oysg==", "dev": true, "dependencies": { "@ampproject/remapping": "1.0.1", - "@angular-devkit/architect": "0.1300.3", - "@angular-devkit/build-webpack": "0.1300.3", - "@angular-devkit/core": "13.0.3", + "@angular-devkit/architect": "0.1300.4", + "@angular-devkit/build-webpack": "0.1300.4", + "@angular-devkit/core": "13.0.4", "@babel/core": "7.15.8", "@babel/generator": "7.15.8", "@babel/helper-annotate-as-pure": "7.15.4", @@ -107,7 +107,7 @@ "@babel/runtime": "7.15.4", "@babel/template": "7.15.4", "@discoveryjs/json-ext": "0.5.5", - "@ngtools/webpack": "13.0.3", + "@ngtools/webpack": "13.0.4", "ansi-colors": "4.1.1", "babel-loader": "8.2.3", "babel-plugin-istanbul": "6.1.1", @@ -216,12 +216,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1300.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1300.3.tgz", - "integrity": "sha512-3DNo8575FFPMqJaVMXxrIduWkrcKm5zYSCvkMOmzHLp+gx+RXQiwnoXfVJpukcE/jwK/4SWyRE8Tw75sfPJ71A==", + "version": "0.1300.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1300.4.tgz", + "integrity": "sha512-6h4ecyGefj0Fdn8+wYV0QhQgtNQOw83Jw/cM+LeIR28VX7A6ZEEnYf2P5YrCmZFGxznXFYQZNiu8E0mPgBOh3A==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1300.3", + "@angular-devkit/architect": "0.1300.4", "rxjs": "6.6.7" }, "engines": { @@ -253,9 +253,9 @@ "dev": true }, "node_modules/@angular-devkit/core": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.0.3.tgz", - "integrity": "sha512-5yTYW6m4pkDPSYNxThm+47h+UZ6XVEfdfsXR3o+WlRG0hc18EuQ+sXZkzhvZrk5KMLlXFex4eO40RPq2vvWS/w==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.0.4.tgz", + "integrity": "sha512-AzgLvERLC6qzY5aZWUpkz5nx+pZChrq3DSt6azMPALwzzoABrwiO6XqzRnj17mXtANXLH2oe9FuHr9jzgFbF1g==", "dev": true, "dependencies": { "ajv": "8.6.3", @@ -314,12 +314,12 @@ "dev": true }, "node_modules/@angular-devkit/schematics": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.0.3.tgz", - "integrity": "sha512-+Va1E0zJBCg5jqSfITusghoMJgPAwlU+WUs49fuGVCzfJPwfSjTKSrsbhanahMd27+Ys3rovGZq0F2JUdL801A==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.0.4.tgz", + "integrity": "sha512-3LsmpfAEOxwPyachrktCHtGUYBzQCCzD0++CUjhK8W99v8/IAplkm4dgovFb1RiRkUm44l+HIS7387AbvEIf5A==", "dev": true, "dependencies": { - "@angular-devkit/core": "13.0.3", + "@angular-devkit/core": "13.0.4", "jsonc-parser": "3.0.0", "magic-string": "0.25.7", "ora": "5.4.1", @@ -350,9 +350,9 @@ "dev": true }, "node_modules/@angular/animations": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.0.2.tgz", - "integrity": "sha512-ROR70rM6E13pIJzaYf0Su/ALSoBm5fIMjozey636pAq21TxTy5IfhgaBjv/vflC9psbpaySGw2H5XnwejP0gSw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.0.3.tgz", + "integrity": "sha512-wGhUzbf8tOHwNx/8JK3RIUisunayENj1j7aSlm8yrBoawvNdgCQVESyZdtfHxHuScRSpzxSIWdMggZ4G4+DuFg==", "dependencies": { "tslib": "^2.3.0" }, @@ -360,13 +360,13 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "13.0.2" + "@angular/core": "13.0.3" } }, "node_modules/@angular/cdk": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.0.2.tgz", - "integrity": "sha512-m7RHIAXpFpgsrydhWXX1hAXRmQpQ+m9eRCYAoz8QiDCchYyVvTaxkZ8J7XGS8RtJ2EiocXSp4TlwQQrpXe+4lg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.0.3.tgz", + "integrity": "sha512-nPlnpdLk+Lady3l5eHh+csbHPOiTvfVpMrluUEnb1RAby07QQucUo7cYOKgFiVmSmaMwDBv2aGj1fAoXKzzc5g==", "dependencies": { "tslib": "^2.3.0" }, @@ -380,16 +380,16 @@ } }, "node_modules/@angular/cli": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.0.3.tgz", - "integrity": "sha512-LDXDXDbQ1MBHVUstu4aNjFbyg5f9hLP52gEKB8Z6fQlf5CB1X5zD6UPcR4IvoYt03EFxg3DHco+ueJQ20oZUWQ==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.0.4.tgz", + "integrity": "sha512-0QMJXFNn57LVg7ZwZFPO90g6aZHDnoe5yCB7fo3nskOhDw1AW/rnbbaNVMVX/SvP30hOOTLsfVJ1Y3I6eKDgRA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@angular-devkit/architect": "0.1300.3", - "@angular-devkit/core": "13.0.3", - "@angular-devkit/schematics": "13.0.3", - "@schematics/angular": "13.0.3", + "@angular-devkit/architect": "0.1300.4", + "@angular-devkit/core": "13.0.4", + "@angular-devkit/schematics": "13.0.4", + "@schematics/angular": "13.0.4", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.2", @@ -416,9 +416,9 @@ } }, "node_modules/@angular/common": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.0.2.tgz", - "integrity": "sha512-UxWzNAU/o9pP02AYB5MrnIlShirfO631NolmvP0jTSEmym1nAeDOwZIYlkgfcJMHFXFc7DBnE2XOGaTZ8if3kw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.0.3.tgz", + "integrity": "sha512-xxQIQD5rWWHafKRPCgvkWvy53b+QkbJ9yAf3qYTp0gXZJMg/Cx3Ylc8LA2o1kyVJxCI/amXf5k4rr1S9yU7zxw==", "dependencies": { "tslib": "^2.3.0" }, @@ -426,14 +426,14 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "13.0.2", + "@angular/core": "13.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.0.2.tgz", - "integrity": "sha512-EvIFT8y5VNICrnPgiamv/z9hfQ7KjLCM52g4ssXGCeGPVj58OEfslEc3jO4BCJG7xuLm7dCuSRV0pBlJNTSYFg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.0.3.tgz", + "integrity": "sha512-WINfdQk6WojEhTIcNOkvhQu1yDRtq3FUx2saCZyGwS3MbzkfWUr4/x6VKJ5sAYJYnlaf9Goypau4/5lPp4+0tA==", "dependencies": { "tslib": "^2.3.0" }, @@ -442,9 +442,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.0.2.tgz", - "integrity": "sha512-KVDntMBoPoAPdpyO3LxR2U3BO3ja5fY5Im5rzynjBCC3dnwAPPKoIlYZlFY/5ov6yVoVleeb/BOovYxHuxZBsA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.0.3.tgz", + "integrity": "sha512-j3uCk46BwyuRmYLwB39LoUEjARMdhGSI6kSDsQWPop+iHGJkP4ThUUQCrCGClqhXdyGdhkTrq8jqZ/GfXmUkPA==", "dev": true, "dependencies": { "@babel/core": "^7.8.6", @@ -468,14 +468,14 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "13.0.2", + "@angular/compiler": "13.0.3", "typescript": ">=4.4.2 <4.5" } }, "node_modules/@angular/core": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.0.2.tgz", - "integrity": "sha512-6Jbct50lncMqzwLILzfmwQRK8eOEMv0quCL3pQptEpYPSlPqKz6QRxD76BykSUOs7XYJ/KdZmu3uGcT2Q/DUVg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.0.3.tgz", + "integrity": "sha512-w8FngZBPrLw9kHftYy824C/wSBtLKCWvGU04qI6V9BCpxedf7cyOIhOzaL+4Pz/rwgvo+0Qn2uM1ssZ2+JUdvQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -488,9 +488,9 @@ } }, "node_modules/@angular/forms": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.0.2.tgz", - "integrity": "sha512-JGgEOTH/OYr7/RlqJUPSzKQF/a55UM5PD6CgpUjAXKrCV18+zhofO05g+ibIZH3OfONntthcbKEXxMTX2EEQqg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.0.3.tgz", + "integrity": "sha512-Sxpc9kiCYi59GzKkpvpqgUejXq7P1dt3l1C5mnV3WBdNEpVBDRD63YLlNTya+w4uSMr+WEbtCys41QO8MXNIHQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -498,22 +498,22 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.0.2", - "@angular/core": "13.0.2", - "@angular/platform-browser": "13.0.2", + "@angular/common": "13.0.3", + "@angular/core": "13.0.3", + "@angular/platform-browser": "13.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/material": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.0.2.tgz", - "integrity": "sha512-DbbkQFpZ73oxOuR9LkkpeUPWP31DNIG3Z94sOrtdBhX3HfbLLOCaAJAIwMl8+bEuzDgtWBmx3taUR8l4WKCO8g==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.0.3.tgz", + "integrity": "sha512-6lEofw8wWl1huNLEgngYfIDA7dY4oSq0sB7F16foDfenC+TokRxfIN950GKNYmvGVYqODUuQdrQ1n2bXE2GQGg==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^13.0.0 || ^14.0.0-0", - "@angular/cdk": "13.0.2", + "@angular/cdk": "13.0.3", "@angular/common": "^13.0.0 || ^14.0.0-0", "@angular/core": "^13.0.0 || ^14.0.0-0", "@angular/forms": "^13.0.0 || ^14.0.0-0", @@ -521,9 +521,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.0.2.tgz", - "integrity": "sha512-fkLGr9Vj2cvFzXefyhNaqwXX90+WbpYj5cCii7S1HcbJ9qSM5ZenLp1t8mGRhmWI7odY4BrFskWOChlWFrLEkA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.0.3.tgz", + "integrity": "sha512-XCeCnsD997Erl4XGNFHIqC9cTkO9uSHdaoDvLuNMsF2kr5V1GOeFkh71CYNmCsWrTj4PFqx9q+ziGgvxM4eeOQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -531,9 +531,9 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/animations": "13.0.2", - "@angular/common": "13.0.2", - "@angular/core": "13.0.2" + "@angular/animations": "13.0.3", + "@angular/common": "13.0.3", + "@angular/core": "13.0.3" }, "peerDependenciesMeta": { "@angular/animations": { @@ -542,9 +542,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.0.2.tgz", - "integrity": "sha512-2wZX2oop3A1kWFcbRYqe8AxBQjT35DXf1qlGyFQoMn7D0vOAprg6X1hUK2XBItRrvwRWh3hSVhzkustTIl+r6g==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.0.3.tgz", + "integrity": "sha512-+s2o7M/WzRaytjDt6LPqZQ2mmVFpOQBbfiXmq4OwnETc2d6dIpWJzfs00MCAVhu1tR1btzsA3Qa6lA1YqULHrg==", "dependencies": { "tslib": "^2.3.0" }, @@ -552,16 +552,16 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.0.2", - "@angular/compiler": "13.0.2", - "@angular/core": "13.0.2", - "@angular/platform-browser": "13.0.2" + "@angular/common": "13.0.3", + "@angular/compiler": "13.0.3", + "@angular/core": "13.0.3", + "@angular/platform-browser": "13.0.3" } }, "node_modules/@angular/router": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.0.2.tgz", - "integrity": "sha512-AfmT845dcYPvNbUdV2ALlf++szZP3ie2d0eu7JyGWe3anV1fbDcg76RhjxFK8yVUxryrCQtEnot1VEEVlhGkyw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.0.3.tgz", + "integrity": "sha512-NNDrSK32mpkuQiY6CzAjRBvWSiLM+61dC3EOfBUDIyPzIp318fhqZ5ohxY42Fvp07KGnRv5tcqb/1QE8Ukwbyg==", "dependencies": { "tslib": "^2.3.0" }, @@ -569,16 +569,16 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.0.2", - "@angular/core": "13.0.2", - "@angular/platform-browser": "13.0.2", + "@angular/common": "13.0.3", + "@angular/core": "13.0.3", + "@angular/platform-browser": "13.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-13.0.2.tgz", - "integrity": "sha512-cH5adbvwI+cr6qKVdvNfQ5B0I//3NJwXkP04ifllPUIw7Te1pUfVb8eIN8UI/80aqG0uu/uIes7QoovSIayqOA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-13.0.3.tgz", + "integrity": "sha512-vQdaHN4S9SKOxNzio/vl6NG7jzMz2VWsTF9u/mR8okzkb60xbJ3s5v1Ci+VeZFkVuWEt2l5NbZxgnXabQHl4tA==", "dependencies": { "tslib": "^2.3.0" }, @@ -589,8 +589,8 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.0.2", - "@angular/core": "13.0.2" + "@angular/common": "13.0.3", + "@angular/core": "13.0.3" } }, "node_modules/@assemblyscript/loader": { @@ -2384,14 +2384,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", - "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.0.0", + "espree": "^9.2.0", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -2486,12 +2486,12 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" }, @@ -2540,9 +2540,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.0.3.tgz", - "integrity": "sha512-sVi1Xk8pyy6Y6JODySucYfvuxb5k3IIX/oIWy8QxlFVzpeB2UMqEOevrgvtmiEbQNB1W+aYSTph6oeV+PRX5YA==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.0.4.tgz", + "integrity": "sha512-kH0kYOQvbv6SnVdcdi21AbJo17H1HSGlCy/8C1ujLdgtT6enKMnx9onYIoZSmb5U98GqYc+DV/W0HwpHwRcOoQ==", "dev": true, "engines": { "node": "^12.20.0 || ^14.15.0 || >=16.10.0", @@ -2673,13 +2673,13 @@ } }, "node_modules/@schematics/angular": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.0.3.tgz", - "integrity": "sha512-qH6mnmGaDCuG1FM3vLdvSFDG394TeZO0ZvRDrw3iCYlX5Nkbz0Kvt0MPtWNZmlohwFhGlbXKVQiR++1dxa6eEA==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.0.4.tgz", + "integrity": "sha512-P9F5c8ApLbEyfNO4TZNsTyAdrtOjwIhrM/P+eEC4/x6nklWlEFE6TGMYTNjiK/RRhkbX1tBs8gcdJLYxtEqPSg==", "dev": true, "dependencies": { - "@angular-devkit/core": "13.0.3", - "@angular-devkit/schematics": "13.0.3", + "@angular-devkit/core": "13.0.4", + "@angular-devkit/schematics": "13.0.4", "jsonc-parser": "3.0.0" }, "engines": { @@ -2743,9 +2743,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.0.tgz", - "integrity": "sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -2784,9 +2784,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.11.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz", - "integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==", + "version": "16.11.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.12.tgz", + "integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==", "dev": true }, "node_modules/@types/parse-json": { @@ -2802,13 +2802,13 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz", - "integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz", + "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "5.5.0", - "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/experimental-utils": "5.6.0", + "@typescript-eslint/scope-manager": "5.6.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -2855,15 +2855,15 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz", - "integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz", + "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.5.0", - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/typescript-estree": "5.5.0", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -2879,14 +2879,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz", - "integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz", + "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.5.0", - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/typescript-estree": "5.5.0", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", "debug": "^4.3.2" }, "engines": { @@ -2906,13 +2906,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz", - "integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz", + "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/visitor-keys": "5.5.0" + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2923,9 +2923,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz", - "integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz", + "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2936,13 +2936,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz", - "integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz", + "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/visitor-keys": "5.5.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -2984,12 +2984,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz", - "integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz", + "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/types": "5.6.0", "eslint-visitor-keys": "^3.0.0" }, "engines": { @@ -4123,9 +4123,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001283", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", - "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", + "version": "1.0.30001285", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz", + "integrity": "sha512-KAOkuUtcQ901MtmvxfKD+ODHH9YVDYnBt+TGYSz2KIfnq22CiArbUxXPN9067gNbgMlnNYRSwho8OPXZPALB9Q==", "dev": true, "funding": { "type": "opencollective", @@ -4267,13 +4267,15 @@ } }, "node_modules/cli-table": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.9.tgz", - "integrity": "sha512-7eA6hFtAZwVx3dWAGoaBqTrzWko5jRUFKpHT64ZHkJpaA3y5wf5NlLjguqTRmqycatJZiwftODYYyGNLbQ7MuA==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", "dev": true, "dependencies": { - "colors": "1.0.3", - "strip-ansi": "^6.0.1" + "colors": "1.0.3" + }, + "engines": { + "node": ">= 0.2.0" } }, "node_modules/cli-width": { @@ -4368,12 +4370,12 @@ } }, "node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, "engines": { - "node": ">= 6" + "node": ">= 12" } }, "node_modules/commondir": { @@ -4617,9 +4619,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.19.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.2.tgz", - "integrity": "sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.3.tgz", + "integrity": "sha512-59tYzuWgEEVU9r+SRgceIGXSSUn47JknoiXW6Oq7RW8QHjXWz3/vp8pa7dbtuVu40sewz3OP3JmQEcDdztrLhA==", "dev": true, "dependencies": { "browserslist": "^4.18.1", @@ -5301,9 +5303,9 @@ ] }, "node_modules/domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "dev": true, "dependencies": { "domelementtype": "^2.2.0" @@ -5354,9 +5356,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz", - "integrity": "sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw==", + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.13.tgz", + "integrity": "sha512-ih5tIhzEuf78pBY70FXLo+Pw73R5MPPPcXb4CGBMJaCQt/qo/IGIesKXmswpemVCKSE2Bulr5FslUv7gAWJoOw==", "dev": true }, "node_modules/emoji-regex": { @@ -5789,13 +5791,13 @@ } }, "node_modules/eslint": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz", - "integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", + "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.0.4", - "@humanwhocodes/config-array": "^0.6.0", + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -5806,7 +5808,7 @@ "eslint-scope": "^7.1.0", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.1.0", - "espree": "^9.1.0", + "espree": "^9.2.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -6085,9 +6087,9 @@ } }, "node_modules/espree": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz", - "integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", + "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", "dev": true, "dependencies": { "acorn": "^8.6.0", @@ -7726,9 +7728,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.0.tgz", - "integrity": "sha512-4WuKcUxtzxBoKOUFbt1MtTY9fJwPVD4aN/4Cgxee7OLetPZn5as2bjfZz98XSf2Zq1JFfhqPZpS+43BmWXKgCA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.2.tgz", + "integrity": "sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag==", "dev": true, "dependencies": { "@types/node": "*", @@ -8896,15 +8898,15 @@ } }, "node_modules/npm-check-updates": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.0.2.tgz", - "integrity": "sha512-VzMNuUXqRta1qpBkFiE0hKfpOGP2FbYwpBBTcJXoJWppOPBSi/paWFVhPVWf7PgRoDWegK+PDAWKhIvhyrBrIg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.0.3.tgz", + "integrity": "sha512-MTHzkDZY1ebhPaDvzWOU9bt4UYdHmY4tIcMCaZjgguGKUgwqokH/aB0Nrc4WcZ4rD491Spuj5DILo/RvKAefvw==", "dev": true, "dependencies": { "chalk": "^4.1.2", "cint": "^8.2.1", - "cli-table": "^0.3.6", - "commander": "^6.2.1", + "cli-table": "^0.3.11", + "commander": "^8.3.0", "fast-memoize": "^2.5.2", "find-up": "5.0.0", "fp-and-or": "^0.1.3", @@ -8926,7 +8928,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "semver-utils": "^1.1.4", - "source-map-support": "^0.5.20", + "source-map-support": "^0.5.21", "spawn-please": "^1.0.0", "update-notifier": "^5.1.0" }, @@ -9042,6 +9044,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-check-updates/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-check-updates/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/npm-check-updates/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12519,26 +12540,16 @@ } }, "node_modules/sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, "dependencies": { "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", + "uuid": "^8.3.2", "websocket-driver": "^0.7.4" } }, - "node_modules/sockjs/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/socks": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", @@ -13497,9 +13508,9 @@ } }, "node_modules/watchpack": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.0.tgz", - "integrity": "sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -14058,30 +14069,30 @@ } }, "node_modules/yargs": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.0.tgz", + "integrity": "sha512-GQl1pWyDoGptFPJx9b9L6kmR33TGusZvXIZUT+BOz9f7X2L94oeAskFYLEg/FkhV06zZPBYLvLZRWeYId29lew==", "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" }, "engines": { "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yn": { @@ -14126,12 +14137,12 @@ } }, "@angular-devkit/architect": { - "version": "0.1300.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1300.3.tgz", - "integrity": "sha512-XY3sjRLk06Q+uAU0BePuIWcK1n3Jr0ksNV0ACNAct+MnI3QFfPPaYA/Tdhp9uWobuZ4lUrL0drc2uppNu0wKmA==", + "version": "0.1300.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1300.4.tgz", + "integrity": "sha512-COW2W6rI9D69QEXGc/MyTbJY9gT+u8yMTpONpIjopd+KoSK/q2wGr0RleUf7XSCunZCs0SRI7z3Pw1EAdQCP7Q==", "dev": true, "requires": { - "@angular-devkit/core": "13.0.3", + "@angular-devkit/core": "13.0.4", "rxjs": "6.6.7" }, "dependencies": { @@ -14153,15 +14164,15 @@ } }, "@angular-devkit/build-angular": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.0.3.tgz", - "integrity": "sha512-5KFsknpnq3mc0KwcIDjvmqB3trz5cMt48dB0nrc23zkFI9v4hkpalc/OEg/H3G93K0c9g6dcyxmHkNfsU1+CHw==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.0.4.tgz", + "integrity": "sha512-GYAxQTI0YkjVKciepwliMugUDjgXlmePG80LL2FCVQYnSM6r2uAI3dF8vX8fREZIRpBpDuTtUIohCRr1X5Oysg==", "dev": true, "requires": { "@ampproject/remapping": "1.0.1", - "@angular-devkit/architect": "0.1300.3", - "@angular-devkit/build-webpack": "0.1300.3", - "@angular-devkit/core": "13.0.3", + "@angular-devkit/architect": "0.1300.4", + "@angular-devkit/build-webpack": "0.1300.4", + "@angular-devkit/core": "13.0.4", "@babel/core": "7.15.8", "@babel/generator": "7.15.8", "@babel/helper-annotate-as-pure": "7.15.4", @@ -14172,7 +14183,7 @@ "@babel/runtime": "7.15.4", "@babel/template": "7.15.4", "@discoveryjs/json-ext": "0.5.5", - "@ngtools/webpack": "13.0.3", + "@ngtools/webpack": "13.0.4", "ansi-colors": "4.1.1", "babel-loader": "8.2.3", "babel-plugin-istanbul": "6.1.1", @@ -14245,12 +14256,12 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1300.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1300.3.tgz", - "integrity": "sha512-3DNo8575FFPMqJaVMXxrIduWkrcKm5zYSCvkMOmzHLp+gx+RXQiwnoXfVJpukcE/jwK/4SWyRE8Tw75sfPJ71A==", + "version": "0.1300.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1300.4.tgz", + "integrity": "sha512-6h4ecyGefj0Fdn8+wYV0QhQgtNQOw83Jw/cM+LeIR28VX7A6ZEEnYf2P5YrCmZFGxznXFYQZNiu8E0mPgBOh3A==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1300.3", + "@angular-devkit/architect": "0.1300.4", "rxjs": "6.6.7" }, "dependencies": { @@ -14272,9 +14283,9 @@ } }, "@angular-devkit/core": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.0.3.tgz", - "integrity": "sha512-5yTYW6m4pkDPSYNxThm+47h+UZ6XVEfdfsXR3o+WlRG0hc18EuQ+sXZkzhvZrk5KMLlXFex4eO40RPq2vvWS/w==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.0.4.tgz", + "integrity": "sha512-AzgLvERLC6qzY5aZWUpkz5nx+pZChrq3DSt6azMPALwzzoABrwiO6XqzRnj17mXtANXLH2oe9FuHr9jzgFbF1g==", "dev": true, "requires": { "ajv": "8.6.3", @@ -14315,12 +14326,12 @@ } }, "@angular-devkit/schematics": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.0.3.tgz", - "integrity": "sha512-+Va1E0zJBCg5jqSfITusghoMJgPAwlU+WUs49fuGVCzfJPwfSjTKSrsbhanahMd27+Ys3rovGZq0F2JUdL801A==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.0.4.tgz", + "integrity": "sha512-3LsmpfAEOxwPyachrktCHtGUYBzQCCzD0++CUjhK8W99v8/IAplkm4dgovFb1RiRkUm44l+HIS7387AbvEIf5A==", "dev": true, "requires": { - "@angular-devkit/core": "13.0.3", + "@angular-devkit/core": "13.0.4", "jsonc-parser": "3.0.0", "magic-string": "0.25.7", "ora": "5.4.1", @@ -14345,32 +14356,32 @@ } }, "@angular/animations": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.0.2.tgz", - "integrity": "sha512-ROR70rM6E13pIJzaYf0Su/ALSoBm5fIMjozey636pAq21TxTy5IfhgaBjv/vflC9psbpaySGw2H5XnwejP0gSw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.0.3.tgz", + "integrity": "sha512-wGhUzbf8tOHwNx/8JK3RIUisunayENj1j7aSlm8yrBoawvNdgCQVESyZdtfHxHuScRSpzxSIWdMggZ4G4+DuFg==", "requires": { "tslib": "^2.3.0" } }, "@angular/cdk": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.0.2.tgz", - "integrity": "sha512-m7RHIAXpFpgsrydhWXX1hAXRmQpQ+m9eRCYAoz8QiDCchYyVvTaxkZ8J7XGS8RtJ2EiocXSp4TlwQQrpXe+4lg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.0.3.tgz", + "integrity": "sha512-nPlnpdLk+Lady3l5eHh+csbHPOiTvfVpMrluUEnb1RAby07QQucUo7cYOKgFiVmSmaMwDBv2aGj1fAoXKzzc5g==", "requires": { "parse5": "^5.0.0", "tslib": "^2.3.0" } }, "@angular/cli": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.0.3.tgz", - "integrity": "sha512-LDXDXDbQ1MBHVUstu4aNjFbyg5f9hLP52gEKB8Z6fQlf5CB1X5zD6UPcR4IvoYt03EFxg3DHco+ueJQ20oZUWQ==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.0.4.tgz", + "integrity": "sha512-0QMJXFNn57LVg7ZwZFPO90g6aZHDnoe5yCB7fo3nskOhDw1AW/rnbbaNVMVX/SvP30hOOTLsfVJ1Y3I6eKDgRA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1300.3", - "@angular-devkit/core": "13.0.3", - "@angular-devkit/schematics": "13.0.3", - "@schematics/angular": "13.0.3", + "@angular-devkit/architect": "0.1300.4", + "@angular-devkit/core": "13.0.4", + "@angular-devkit/schematics": "13.0.4", + "@schematics/angular": "13.0.4", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.2", @@ -14389,25 +14400,25 @@ } }, "@angular/common": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.0.2.tgz", - "integrity": "sha512-UxWzNAU/o9pP02AYB5MrnIlShirfO631NolmvP0jTSEmym1nAeDOwZIYlkgfcJMHFXFc7DBnE2XOGaTZ8if3kw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.0.3.tgz", + "integrity": "sha512-xxQIQD5rWWHafKRPCgvkWvy53b+QkbJ9yAf3qYTp0gXZJMg/Cx3Ylc8LA2o1kyVJxCI/amXf5k4rr1S9yU7zxw==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.0.2.tgz", - "integrity": "sha512-EvIFT8y5VNICrnPgiamv/z9hfQ7KjLCM52g4ssXGCeGPVj58OEfslEc3jO4BCJG7xuLm7dCuSRV0pBlJNTSYFg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.0.3.tgz", + "integrity": "sha512-WINfdQk6WojEhTIcNOkvhQu1yDRtq3FUx2saCZyGwS3MbzkfWUr4/x6VKJ5sAYJYnlaf9Goypau4/5lPp4+0tA==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.0.2.tgz", - "integrity": "sha512-KVDntMBoPoAPdpyO3LxR2U3BO3ja5fY5Im5rzynjBCC3dnwAPPKoIlYZlFY/5ov6yVoVleeb/BOovYxHuxZBsA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.0.3.tgz", + "integrity": "sha512-j3uCk46BwyuRmYLwB39LoUEjARMdhGSI6kSDsQWPop+iHGJkP4ThUUQCrCGClqhXdyGdhkTrq8jqZ/GfXmUkPA==", "dev": true, "requires": { "@babel/core": "^7.8.6", @@ -14424,57 +14435,57 @@ } }, "@angular/core": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.0.2.tgz", - "integrity": "sha512-6Jbct50lncMqzwLILzfmwQRK8eOEMv0quCL3pQptEpYPSlPqKz6QRxD76BykSUOs7XYJ/KdZmu3uGcT2Q/DUVg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.0.3.tgz", + "integrity": "sha512-w8FngZBPrLw9kHftYy824C/wSBtLKCWvGU04qI6V9BCpxedf7cyOIhOzaL+4Pz/rwgvo+0Qn2uM1ssZ2+JUdvQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.0.2.tgz", - "integrity": "sha512-JGgEOTH/OYr7/RlqJUPSzKQF/a55UM5PD6CgpUjAXKrCV18+zhofO05g+ibIZH3OfONntthcbKEXxMTX2EEQqg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.0.3.tgz", + "integrity": "sha512-Sxpc9kiCYi59GzKkpvpqgUejXq7P1dt3l1C5mnV3WBdNEpVBDRD63YLlNTya+w4uSMr+WEbtCys41QO8MXNIHQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/material": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.0.2.tgz", - "integrity": "sha512-DbbkQFpZ73oxOuR9LkkpeUPWP31DNIG3Z94sOrtdBhX3HfbLLOCaAJAIwMl8+bEuzDgtWBmx3taUR8l4WKCO8g==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.0.3.tgz", + "integrity": "sha512-6lEofw8wWl1huNLEgngYfIDA7dY4oSq0sB7F16foDfenC+TokRxfIN950GKNYmvGVYqODUuQdrQ1n2bXE2GQGg==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.0.2.tgz", - "integrity": "sha512-fkLGr9Vj2cvFzXefyhNaqwXX90+WbpYj5cCii7S1HcbJ9qSM5ZenLp1t8mGRhmWI7odY4BrFskWOChlWFrLEkA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.0.3.tgz", + "integrity": "sha512-XCeCnsD997Erl4XGNFHIqC9cTkO9uSHdaoDvLuNMsF2kr5V1GOeFkh71CYNmCsWrTj4PFqx9q+ziGgvxM4eeOQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.0.2.tgz", - "integrity": "sha512-2wZX2oop3A1kWFcbRYqe8AxBQjT35DXf1qlGyFQoMn7D0vOAprg6X1hUK2XBItRrvwRWh3hSVhzkustTIl+r6g==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.0.3.tgz", + "integrity": "sha512-+s2o7M/WzRaytjDt6LPqZQ2mmVFpOQBbfiXmq4OwnETc2d6dIpWJzfs00MCAVhu1tR1btzsA3Qa6lA1YqULHrg==", "requires": { "tslib": "^2.3.0" } }, "@angular/router": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.0.2.tgz", - "integrity": "sha512-AfmT845dcYPvNbUdV2ALlf++szZP3ie2d0eu7JyGWe3anV1fbDcg76RhjxFK8yVUxryrCQtEnot1VEEVlhGkyw==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.0.3.tgz", + "integrity": "sha512-NNDrSK32mpkuQiY6CzAjRBvWSiLM+61dC3EOfBUDIyPzIp318fhqZ5ohxY42Fvp07KGnRv5tcqb/1QE8Ukwbyg==", "requires": { "tslib": "^2.3.0" } }, "@angular/service-worker": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-13.0.2.tgz", - "integrity": "sha512-cH5adbvwI+cr6qKVdvNfQ5B0I//3NJwXkP04ifllPUIw7Te1pUfVb8eIN8UI/80aqG0uu/uIes7QoovSIayqOA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-13.0.3.tgz", + "integrity": "sha512-vQdaHN4S9SKOxNzio/vl6NG7jzMz2VWsTF9u/mR8okzkb60xbJ3s5v1Ci+VeZFkVuWEt2l5NbZxgnXabQHl4tA==", "requires": { "tslib": "^2.3.0" } @@ -15764,14 +15775,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", - "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.0.0", + "espree": "^9.2.0", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -15843,12 +15854,12 @@ "dev": true }, "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" } @@ -15885,9 +15896,9 @@ "dev": true }, "@ngtools/webpack": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.0.3.tgz", - "integrity": "sha512-sVi1Xk8pyy6Y6JODySucYfvuxb5k3IIX/oIWy8QxlFVzpeB2UMqEOevrgvtmiEbQNB1W+aYSTph6oeV+PRX5YA==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.0.4.tgz", + "integrity": "sha512-kH0kYOQvbv6SnVdcdi21AbJo17H1HSGlCy/8C1ujLdgtT6enKMnx9onYIoZSmb5U98GqYc+DV/W0HwpHwRcOoQ==", "dev": true, "requires": {} }, @@ -15991,13 +16002,13 @@ } }, "@schematics/angular": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.0.3.tgz", - "integrity": "sha512-qH6mnmGaDCuG1FM3vLdvSFDG394TeZO0ZvRDrw3iCYlX5Nkbz0Kvt0MPtWNZmlohwFhGlbXKVQiR++1dxa6eEA==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.0.4.tgz", + "integrity": "sha512-P9F5c8ApLbEyfNO4TZNsTyAdrtOjwIhrM/P+eEC4/x6nklWlEFE6TGMYTNjiK/RRhkbX1tBs8gcdJLYxtEqPSg==", "dev": true, "requires": { - "@angular-devkit/core": "13.0.3", - "@angular-devkit/schematics": "13.0.3", + "@angular-devkit/core": "13.0.4", + "@angular-devkit/schematics": "13.0.4", "jsonc-parser": "3.0.0" } }, @@ -16047,9 +16058,9 @@ "dev": true }, "@types/eslint": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.0.tgz", - "integrity": "sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", "dev": true, "requires": { "@types/estree": "*", @@ -16088,9 +16099,9 @@ "dev": true }, "@types/node": { - "version": "16.11.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz", - "integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==", + "version": "16.11.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.12.tgz", + "integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==", "dev": true }, "@types/parse-json": { @@ -16106,13 +16117,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz", - "integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz", + "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.5.0", - "@typescript-eslint/scope-manager": "5.5.0", + "@typescript-eslint/experimental-utils": "5.6.0", + "@typescript-eslint/scope-manager": "5.6.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -16139,55 +16150,55 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz", - "integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz", + "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.5.0", - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/typescript-estree": "5.5.0", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz", - "integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz", + "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.5.0", - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/typescript-estree": "5.5.0", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", "debug": "^4.3.2" } }, "@typescript-eslint/scope-manager": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz", - "integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz", + "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/visitor-keys": "5.5.0" + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0" } }, "@typescript-eslint/types": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz", - "integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz", + "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz", - "integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz", + "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.5.0", - "@typescript-eslint/visitor-keys": "5.5.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -16213,12 +16224,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz", - "integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz", + "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==", "dev": true, "requires": { - "@typescript-eslint/types": "5.5.0", + "@typescript-eslint/types": "5.6.0", "eslint-visitor-keys": "^3.0.0" } }, @@ -17103,9 +17114,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001283", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", - "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", + "version": "1.0.30001285", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz", + "integrity": "sha512-KAOkuUtcQ901MtmvxfKD+ODHH9YVDYnBt+TGYSz2KIfnq22CiArbUxXPN9067gNbgMlnNYRSwho8OPXZPALB9Q==", "dev": true }, "canonical-path": { @@ -17206,13 +17217,12 @@ "dev": true }, "cli-table": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.9.tgz", - "integrity": "sha512-7eA6hFtAZwVx3dWAGoaBqTrzWko5jRUFKpHT64ZHkJpaA3y5wf5NlLjguqTRmqycatJZiwftODYYyGNLbQ7MuA==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", "dev": true, "requires": { - "colors": "1.0.3", - "strip-ansi": "^6.0.1" + "colors": "1.0.3" } }, "cli-width": { @@ -17292,9 +17302,9 @@ "dev": true }, "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true }, "commondir": { @@ -17490,9 +17500,9 @@ "dev": true }, "core-js-compat": { - "version": "3.19.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.2.tgz", - "integrity": "sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.3.tgz", + "integrity": "sha512-59tYzuWgEEVU9r+SRgceIGXSSUn47JknoiXW6Oq7RW8QHjXWz3/vp8pa7dbtuVu40sewz3OP3JmQEcDdztrLhA==", "dev": true, "requires": { "browserslist": "^4.18.1", @@ -18005,9 +18015,9 @@ "dev": true }, "domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "dev": true, "requires": { "domelementtype": "^2.2.0" @@ -18046,9 +18056,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz", - "integrity": "sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw==", + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.13.tgz", + "integrity": "sha512-ih5tIhzEuf78pBY70FXLo+Pw73R5MPPPcXb4CGBMJaCQt/qo/IGIesKXmswpemVCKSE2Bulr5FslUv7gAWJoOw==", "dev": true }, "emoji-regex": { @@ -18338,13 +18348,13 @@ "dev": true }, "eslint": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz", - "integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", + "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.4", - "@humanwhocodes/config-array": "^0.6.0", + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -18355,7 +18365,7 @@ "eslint-scope": "^7.1.0", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.1.0", - "espree": "^9.1.0", + "espree": "^9.2.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -18553,9 +18563,9 @@ "dev": true }, "espree": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz", - "integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", + "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", "dev": true, "requires": { "acorn": "^8.6.0", @@ -19799,9 +19809,9 @@ } }, "jest-worker": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.0.tgz", - "integrity": "sha512-4WuKcUxtzxBoKOUFbt1MtTY9fJwPVD4aN/4Cgxee7OLetPZn5as2bjfZz98XSf2Zq1JFfhqPZpS+43BmWXKgCA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.2.tgz", + "integrity": "sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag==", "dev": true, "requires": { "@types/node": "*", @@ -20688,15 +20698,15 @@ } }, "npm-check-updates": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.0.2.tgz", - "integrity": "sha512-VzMNuUXqRta1qpBkFiE0hKfpOGP2FbYwpBBTcJXoJWppOPBSi/paWFVhPVWf7PgRoDWegK+PDAWKhIvhyrBrIg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.0.3.tgz", + "integrity": "sha512-MTHzkDZY1ebhPaDvzWOU9bt4UYdHmY4tIcMCaZjgguGKUgwqokH/aB0Nrc4WcZ4rD491Spuj5DILo/RvKAefvw==", "dev": true, "requires": { "chalk": "^4.1.2", "cint": "^8.2.1", - "cli-table": "^0.3.6", - "commander": "^6.2.1", + "cli-table": "^0.3.11", + "commander": "^8.3.0", "fast-memoize": "^2.5.2", "find-up": "5.0.0", "fp-and-or": "^0.1.3", @@ -20718,7 +20728,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "semver-utils": "^1.1.4", - "source-map-support": "^0.5.20", + "source-map-support": "^0.5.21", "spawn-please": "^1.0.0", "update-notifier": "^5.1.0" }, @@ -20791,6 +20801,22 @@ "p-limit": "^3.0.2" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -23445,22 +23471,14 @@ "dev": true }, "sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, "requires": { "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", + "uuid": "^8.3.2", "websocket-driver": "^0.7.4" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } } }, "socks": { @@ -24174,9 +24192,9 @@ "dev": true }, "watchpack": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.0.tgz", - "integrity": "sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -24576,24 +24594,24 @@ "dev": true }, "yargs": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.0.tgz", + "integrity": "sha512-GQl1pWyDoGptFPJx9b9L6kmR33TGusZvXIZUT+BOz9f7X2L94oeAskFYLEg/FkhV06zZPBYLvLZRWeYId29lew==", "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" } }, "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==", "dev": true }, "yn": { diff --git a/client/package.json b/client/package.json index 0ee40ed..cef563f 100644 --- a/client/package.json +++ b/client/package.json @@ -1,31 +1,31 @@ { "author": "Chrystian Huot ", "dependencies": { - "@angular/animations": "^13.0.2", - "@angular/cdk": "^13.0.2", - "@angular/common": "~13.0.2", - "@angular/compiler": "~13.0.2", - "@angular/core": "~13.0.2", - "@angular/forms": "~13.0.2", - "@angular/material": "^13.0.2", - "@angular/platform-browser": "~13.0.2", - "@angular/platform-browser-dynamic": "~13.0.2", - "@angular/router": "^13.0.2", - "@angular/service-worker": "^13.0.2", + "@angular/animations": "^13.0.3", + "@angular/cdk": "^13.0.3", + "@angular/common": "~13.0.3", + "@angular/compiler": "~13.0.3", + "@angular/core": "~13.0.3", + "@angular/forms": "~13.0.3", + "@angular/material": "^13.0.3", + "@angular/platform-browser": "~13.0.3", + "@angular/platform-browser-dynamic": "~13.0.3", + "@angular/router": "^13.0.3", + "@angular/service-worker": "^13.0.3", "rxjs": "~7.4.0", "tslib": "^2.3.1", "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "~13.0.3", - "@angular/cli": "^13.0.3", - "@angular/compiler-cli": "~13.0.2", - "@types/node": "~16.11.11", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", + "@angular-devkit/build-angular": "~13.0.4", + "@angular/cli": "^13.0.4", + "@angular/compiler-cli": "~13.0.3", + "@types/node": "~16.11.12", + "@typescript-eslint/eslint-plugin": "^5.6.0", + "@typescript-eslint/parser": "^5.6.0", "ajv-keywords": "^5.1.0", - "eslint": "^8.3.0", - "npm-check-updates": "^12.0.2", + "eslint": "^8.4.1", + "npm-check-updates": "^12.0.3", "ts-node": "~10.4.0", "typescript": "~4.4.4" }, @@ -39,5 +39,5 @@ "build": "ng build --base-href ./ --configuration production", "start": "ng serve" }, - "version": "6.0.3" + "version": "6.0.4" } diff --git a/client/src/app/components/rdio-scanner/rdio-scanner.service.ts b/client/src/app/components/rdio-scanner/rdio-scanner.service.ts index 7dfa553..7174774 100644 --- a/client/src/app/components/rdio-scanner/rdio-scanner.service.ts +++ b/client/src/app/components/rdio-scanner/rdio-scanner.service.ts @@ -757,8 +757,6 @@ export class RdioScannerService implements OnDestroy { } }; - this.websocket.onerror = () => this.event.emit({ linked: false }); - this.websocket.onopen = () => { this.event.emit({ linked: true }); diff --git a/docs/platforms/darwin.md b/docs/platforms/darwin.md index bfb009a..fa1b6cc 100644 --- a/docs/platforms/darwin.md +++ b/docs/platforms/darwin.md @@ -25,8 +25,8 @@ Here is a list of recorders known to work with [Rdio Scanner](https://github.com You can enjoy your [Rdio Scanner](https://github.com/chuot/rdio-scanner) on the go on your mobile device with the native app. -[![Available on the App Store](./docs/images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) -[![Get it on Google Play](./docs/images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) +[![Available on the App Store](../images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) +[![Get it on Google Play](../images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) \pagebreak{} @@ -41,8 +41,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@macos ~ % mkdir rdio-scanner rdio@macos ~ % cd rdio-scanner rdio@macos rdio-scanner % unzip \ - > ~/Downloads/rdio-scanner-darwin-arm64-v6.0.3.zip - Archive: /Users/rdio/Downloads/rdio-scanner-darwin-arm64-v6.0.3.zip + > ~/Downloads/rdio-scanner-darwin-arm64-v6.0.4.zip + Archive: /Users/rdio/Downloads/rdio-scanner-darwin-arm64-v6.0.4.zip inflating: rdio-scanner inflating: rdio-scanner.pdf @@ -50,11 +50,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@macos rdio-scanner % ./rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 08:38:06 server started - 2021/11/29 08:38:06 main interface at http://macos.local:3000 - 2021/11/29 08:38:06 admin interface at http://macos.local:3000/admin + 2021/12/08 08:38:06 server started + 2021/12/08 08:38:06 main interface at http://macos.local:3000 + 2021/12/08 08:38:06 admin interface at http://macos.local:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -76,11 +76,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance rdio@macos rdio-scanner % ./rdio-scanner --listen :80 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 08:48:03 server started - 2021/11/29 08:48:03 main interface at http://macos.local - 2021/11/29 08:48:03 admin interface at http://macos.local/admin + 2021/12/08 08:48:03 server started + 2021/12/08 08:48:03 main interface at http://macos.local + 2021/12/08 08:48:03 admin interface at http://macos.local/admin ## Listening with SSL with self-signed certificates @@ -89,8 +89,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. rdio@macos rdio-scanner % ./rdio-scanner -ssl_create - 2021/11/29 08:49:16 generating ssl certificate files - 2021/11/29 08:49:17 ssl files created + 2021/12/08 08:49:16 generating ssl certificate files + 2021/12/08 08:49:17 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -107,12 +107,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_key_file server.key \ > -ssl_listen :443 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 08:50:58 server started - 2021/11/29 08:50:58 main interface at http://macos.local - 2021/11/29 08:50:58 main interface at https://macos.local - 2021/11/29 08:50:58 admin interface at https://macos.local/admin + 2021/12/08 08:50:58 server started + 2021/12/08 08:50:58 main interface at http://macos.local + 2021/12/08 08:50:58 main interface at https://macos.local + 2021/12/08 08:50:58 admin interface at https://macos.local/admin ## Save your advanced configuration to a config file @@ -124,7 +124,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2021/11/29 08:52:24 rdio-scanner.ini file created + 2021/12/08 08:52:24 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -139,12 +139,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an rdio@macos rdio-scanner % ./rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 08:54:08 server started - 2021/11/29 08:54:08 main interface at http://macos.local - 2021/11/29 08:54:08 main interface at https://macos.local - 2021/11/29 08:54:08 admin interface at https://macos.local/admin + 2021/12/08 08:54:08 server started + 2021/12/08 08:54:08 main interface at http://macos.local + 2021/12/08 08:54:08 main interface at https://macos.local + 2021/12/08 08:54:08 admin interface at https://macos.local/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/freebsd.md b/docs/platforms/freebsd.md index d01cc37..cb3f826 100644 --- a/docs/platforms/freebsd.md +++ b/docs/platforms/freebsd.md @@ -25,8 +25,8 @@ Here is a list of recorders known to work with [Rdio Scanner](https://github.com You can enjoy your [Rdio Scanner](https://github.com/chuot/rdio-scanner) on the go on your mobile device with the native app. -[![Available on the App Store](./docs/images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) -[![Get it on Google Play](./docs/images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) +[![Available on the App Store](../images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) +[![Get it on Google Play](../images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) \pagebreak{} @@ -41,8 +41,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@pc-freebsd:~ $ mkdir rdio-scanner rdio@pc-freebsd:~ $ cd rdio-scanner rdio@pc-freebsd:~/rdio-scanner $ unzip \ - > ~/rdio-scanner-freebsd-amd64-v6.0.3.zip - Archive: ../rdio-scanner-freebsd-amd64-v6.0.3.zip + > ~/rdio-scanner-freebsd-amd64-v6.0.4.zip + Archive: ../rdio-scanner-freebsd-amd64-v6.0.4.zip extracting: rdio-scanner extracting: rdio-scanner.pdf @@ -50,11 +50,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@pc-freebsd:~/rdio-scanner $ ./rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/28 08:16:36 server started - 2021/11/28 08:16:36 main interface at http://pc-freebsd:3000 - 2021/11/28 08:16:36 admin interface at http://pc-freebsd:3000/admin + 2021/12/08 08:16:36 server started + 2021/12/08 08:16:36 main interface at http://pc-freebsd:3000 + 2021/12/08 08:16:36 admin interface at http://pc-freebsd:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -80,11 +80,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance Password: root@pc-freebsd:/home/rdio/rdio-scanner # ./rdio-scanner -listen :80 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/28 08:19:38 server started - 2021/11/28 08:19:38 main interface at http://pc-freebsd - 2021/11/28 08:19:38 admin interface at http://pc-freebsd/admin + 2021/12/08 08:19:38 server started + 2021/12/08 08:19:38 main interface at http://pc-freebsd + 2021/12/08 08:19:38 admin interface at http://pc-freebsd/admin ## Listening with SSL with self-signed certificates @@ -93,8 +93,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. rdio@pc-freebsd:~/rdio-scanner $ ./rdio-scanner -ssl_create - 2021/11/28 10:32:17 generating ssl certificate files - 2021/11/28 10:32:19 ssl files created + 2021/12/08 10:32:17 generating ssl certificate files + 2021/12/08 10:32:19 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -113,12 +113,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_key_file server.key \ > -ssl_listen :443 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/28 10:34:29 server started - 2021/11/28 10:34:29 main interface at http://pc-freebsd - 2021/11/28 10:34:29 main interface at https://pc-freebsd - 2021/11/28 10:34:29 admin interface at https://pc-freebsd/admin + 2021/12/08 10:34:29 server started + 2021/12/08 10:34:29 main interface at http://pc-freebsd + 2021/12/08 10:34:29 main interface at https://pc-freebsd + 2021/12/08 10:34:29 admin interface at https://pc-freebsd/admin ## Save your advanced configuration to a config file @@ -130,7 +130,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2021/11/28 10:37:00 rdio-scanner.ini file created + 2021/12/08 10:37:00 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -147,12 +147,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an Password: root@pc-freebsd:/home/rdio/rdio-scanner # ./rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/28 10:38:28 server started - 2021/11/28 10:38:29 main interface at http://pc-freebsd - 2021/11/28 10:38:29 main interface at https://pc-freebsd - 2021/11/28 10:38:29 admin interface at https://pc-freebsd/admin + 2021/12/08 10:38:28 server started + 2021/12/08 10:38:29 main interface at http://pc-freebsd + 2021/12/08 10:38:29 main interface at https://pc-freebsd + 2021/12/08 10:38:29 admin interface at https://pc-freebsd/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/linux.md b/docs/platforms/linux.md index 33b6b34..9ed8787 100644 --- a/docs/platforms/linux.md +++ b/docs/platforms/linux.md @@ -25,8 +25,8 @@ Here is a list of recorders known to work with [Rdio Scanner](https://github.com You can enjoy your [Rdio Scanner](https://github.com/chuot/rdio-scanner) on the go on your mobile device with the native app. -[![Available on the App Store](./docs/images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) -[![Get it on Google Play](./docs/images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) +[![Available on the App Store](../images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) +[![Get it on Google Play](../images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) \pagebreak{} @@ -41,8 +41,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd [rdio@pc-linux ~]$ mkdir rdio-scanner [rdio@pc-linux ~]$ cd rdio-scanner [rdio@pc-linux rdio-scanner]$ unzip \ - > ~/Downloads/rdio-scanner-linux-amd64-v6.0.3.zip - Archive: /home/rdio/Downloads/rdio-scanner-linux-amd64-v6.0.3.zip + > ~/Downloads/rdio-scanner-linux-amd64-v6.0.4.zip + Archive: /home/rdio/Downloads/rdio-scanner-linux-amd64-v6.0.4.zip inflating: rdio-scanner inflating: rdio-scanner.pdf @@ -50,11 +50,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd [rdio@pc-linux rdio-scanner]$ ./rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 09:11:48 server started - 2021/11/29 09:11:48 main interface at http://pc-linux:3000 - 2021/11/29 09:11:48 admin interface at http://pc-linux:3000/admin + 2021/12/08 09:11:48 server started + 2021/12/08 09:11:48 main interface at http://pc-linux:3000 + 2021/12/08 09:11:48 admin interface at http://pc-linux:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -77,11 +77,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance [rdio@pc-linux rdio-scanner]$ sudo ./rdio-scanner -listen :80 [sudo] password for rdio: - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 09:14:00 server started - 2021/11/29 09:14:00 main interface at http://pc-linux - 2021/11/29 09:14:00 admin interface at http://pc-linux/admin + 2021/12/08 09:14:00 server started + 2021/12/08 09:14:00 main interface at http://pc-linux + 2021/12/08 09:14:00 admin interface at http://pc-linux/admin ## Listening with SSL with self-signed certificates @@ -90,8 +90,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. [rdio@pc-linux rdio-scanner]$ ./rdio-scanner -ssl_create - 2021/11/29 09:15:03 generating ssl certificate files - 2021/11/29 09:15:05 ssl files created + 2021/12/08 09:15:03 generating ssl certificate files + 2021/12/08 09:15:05 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -109,12 +109,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_listen :443 [sudo] password for rdio: - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 09:16:47 server started - 2021/11/29 09:16:47 main interface at http://pc-linux - 2021/11/29 09:16:47 main interface at https://pc-linux - 2021/11/29 09:16:47 admin interface at https://pc-linux/admin + 2021/12/08 09:16:47 server started + 2021/12/08 09:16:47 main interface at http://pc-linux + 2021/12/08 09:16:47 main interface at https://pc-linux + 2021/12/08 09:16:47 admin interface at https://pc-linux/admin ## Save your advanced configuration to a config file @@ -126,7 +126,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2021/11/29 09:19:29 rdio-scanner.ini file created + 2021/12/08 09:19:29 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -142,12 +142,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an [rdio@pc-linux rdio-scanner]$ sudo ./rdio-scanner [sudo] Mot de passe de rdio : - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/29 09:20:40 server started - 2021/11/29 09:20:40 main interface at http://pc-linux - 2021/11/29 09:20:40 main interface at https://pc-linux - 2021/11/29 09:20:40 admin interface at https://pc-linux/admin + 2021/12/08 09:20:40 server started + 2021/12/08 09:20:40 main interface at http://pc-linux + 2021/12/08 09:20:40 main interface at https://pc-linux + 2021/12/08 09:20:40 admin interface at https://pc-linux/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/windows.md b/docs/platforms/windows.md index acb8ca7..f2ee3c0 100644 --- a/docs/platforms/windows.md +++ b/docs/platforms/windows.md @@ -25,8 +25,8 @@ Here is a list of recorders known to work with [Rdio Scanner](https://github.com You can enjoy your [Rdio Scanner](https://github.com/chuot/rdio-scanner) on the go on your mobile device with the native app. -[![Available on the App Store](./docs/images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) -[![Get it on Google Play](./docs/images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) +[![Available on the App Store](../images/app-store-badge.png?raw=true)](https://apps.apple.com/us/app/rdio-scanner/id1563065667#?platform=iphone) +[![Get it on Google Play](../images/google-play-badge.png?raw=true)](https://play.google.com/store/apps/details?id=solutions.saubeo.rdioScanner) \pagebreak{} @@ -43,7 +43,7 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd C:\Users\rdio> cd rdio-scanner C:\Users\rdio\rdio-scanner> tar -xvf ^ - ..\downloads\rdio-scanner-windows-amd64-v6.0.3.zip + ..\downloads\rdio-scanner-windows-amd64-v6.0.4.zip x rdio-scanner.exe x rdio-scanner.pdf @@ -51,11 +51,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd C:\Users\rdio\rdio-scanner>rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/25 13:48:48 server started - 2021/11/25 13:48:48 main interface at http://pc-windows:3000 - 2021/11/25 13:48:48 admin interface at http://pc-windows:3000/admin + 2021/12/08 13:48:48 server started + 2021/12/08 13:48:48 main interface at http://pc-windows:3000 + 2021/12/08 13:48:48 admin interface at http://pc-windows:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -77,11 +77,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance C:\Users\rdio\rdio-scanner>rdio-scanner -listen :80 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/26 10:53:31 server started - 2021/11/26 10:53:31 main interface at http://pc-windows - 2021/11/26 10:53:31 admin interface at http://pc-windows/admin + 2021/12/08 10:53:31 server started + 2021/12/08 10:53:31 main interface at http://pc-windows + 2021/12/08 10:53:31 admin interface at http://pc-windows/admin ## Listening with SSL with self-signed certificates @@ -90,8 +90,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. C:\Users\rdio\rdio-scanner>rdio-scanner -ssl_create - 2021/11/26 10:58:51 generating ssl certificate files - 2021/11/26 10:58:54 ssl files created + 2021/12/08 10:58:51 generating ssl certificate files + 2021/12/08 10:58:54 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -108,12 +108,12 @@ Now we use the self-signed server certificate to run our instance. -ssl_key_file server.key ^ -ssl_listen :443 - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/26 11:05:43 server started - 2021/11/26 11:05:43 main interface at http://pc-windows - 2021/11/26 11:05:43 main interface at https://pc-windows - 2021/11/26 11:05:43 admin interface at https://pc-windows/admin + 2021/12/08 11:05:43 server started + 2021/12/08 11:05:43 main interface at http://pc-windows + 2021/12/08 11:05:43 main interface at https://pc-windows + 2021/12/08 11:05:43 admin interface at https://pc-windows/admin ## Save your advanced configuration to a config file @@ -125,7 +125,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y -ssl_key_file server.key ^ -ssl_listen :443 ^ -config_save - 2021/11/26 11:08:28 rdio-scanner.ini file created + 2021/12/08 11:08:28 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -140,12 +140,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an C:\Users\rdio\rdio-scanner>rdio-scanner - Rdio Scanner v6.0.3 + Rdio Scanner v6.0.4 ---------------------------------- - 2021/11/26 11:11:28 server started - 2021/11/26 11:11:28 main interface at http://pc-windows - 2021/11/26 11:11:28 main interface at https://pc-windows - 2021/11/26 11:11:28 admin interface at https://pc-windows/admin + 2021/12/08 11:11:28 server started + 2021/12/08 11:11:28 main interface at http://pc-windows + 2021/12/08 11:11:28 main interface at https://pc-windows + 2021/12/08 11:11:28 admin interface at https://pc-windows/admin \pagebreak{} diff --git a/server/access.go b/server/access.go index 113c64b..c5a9303 100644 --- a/server/access.go +++ b/server/access.go @@ -202,11 +202,9 @@ func (accesses *Accesses) Read(db *Database) error { *accesses = append(*accesses, access) } - if err != nil { - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -270,12 +268,9 @@ func (accesses *Accesses) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/admin.go b/server/admin.go index 40472b1..ea09b3f 100644 --- a/server/admin.go +++ b/server/admin.go @@ -37,7 +37,6 @@ const ( ) type Admin struct { - initialized bool Attempts AdminLoginAttempts AttemptsMax uint AttemptsMaxDelay time.Duration @@ -47,6 +46,7 @@ type Admin struct { Register chan *websocket.Conn Tokens []string Unregister chan *websocket.Conn + running bool } type AdminLoginAttempt struct { @@ -56,6 +56,20 @@ type AdminLoginAttempt struct { type AdminLoginAttempts map[string]*AdminLoginAttempt +func NewAdmin(controller *Controller) *Admin { + return &Admin{ + Attempts: AdminLoginAttempts{}, + AttemptsMax: uint(3), + AttemptsMaxDelay: time.Duration(time.Duration.Minutes(10)), + Broadcast: make(chan *[]byte, 100), + Conns: make(map[*websocket.Conn]bool), + Controller: controller, + Register: make(chan *websocket.Conn, 100), + Tokens: []string{}, + Unregister: make(chan *websocket.Conn, 100), + } +} + func (admin *Admin) BroadcastConfig() { if b, err := json.Marshal(admin.GetConfig()); err == nil { @@ -298,52 +312,6 @@ func (admin *Admin) GetConfig() map[string]interface{} { } } -func (admin *Admin) Init(controller *Controller) error { - if admin.initialized { - return errors.New("admin already initialized") - } - - admin.initialized = true - admin.Attempts = AdminLoginAttempts{} - admin.AttemptsMax = uint(3) - admin.AttemptsMaxDelay = time.Duration(time.Duration.Minutes(10)) - admin.Broadcast = make(chan *[]byte, 100) - admin.Conns = make(map[*websocket.Conn]bool) - admin.Controller = controller - admin.Register = make(chan *websocket.Conn, 100) - admin.Tokens = []string{} - admin.Unregister = make(chan *websocket.Conn, 100) - - go func() { - for { - select { - case data, ok := <-admin.Broadcast: - if !ok { - return - } - - for conn := range admin.Conns { - err := conn.WriteMessage(websocket.TextMessage, *data) - if err != nil { - admin.Unregister <- conn - } - } - - case conn := <-admin.Register: - admin.Conns[conn] = true - - case conn := <-admin.Unregister: - if _, ok := admin.Conns[conn]; ok { - delete(admin.Conns, conn) - conn.Close() - } - } - } - }() - - return nil -} - func (admin *Admin) LogsHandler(w http.ResponseWriter, r *http.Request) { t := admin.GetAuthorization(r) if !admin.ValidateToken(t) { @@ -570,6 +538,43 @@ func (admin *Admin) SendConfig(w http.ResponseWriter) { } } +func (admin *Admin) Start() error { + if admin.running { + return errors.New("admin already running") + } else { + admin.running = true + } + + go func() { + for { + select { + case data, ok := <-admin.Broadcast: + if !ok { + return + } + + for conn := range admin.Conns { + err := conn.WriteMessage(websocket.TextMessage, *data) + if err != nil { + admin.Unregister <- conn + } + } + + case conn := <-admin.Register: + admin.Conns[conn] = true + + case conn := <-admin.Unregister: + if _, ok := admin.Conns[conn]; ok { + delete(admin.Conns, conn) + conn.Close() + } + } + } + }() + + return nil +} + func (admin *Admin) ValidateToken(sToken string) bool { found := false for _, t := range admin.Tokens { diff --git a/server/api.go b/server/api.go index 7d5f340..d5be6cb 100644 --- a/server/api.go +++ b/server/api.go @@ -17,7 +17,6 @@ package main import ( "encoding/json" - "errors" "fmt" "io" "mime" @@ -35,18 +34,11 @@ const ( ) type Api struct { - initialized bool - Controller *Controller + Controller *Controller } -func (api *Api) Init(controller *Controller) error { - if api.initialized { - return errors.New("api already initialized") - } - - api.Controller = controller - - return nil +func NewApi(controller *Controller) *Api { + return &Api{Controller: controller} } func (api *Api) CallUploadHandler(w http.ResponseWriter, r *http.Request) { diff --git a/server/apikey.go b/server/apikey.go index 860f509..ce2d85f 100644 --- a/server/apikey.go +++ b/server/apikey.go @@ -174,10 +174,10 @@ func (apikeys *Apikeys) Read(db *Database) error { rows.Close() if err != nil { - err = formatError(err) + return formatError(err) } - return err + return nil } func (apikeys *Apikeys) Write(db *Database) error { @@ -239,12 +239,9 @@ func (apikeys *Apikeys) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/client.go b/server/client.go index 331f36e..467e4e0 100644 --- a/server/client.go +++ b/server/client.go @@ -49,7 +49,7 @@ func (client *Client) Init(controller *Controller, conn *websocket.Conn) error { client.Access = &Access{} client.Controller = controller client.Conn = conn - client.Send = make(chan *Message, 100) + client.Send = make(chan *Message, 8) client.LivefeedMap = LivefeedMap{} controller.Register <- client diff --git a/server/config.go b/server/config.go index c207786..fba2e37 100644 --- a/server/config.go +++ b/server/config.go @@ -35,6 +35,7 @@ const ( ) type Config struct { + BaseDir string ConfigFile string DbType string DbFile string @@ -53,43 +54,7 @@ type Config struct { newAdminPassword string } -func (config *Config) GetConfigFilePath() string { - return config.GetPath(config.ConfigFile) -} - -func (config *Config) GetDbFilePath() string { - return config.GetPath(config.DbFile) -} - -func (config *Config) GetPath(p string) string { - if !path.IsAbs(p) { - if exe, err := os.Executable(); err == nil { - if !regexp.MustCompile(`go-build[0-9]+`).Match([]byte(exe)) { - return path.Join(filepath.Dir(exe), p) - } - } - } - - return p -} - -func (config *Config) GetSslCaCertFilePath() string { - return config.GetPath(config.SslCaCertFile) -} - -func (config *Config) GetSslCaKeyFilePath() string { - return config.GetPath(config.SslCaKeyFile) -} - -func (config *Config) GetSslCertFilePath() string { - return config.GetPath(config.SslCertFile) -} - -func (config *Config) GetSslKeyFilePath() string { - return config.GetPath(config.SslKeyFile) -} - -func (config *Config) Init() (ok bool, error error) { +func NewConfig() *Config { const ( defaultAdminUrl = "/admin" defaultConfigFile = "rdio-scanner.ini" @@ -101,6 +66,7 @@ func (config *Config) Init() (ok bool, error error) { ) var ( + config = &Config{} configSave = flag.Bool("config_save", false, fmt.Sprintf("save configuration to %s", defaultConfigFile)) serviceAction = flag.String("service", "", "service command, one of start, stop, restart, install, uninstall") sslCreate = flag.Bool("ssl_create", false, "create self-signed certificates") @@ -121,33 +87,50 @@ func (config *Config) Init() (ok bool, error error) { flag.StringVar(&config.SslKeyFile, "ssl_key_file", "", "ssl PEM formated key") flag.StringVar(&config.SslListen, "ssl_listen", "", "listening address for ssl") flag.StringVar(&config.newAdminPassword, "admin_password", "", "change admin password") - flag.Parse() + if exe, err := os.Executable(); err == nil { + if !regexp.MustCompile(`go-build[0-9]+`).Match([]byte(exe)) { + config.BaseDir = filepath.Dir(exe) + if !config.isBaseDirWritable() { + if h, err := os.UserHomeDir(); err == nil { + config.BaseDir = filepath.Join(h, "Rdio Scanner") + if _, err := os.Stat(config.BaseDir); os.IsNotExist(err) { + os.MkdirAll(config.BaseDir, 0770) + } + } + } + } + } + + if !config.isBaseDirWritable() { + log.Fatalf("no write permissions in %s", config.BaseDir) + } + switch { case *configSave: if err := config.saveConfig(); err == nil { - log.Printf("%s file created", config.ConfigFile) - return false, nil - + fmt.Printf("%s file created\n", config.ConfigFile) + os.Exit(0) } else { - return false, err + fmt.Printf("error: %s\n", err.Error()) + os.Exit(-1) } case *sslCreate: - log.Print("generating ssl certificate files") + fmt.Println("generating ssl certificate files") if err := CreateSelfSignedCert(config); err == nil { - log.Print("ssl files created") - return false, nil - + fmt.Println("ssl files created") + os.Exit(0) } else { - return false, err + fmt.Printf("error: %s", err.Error()) + os.Exit(-1) } case *version: fmt.Println(Version) - return false, nil + os.Exit(0) default: if cfg, err := ini.Load(config.GetConfigFilePath()); err == nil { @@ -201,15 +184,56 @@ func (config *Config) Init() (ok bool, error error) { } if !(config.DbType == DbTypeMariadb || config.DbType == DbTypeMysql || config.DbType == DbTypeSqlite) { - return false, fmt.Errorf("unknown database type %s", config.DbType) + fmt.Printf("unknown database type %s\n", config.DbType) + return nil } } if *serviceAction != "" { - return NewDaemon().Control(*serviceAction) + NewDaemon().Control(*serviceAction) } - return true, nil + return config +} + +func (config *Config) GetConfigFilePath() string { + return config.GetPath(config.ConfigFile) +} + +func (config *Config) GetDbFilePath() string { + return config.GetPath(config.DbFile) +} + +func (config *Config) GetPath(p string) string { + if path.IsAbs(p) { + return p + } + return path.Join(config.BaseDir, p) +} + +func (config *Config) GetSslCaCertFilePath() string { + return config.GetPath(config.SslCaCertFile) +} + +func (config *Config) GetSslCaKeyFilePath() string { + return config.GetPath(config.SslCaKeyFile) +} + +func (config *Config) GetSslCertFilePath() string { + return config.GetPath(config.SslCertFile) +} + +func (config *Config) GetSslKeyFilePath() string { + return config.GetPath(config.SslKeyFile) +} + +func (config *Config) isBaseDirWritable() bool { + if f, err := os.CreateTemp(config.BaseDir, ".tmp*"); err == nil { + f.Close() + os.Remove(f.Name()) + return true + } + return false } func (config *Config) saveConfig() error { diff --git a/server/controller.go b/server/controller.go index 179c842..d6c3d47 100644 --- a/server/controller.go +++ b/server/controller.go @@ -48,9 +48,34 @@ type Controller struct { Register chan *Client Unregister chan *Client Ingest chan *Call - initialized bool ffmpeg bool ffmpegWarned bool + running bool +} + +func NewController(config *Config) *Controller { + controller := &Controller{ + Config: config, + Accesses: &Accesses{}, + Apikeys: &Apikeys{}, + Dirwatches: &Dirwatches{}, + Downstreams: &Downstreams{}, + Groups: &Groups{}, + Options: &Options{}, + Systems: &Systems{}, + Tags: &Tags{}, + Clients: make(map[*Client]bool), + Register: make(chan *Client, 64), + Unregister: make(chan *Client, 64), + Ingest: make(chan *Call, 64), + } + + controller.Admin = NewAdmin(controller) + controller.Api = NewApi(controller) + controller.Database = NewDatabase(config) + controller.Scheduler = NewScheduler(controller) + + return controller } func (controller *Controller) CheckDuplicate(call *Call) bool { @@ -68,7 +93,7 @@ func (controller *Controller) CheckDuplicate(call *Call) bool { return count > 0 } -func (controller *Controller) ConvertAudio(call *Call) error { +func (controller *Controller) ConvertAudio(call *Call) { var ( args = []string{"-i", "-"} err error @@ -80,8 +105,7 @@ func (controller *Controller) ConvertAudio(call *Call) error { LogEvent(controller.Database, LogLevelWarn, "ffmpeg is not accessible, no audio conversion will be performed.") } - - return nil + return } if system, ok := controller.Systems.GetSystem(call.System); ok { @@ -106,6 +130,9 @@ func (controller *Controller) ConvertAudio(call *Call) error { stdout := bytes.NewBuffer([]byte(nil)) cmd.Stdout = stdout + stderr := bytes.NewBuffer([]byte(nil)) + cmd.Stderr = stderr + if err = cmd.Run(); err == nil { call.Audio = stdout.Bytes() call.AudioType = "audio/mp4" @@ -114,9 +141,10 @@ func (controller *Controller) ConvertAudio(call *Call) error { case string: call.AudioName = fmt.Sprintf("%v.m4a", strings.TrimSuffix(v, path.Ext((v)))) } - } - return err + } else { + fmt.Println(stderr.String()) + } } func (controller *Controller) EmitCall(call *Call) { @@ -323,10 +351,7 @@ func (controller *Controller) IngestCall(call *Call) { } if !controller.Options.DisableAudioConversion { - if err = controller.ConvertAudio(call); err != nil { - logError(fmt.Errorf("convertaudio: %s", err.Error())) - return - } + controller.ConvertAudio(call) } if id, err = call.Write(controller.Database); err == nil { @@ -339,111 +364,6 @@ func (controller *Controller) IngestCall(call *Call) { } } -func (controller *Controller) Init(config *Config, database *Database) error { - if controller.initialized { - return errors.New("controller already initialized") - } - - var err error - - controller.initialized = true - controller.Admin = &Admin{} - controller.Api = &Api{} - controller.Config = config - controller.Database = database - controller.Accesses = &Accesses{} - controller.Apikeys = &Apikeys{} - controller.Dirwatches = &Dirwatches{} - controller.Downstreams = &Downstreams{} - controller.Groups = &Groups{} - controller.Options = &Options{} - controller.Scheduler = &Scheduler{} - controller.Systems = &Systems{} - controller.Tags = &Tags{} - controller.Clients = make(map[*Client]bool) - controller.Register = make(chan *Client, 64) - controller.Unregister = make(chan *Client, 64) - controller.Ingest = make(chan *Call, 64) - - if err = controller.Accesses.Read(database); err != nil { - return err - } - if err = controller.Apikeys.Read(database); err != nil { - return err - } - if err = controller.Dirwatches.Read(database); err != nil { - return err - } - if err = controller.Downstreams.Read(database); err != nil { - return err - } - if err = controller.Groups.Read(database); err != nil { - return err - } - if err = controller.Options.Read(database); err != nil { - return err - } - if err = controller.Systems.Read(database); err != nil { - return err - } - if err = controller.Tags.Read(database); err != nil { - return err - } - - if err = controller.Admin.Init(controller); err != nil { - return err - } - if err = controller.Api.Init(controller); err != nil { - return err - } - if err = controller.Scheduler.Init(controller); err != nil { - return err - } - - cmd := exec.Command("ffmpeg", "-version") - if err := cmd.Run(); err == nil { - controller.ffmpeg = true - - } else { - controller.ffmpeg = false - } - - if err = controller.Scheduler.Start(); err != nil { - log.Printf("scheduler: %s", err.Error()) - } - - go func() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - <-c - controller.Terminate() - }() - - go func() { - for { - select { - case call := <-controller.Ingest: - controller.IngestCall(call) - - case client := <-controller.Register: - controller.Clients[client] = true - controller.LogClientsCount() - - case client := <-controller.Unregister: - if _, ok := controller.Clients[client]; ok { - delete(controller.Clients, client) - close(client.Send) - controller.LogClientsCount() - } - } - } - }() - - controller.Dirwatches.Start(controller) - - return nil -} - func (controller *Controller) LogClientsCount() { LogEvent( controller.Database, @@ -629,6 +549,93 @@ func (controller *Controller) SendClientConfig(client *Client) { } } +func (controller *Controller) Start() error { + var err error + + if controller.running { + return errors.New("controller already running") + } else { + controller.running = true + } + + LogEvent(controller.Database, LogLevelWarn, "server started") + + if len(controller.Config.BaseDir) > 0 { + LogEvent(controller.Database, LogLevelWarn, fmt.Sprintf("base folder is %s", controller.Config.BaseDir)) + } + + if err = controller.Accesses.Read(controller.Database); err != nil { + return err + } + if err = controller.Apikeys.Read(controller.Database); err != nil { + return err + } + if err = controller.Dirwatches.Read(controller.Database); err != nil { + return err + } + if err = controller.Downstreams.Read(controller.Database); err != nil { + return err + } + if err = controller.Groups.Read(controller.Database); err != nil { + return err + } + if err = controller.Options.Read(controller.Database); err != nil { + return err + } + if err = controller.Systems.Read(controller.Database); err != nil { + return err + } + if err = controller.Tags.Read(controller.Database); err != nil { + return err + } + + if err = controller.Admin.Start(); err != nil { + return err + } + if err = controller.Scheduler.Start(); err != nil { + return err + } + + cmd := exec.Command("ffmpeg", "-version") + if err := cmd.Run(); err == nil { + controller.ffmpeg = true + + } else { + controller.ffmpeg = false + } + + go func() { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + <-c + controller.Terminate() + }() + + go func() { + for { + select { + case call := <-controller.Ingest: + controller.IngestCall(call) + + case client := <-controller.Register: + controller.Clients[client] = true + controller.LogClientsCount() + + case client := <-controller.Unregister: + if _, ok := controller.Clients[client]; ok { + delete(controller.Clients, client) + close(client.Send) + controller.LogClientsCount() + } + } + } + }() + + controller.Dirwatches.Start(controller) + + return nil +} + func (controller *Controller) Terminate() { if err := controller.Database.Sql.Close(); err != nil { log.Println(err) @@ -636,6 +643,10 @@ func (controller *Controller) Terminate() { controller.Dirwatches.Stop() + for c := range controller.Clients { + c.Conn.Close() + } + log.Println("terminated") os.Exit(0) diff --git a/server/daemon.go b/server/daemon.go index d262a05..feb74f3 100644 --- a/server/daemon.go +++ b/server/daemon.go @@ -62,14 +62,16 @@ func NewDaemon() *Daemon { return &d } -func (d *Daemon) Control(action string) (bool, error) { +func (d *Daemon) Control(action string) { if action == "run" { go d.Service.Run() - return true, nil - } + } else if err := service.Control(d.Service, action); err == nil { + os.Exit(0) - return false, service.Control(d.Service, action) + } else { + os.Exit(-1) + } } type DaemonInterface struct{} diff --git a/server/database.go b/server/database.go index 69d1d0e..c961c42 100644 --- a/server/database.go +++ b/server/database.go @@ -17,7 +17,6 @@ package main import ( "database/sql" - "errors" "fmt" "log" "time" @@ -27,59 +26,52 @@ import ( ) type Database struct { - initialized bool Config *Config DateTimeFormat string Sql *sql.DB } -func (db *Database) Init(config *Config) error { +func NewDatabase(config *Config) *Database { var err error - if db.initialized { - return errors.New("database already initialized") - } + database := &Database{Config: config} - db.initialized = true - - db.Config = config - - switch db.Config.DbType { + switch config.DbType { case DbTypeSqlite: - db.DateTimeFormat = "2006-01-02 15:04:05.000 -07:00" + database.DateTimeFormat = "2006-01-02 15:04:05.000 -07:00" - dsn := fmt.Sprintf("file:%s", db.Config.GetDbFilePath()) + dsn := fmt.Sprintf("file:%s", config.GetDbFilePath()) - if db.Sql, err = sql.Open("sqlite", dsn); err != nil { - return err + if database.Sql, err = sql.Open("sqlite", dsn); err != nil { + log.Fatal(err) } case DbTypeMariadb, DbTypeMysql: - db.DateTimeFormat = "2006-01-02 15:04:05" + database.DateTimeFormat = "2006-01-02 15:04:05" - dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", db.Config.DbUsername, db.Config.DbPassword, db.Config.DbHost, db.Config.DbPort, db.Config.DbName) + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", config.DbUsername, config.DbPassword, config.DbHost, config.DbPort, config.DbName) - if db.Sql, err = sql.Open("mysql", dsn); err != nil { - return err + if database.Sql, err = sql.Open("mysql", dsn); err != nil { + log.Fatal(err) } default: - return fmt.Errorf("unknown database type %s", db.Config.DbType) + log.Fatalf("unknown database type %s\n", config.DbType) } - db.Sql.SetConnMaxLifetime(0) - db.Sql.SetMaxIdleConns(10) - db.Sql.SetMaxOpenConns(10) + database.Sql.SetConnMaxLifetime(0) + database.Sql.SetMaxIdleConns(10) + database.Sql.SetMaxOpenConns(10) - if err = db.migrate(); err != nil { - return err + if err = database.migrate(); err != nil { + log.Fatal(err) } - if err = db.seed(); err != nil { - return err + if err = database.seed(); err != nil { + log.Fatal(err) } - return nil + return database } func (db *Database) ParseDateTime(f interface{}) (time.Time, error) { @@ -102,7 +94,7 @@ func (db *Database) Prune(controller *Controller) error { LogEvent(controller.Database, LogLevelInfo, "database pruning") - date := time.Now().Truncate(time.Duration(controller.Options.PruneDays*24) * time.Hour).Format(db.DateTimeFormat) + date := time.Now().Add(-24 * time.Hour * time.Duration(controller.Options.PruneDays)).Format(db.DateTimeFormat) if _, err := controller.Database.Sql.Exec("delete from `rdioScannerCalls` where `dateTime` < ?", date); err != nil { return err diff --git a/server/dirwatch.go b/server/dirwatch.go index 7d8545d..503efd5 100644 --- a/server/dirwatch.go +++ b/server/dirwatch.go @@ -274,7 +274,7 @@ func (dirwatch *Dirwatch) ingestTrunkRecorder(p string) error { } if call.Audio, err = ioutil.ReadFile(audioName); err != nil { - return err + return nil } if b, err = ioutil.ReadFile(p); err != nil { @@ -494,20 +494,24 @@ func (dirwatch *Dirwatch) Start(controller *Controller) error { } }() - fileSystem := os.DirFS(dirwatch.Directory) + go func() { + time.Sleep(2 * time.Second) - return fs.WalkDir(fileSystem, ".", func(p string, d fs.DirEntry, err error) error { - fp := path.Join(dirwatch.Directory, p) + fs.WalkDir(os.DirFS(dirwatch.Directory), ".", func(p string, d fs.DirEntry, err error) error { + fp := path.Join(dirwatch.Directory, p) - if dirwatch.isDir(fp) { - dirwatch.dirs[fp] = true - dirwatch.watcher.Add(fp) + if dirwatch.isDir(fp) { + dirwatch.dirs[fp] = true + dirwatch.watcher.Add(fp) - } else if dirwatch.DeleteAfter { - dirwatch.Ingest(fp) - } - return err - }) + } else if dirwatch.DeleteAfter { + dirwatch.Ingest(fp) + } + return err + }) + }() + + return nil } func (dirwatch *Dirwatch) Stop() { @@ -582,11 +586,9 @@ func (dirwatches *Dirwatches) Read(db *Database) error { *dirwatches = append(*dirwatches, dirwatch) } - if err != nil { - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -641,8 +643,7 @@ func (dirwatches *Dirwatches) Write(db *Database) error { return formatError(err) } - rows, err = db.Sql.Query("select `_id` from `rdioScannerDirWatches`") - if err != nil { + if rows, err = db.Sql.Query("select `_id` from `rdioScannerDirWatches`"); err != nil { return formatError(err) } @@ -661,12 +662,9 @@ func (dirwatches *Dirwatches) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -674,28 +672,13 @@ func (dirwatches *Dirwatches) Write(db *Database) error { } func (dirwatch *Dirwatch) isDir(d string) bool { - var isDir bool - - logError := func(err error) { - LogEvent(dirwatch.controller.Database, LogLevelError, fmt.Sprintf("dirwatch.isDir: %s", err.Error())) + if fi, err := os.Stat(d); err == nil { + if fi.IsDir() { + return true + } } - if f, err := os.Open(d); err == nil { - if fi, err := f.Stat(); err == nil { - if fi.IsDir() { - isDir = true - } - } else { - logError(err) - } - if err := f.Close(); err != nil { - logError(err) - } - } else { - logError(err) - } - - return isDir + return false } func (dirwatch *Dirwatch) walkDir(d string) error { diff --git a/server/downstream.go b/server/downstream.go index 623fd8f..939d2e4 100644 --- a/server/downstream.go +++ b/server/downstream.go @@ -337,23 +337,24 @@ func (downstreams *Downstreams) FromMap(f []interface{}) { func (downstreams *Downstreams) Read(db *Database) error { var ( - err error - rows *sql.Rows + apikey interface{} + err error + id uint + rows *sql.Rows + systems interface{} ) *downstreams = Downstreams{} + formatError := func(err error) error { + return fmt.Errorf("downstreams.read: %v", err) + } + if rows, err = db.Sql.Query("select `_id`, `apiKey`, `disabled`, `order`, `systems`, `url` from `rdioScannerDownstreams`"); err != nil { - return err + return formatError(err) } for rows.Next() { - var ( - apikey interface{} - id uint - systems interface{} - ) - downstream := Downstream{} if err = rows.Scan(&id, &apikey, &downstream.Disabled, &downstream.Order, &systems, &downstream.Url); err != nil { break @@ -383,12 +384,10 @@ func (downstreams *Downstreams) Read(db *Database) error { *downstreams = append(*downstreams, downstream) } - if err != nil { - return err - } + rows.Close() - if err = rows.Close(); err != nil { - return err + if err != nil { + return formatError(err) } return nil @@ -473,12 +472,9 @@ func (downstreams *Downstreams) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/go.mod b/server/go.mod index bed9965..e6a5cf6 100644 --- a/server/go.mod +++ b/server/go.mod @@ -21,15 +21,15 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/stretchr/testify v1.7.0 // indirect golang.org/x/mod v0.5.1 // indirect - golang.org/x/net v0.0.0-20211205041911-012df41ee64c // indirect - golang.org/x/sys v0.0.0-20211204120058-94396e421777 // indirect + golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b // indirect + golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.8 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect lukechampine.com/uint128 v1.1.1 // indirect modernc.org/cc/v3 v3.35.18 // indirect - modernc.org/ccgo/v3 v3.12.86 // indirect - modernc.org/libc v1.11.88 // indirect + modernc.org/ccgo/v3 v3.12.87 // indirect + modernc.org/libc v1.11.89 // indirect modernc.org/mathutil v1.4.1 // indirect modernc.org/memory v1.0.5 // indirect modernc.org/opt v0.1.1 // indirect diff --git a/server/go.sum b/server/go.sum index ffb01e7..690e6b3 100644 --- a/server/go.sum +++ b/server/go.sum @@ -47,8 +47,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211205041911-012df41ee64c h1:7SfqwP5fxEtl/P02w5IhKc86ziJ+A25yFrkVgoy2FT8= -golang.org/x/net v0.0.0-20211205041911-012df41ee64c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b h1:MWaHNqZy3KTpuTMAGvv+Kw+ylsEpmyJZizz1dqxnu28= +golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -65,8 +65,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211204120058-94396e421777 h1:QAkhGVjOxMa+n4mlsAWeAU+BMZmimQAaNiMu+iUi94E= -golang.org/x/sys v0.0.0-20211204120058-94396e421777/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -141,8 +141,9 @@ modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3 modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= -modernc.org/ccgo/v3 v3.12.86 h1:zN0MkWIf1a2SgP6w9V3EG5r30CSrpRunyzJ5wcYRLFM= modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU= +modernc.org/ccgo/v3 v3.12.87 h1:d8IVZadjkPWICHmMWEaPAL37zBrZ7rE7/+Plegf0cyw= +modernc.org/ccgo/v3 v3.12.87/go.mod h1:55tmwIw8bqNbqYCZ2DIXGqB1I0goRe6tq2qHqr1FaQU= modernc.org/ccorpus v1.11.1 h1:K0qPfpVG1MJh5BYazccnmhywH4zHuOgJXgbjzyp6dWA= modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= @@ -182,8 +183,9 @@ modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0= modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI= modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE= modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY= -modernc.org/libc v1.11.88 h1:ibbHksDVITfJtBTSCENSXRt/pL4P/QJP+EzJUimW268= modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ= +modernc.org/libc v1.11.89 h1:41X0GhYT3+0WbXvsOMDguwnmfY6692gXkSlOuSaO9jc= +modernc.org/libc v1.11.89/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c= modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= diff --git a/server/group.go b/server/group.go index 77c6aec..50794db 100644 --- a/server/group.go +++ b/server/group.go @@ -166,11 +166,9 @@ func (groups *Groups) Read(db *Database) error { *groups = append(*groups, group) } - if err != nil { - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -228,12 +226,9 @@ func (groups *Groups) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/log.go b/server/log.go index 9037f1c..aae5400 100644 --- a/server/log.go +++ b/server/log.go @@ -229,12 +229,10 @@ func NewLogResults(logOptions *LogOptions, db *Database) (*LogResults, error) { logResults.Logs = append(logResults.Logs, log) } - if err != nil { - return logResults, formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { - return logResults, formatError(err) + if err != nil { + return nil, formatError(err) } return logResults, nil diff --git a/server/main.go b/server/main.go index e4fdf59..e23e17b 100644 --- a/server/main.go +++ b/server/main.go @@ -40,27 +40,16 @@ func main() { sslPort string ) - config := &Config{} - ok, err := config.Init() - if err != nil { - log.Fatal(err) - } - if !ok { - os.Exit(0) - } + config := NewConfig() - database := &Database{} - if err = database.Init(config); err != nil { - log.Fatal(err) - } - - controller := &Controller{} - if err = controller.Init(config, database); err != nil { - log.Fatal(err) - } + controller := NewController(config) if config.newAdminPassword != "" { if hash, err := bcrypt.GenerateFromPassword([]byte(config.newAdminPassword), bcrypt.DefaultCost); err == nil { + if err := controller.Options.Read(controller.Database); err != nil { + log.Fatal(err) + } + controller.Options.adminPassword = string(hash) controller.Options.adminPasswordNeedChange = config.newAdminPassword == defaults.adminPassword @@ -68,10 +57,6 @@ func main() { log.Fatal(err) } - if err := controller.Options.Read(controller.Database); err != nil { - log.Fatal(err) - } - LogEvent(controller.Database, LogLevelInfo, "admin password changed.") os.Exit(0) @@ -84,7 +69,9 @@ func main() { fmt.Printf("\nRdio Scanner v%s\n", Version) fmt.Printf("----------------------------------\n") - LogEvent(controller.Database, LogLevelWarn, "server started") + if err := controller.Start(); err != nil { + log.Fatal(err) + } if h, err := os.Hostname(); err == nil { hostname = h diff --git a/server/scheduler.go b/server/scheduler.go index 391d24e..0c53c1d 100644 --- a/server/scheduler.go +++ b/server/scheduler.go @@ -22,22 +22,17 @@ import ( ) type Scheduler struct { - initialized bool - cancel chan interface{} - Controller *Controller - Ticker *time.Ticker + Controller *Controller + Ticker *time.Ticker + cancel chan interface{} + running bool } -func (scheduler *Scheduler) Init(controller *Controller) error { - if scheduler.initialized { - return errors.New("scheduler already initialized") +func NewScheduler(controller *Controller) *Scheduler { + return &Scheduler{ + Controller: controller, + cancel: make(chan interface{}), } - - scheduler.Controller = controller - scheduler.cancel = make(chan interface{}) - scheduler.initialized = true - - return nil } func (scheduler *Scheduler) run() { @@ -55,14 +50,10 @@ func (scheduler *Scheduler) run() { } func (scheduler *Scheduler) Start() error { - if !scheduler.initialized { - return errors.New("scheduler not initialized") - } - - if scheduler.Ticker != nil { - if err := scheduler.Stop(); err != nil { - return err - } + if scheduler.running { + return errors.New("scheduler already running") + } else { + scheduler.running = true } scheduler.Ticker = time.NewTicker(time.Hour) @@ -83,12 +74,13 @@ func (scheduler *Scheduler) Start() error { } func (scheduler *Scheduler) Stop() error { - if !scheduler.initialized { - return errors.New("scheduler not initialized") + if !scheduler.running { + return errors.New("scheduler not running") } scheduler.Ticker.Stop() scheduler.Ticker = nil + scheduler.running = false return nil } diff --git a/server/search.go b/server/search.go index 5a1daad..d332654 100644 --- a/server/search.go +++ b/server/search.go @@ -283,8 +283,10 @@ func NewSearchResults(searchOptions *SearchOptions, client *Client) (*SearchResu searchResults.Results = append(searchResults.Results, searchResult) } + rows.Close() + if err != nil { - err = formatError(err) + return nil, formatError(err) } return searchResults, err diff --git a/server/system.go b/server/system.go index 1182de5..1aeeb83 100644 --- a/server/system.go +++ b/server/system.go @@ -358,11 +358,9 @@ func (systems *Systems) Read(db *Database) error { *systems = append(*systems, system) } - if err != nil { - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -437,12 +435,9 @@ func (systems *Systems) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/tags.go b/server/tags.go index cfb7fa8..e365ed6 100644 --- a/server/tags.go +++ b/server/tags.go @@ -166,11 +166,9 @@ func (tags *Tags) Read(db *Database) error { *tags = append(*tags, tag) } - if err != nil { - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } @@ -227,12 +225,9 @@ func (tags *Tags) Write(db *Database) error { } } - if err != nil { - rows.Close() - return formatError(err) - } + rows.Close() - if err = rows.Close(); err != nil { + if err != nil { return formatError(err) } diff --git a/server/version.go b/server/version.go index e93dca2..da695c0 100644 --- a/server/version.go +++ b/server/version.go @@ -15,4 +15,4 @@ package main -const Version = "6.0.3" +const Version = "6.0.4"