diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7fdb7fd..dc01c62 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -18,6 +18,7 @@ If applicable, add screenshots to help explain your problem. **Log Files** If related to missing devices or SMART data, please run the `collector` in DEBUG mode, and attach the log file. +See [/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md](docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md) for other troubleshooting tips. ``` docker run -it --rm -p 8080:8080 \ @@ -29,7 +30,7 @@ docker run -it --rm -p 8080:8080 \ -e COLLECTOR_LOG_FILE=/tmp/collector.log \ -e SCRUTINY_LOG_FILE=/tmp/web.log \ --name scrutiny \ -analogj/scrutiny +ghcr.io/analogj/scrutiny:master-omnibus # in another terminal trigger the collector docker exec scrutiny scrutiny-collector-metrics run @@ -37,5 +38,4 @@ docker exec scrutiny scrutiny-collector-metrics run # then use docker cp to copy the log files out of the container. docker cp scrutiny:/tmp/collector.log collector.log docker cp scrutiny:/tmp/web.log web.log - ``` diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 362aacc..dc684fe 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,7 +6,21 @@ jobs: build: name: Build runs-on: ubuntu-latest - container: karalabe/xgo-1.13.x + container: techknowlogick/xgo:go-1.13.x + + # Service containers to run with `build` (Required for end-to-end testing) + services: + influxdb: + image: influxdb:2.2 + env: + DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_USERNAME: admin + DOCKER_INFLUXDB_INIT_PASSWORD: password12345 + DOCKER_INFLUXDB_INIT_ORG: scrutiny + DOCKER_INFLUXDB_INIT_BUCKET: metrics + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: my-super-secret-auth-token + ports: + - 8086:8086 env: PROJECT_PATH: /go/src/github.com/analogj/scrutiny CGO_ENABLED: 1 @@ -26,6 +40,13 @@ jobs: go mod vendor go test -race -coverprofile=coverage.txt -covermode=atomic -v -tags "static" $(go list ./... | grep -v /vendor/) + - name: Generate coverage report + uses: codecov/codecov-action@v2 + with: + files: ${{ env.PROJECT_PATH }}/coverage.txt + flags: unittests + fail_ci_if_error: true + verbose: true - name: Build Binaries run: | @@ -49,9 +70,13 @@ jobs: /build/scrutiny-collector-metrics-linux-arm-7 /build/scrutiny-web-windows-4.0-amd64.exe /build/scrutiny-collector-metrics-windows-4.0-amd64.exe +# /build/scrutiny-web-darwin-arm64 +# /build/scrutiny-collector-metrics-darwin-arm64 +# /build/scrutiny-web-darwin-amd64 +# /build/scrutiny-collector-metrics-darwin-amd64 # /build/scrutiny-web-freebsd-amd64 # /build/scrutiny-collector-metrics-freebsd-amd64 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v2 with: file: ${{ env.PROJECT_PATH }}/coverage.txt flags: unittests diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml new file mode 100644 index 0000000..4109e87 --- /dev/null +++ b/.github/workflows/docker-build.yaml @@ -0,0 +1,148 @@ +name: Docker +on: + schedule: + - cron: '36 12 * * *' + push: + branches: [ master, influxdb ] + # Publish semver tags as releases. + tags: [ 'v*.*.*' ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + collector: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + tags: | + type=ref,enable=true,event=branch,suffix=-collector + type=ref,enable=true,event=tag,suffix=-collector + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + platforms: linux/amd64,linux/arm64 + context: . + file: docker/Dockerfile.collector + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + web: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + tags: | + type=ref,enable=true,event=branch,suffix=-web + type=ref,enable=true,event=tag,suffix=-web + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + platforms: linux/amd64,linux/arm64 + context: . + file: docker/Dockerfile.web + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + omnibus: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + tags: | + type=ref,enable=true,event=branch,suffix=-omnibus + type=ref,enable=true,event=tag,suffix=-omnibus + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + platforms: linux/amd64,linux/arm64 + context: . + file: docker/Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f7f9e1c..ea275c6 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -16,7 +16,20 @@ jobs: build: name: Build runs-on: ubuntu-latest - container: karalabe/xgo-1.13.x + container: techknowlogick/xgo:go-1.13.x + # Service containers to run with `build` (Required for end-to-end testing) + services: + influxdb: + image: influxdb:2.2 + env: + DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_USERNAME: admin + DOCKER_INFLUXDB_INIT_PASSWORD: password12345 + DOCKER_INFLUXDB_INIT_ORG: scrutiny + DOCKER_INFLUXDB_INIT_BUCKET: metrics + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: my-super-secret-auth-token + ports: + - 8086:8086 env: PROJECT_PATH: /go/src/github.com/analogj/scrutiny CGO_ENABLED: 1 @@ -28,13 +41,16 @@ jobs: git --version - name: Checkout uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: Bump version id: bump_version uses: packagrio/action-bumpr-go@master with: version_bump_type: ${{ github.event.inputs.version_bump_type }} version_metadata_path: ${{ github.event.inputs.version_metadata_path }} - github_token: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} # Leave this line unchanged - name: Test run: | mkdir -p $(dirname "$PROJECT_PATH") @@ -50,154 +66,38 @@ jobs: cd $PROJECT_PATH make all - - name: Commit - uses: EndBug/add-and-commit@v4 # You can change this to use a specific version - with: - - author_name: Jason Kulatunga - author_email: jason@thesparktree.com - cwd: ${{ env.PROJECT_PATH }} - force: false - signoff: true - message: '(${{steps.bump_version.outputs.release_version}}) Automated packaging of release by Packagr' - tag: ${{steps.bump_version.outputs.release_version}} - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} # Leave this line unchanged - - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - tag_name: ${{ steps.bump_version.outputs.release_version }} - release_name: Release ${{ steps.bump_version.outputs.release_version }} - draft: false - prerelease: false - - - name: Release Asset - Web - linux-amd64 - id: upload-release-asset1 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-web-linux-amd64 - asset_name: scrutiny-web-linux-amd64 - asset_content_type: application/octet-stream - - name: Release Asset - Collector - linux-amd64 - id: upload-release-asset2 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-collector-metrics-linux-amd64 - asset_name: scrutiny-collector-metrics-linux-amd64 - asset_content_type: application/octet-stream - - - - name: Release Asset - Web - linux-arm64 - id: upload-release-asset3 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-web-linux-arm64 - asset_name: scrutiny-web-linux-arm64 - asset_content_type: application/octet-stream - - name: Release Asset - Collector - linux-arm64 - id: upload-release-asset4 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-collector-metrics-linux-arm64 - asset_name: scrutiny-collector-metrics-linux-arm64 - asset_content_type: application/octet-stream - - - name: Release Asset - Web - linux-arm-5 - id: upload-release-asset5 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-web-linux-arm-5 - asset_name: scrutiny-web-linux-arm-5 - asset_content_type: application/octet-stream - - name: Release Asset - Collector - linux-arm-5 - id: upload-release-asset6 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-collector-metrics-linux-arm-5 - asset_name: scrutiny-collector-metrics-linux-arm-5 - asset_content_type: application/octet-stream + # restore modified dir to GH workspace. + cp -arf $PROJECT_PATH/. $GITHUB_WORKSPACE/ - - name: Release Asset - Web - linux-arm-6 - id: upload-release-asset7 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-web-linux-arm-6 - asset_name: scrutiny-web-linux-arm-6 - asset_content_type: application/octet-stream - - name: Release Asset - Collector - linux-arm-6 - id: upload-release-asset8 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-collector-metrics-linux-arm-6 - asset_name: scrutiny-collector-metrics-linux-arm-6 - asset_content_type: application/octet-stream + # copy all the build artifacts to the GH workspace + cp -arf /build/. $GITHUB_WORKSPACE/ - - name: Release Asset - Web - linux-arm-7 - id: upload-release-asset9 - uses: actions/upload-release-asset@v1 + - name: Commit Changes + id: commit + uses: packagrio/action-releasr-go@master env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} + # This is necessary in order to push a commit to the repo + GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} # Leave this line unchanged with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-web-linux-arm-7 - asset_name: scrutiny-web-linux-arm-7 - asset_content_type: application/octet-stream - - name: Release Asset - Collector - linux-arm-7 - id: upload-release-asset10 - uses: actions/upload-release-asset@v1 + version_metadata_path: ${{ github.event.inputs.version_metadata_path }} + - name: Publish Release + id: publish + uses: packagrio/action-publishr-go@master env: - GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} + # This is necessary in order to push a commit to the repo + GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} # Leave this line unchanged with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: /build/scrutiny-collector-metrics-linux-arm-7 - asset_name: scrutiny-collector-metrics-linux-arm-7 - asset_content_type: application/octet-stream - -# - name: Release Asset - Web - freebsd-amd64 -# id: upload-release-asset7 -# uses: actions/upload-release-asset@v1 -# env: -# GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} -# with: -# upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps -# asset_path: ${{ env.PROJECT_PATH }}/scrutiny-web-freebsd-amd64 -# asset_name: scrutiny-web-freebsd-amd64 -# asset_content_type: application/octet-stream -# - name: Release Asset - Collector - freebsd-amd64 -# id: upload-release-asset8 -# uses: actions/upload-release-asset@v1 -# env: -# GITHUB_TOKEN: ${{ secrets.SCRUTINY_GITHUB_TOKEN }} -# with: -# upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps -# asset_path: ${{ env.PROJECT_PATH }}/scrutiny-collector-metrics-freebsd-amd64 -# asset_name: scrutiny-collector-metrics-freebsd-amd64 -# asset_content_type: application/octet-stream + version_metadata_path: ${{ github.event.inputs.version_metadata_path }} + upload_assets: + scrutiny-web-linux-amd64 + scrutiny-collector-metrics-linux-amd64 + scrutiny-web-linux-arm64 + scrutiny-collector-metrics-linux-arm64 + scrutiny-web-linux-arm-5 + scrutiny-collector-metrics-linux-arm-5 + scrutiny-web-linux-arm-6 + scrutiny-collector-metrics-linux-arm-6 + scrutiny-web-linux-arm-7 + scrutiny-collector-metrics-linux-arm-7 + scrutiny-web-windows-4.0-amd64.exe + scrutiny-collector-metrics-windows-4.0-amd64.exe diff --git a/.github/workflows/sponsors.yaml b/.github/workflows/sponsors.yaml index 8cf880d..b5c7479 100644 --- a/.github/workflows/sponsors.yaml +++ b/.github/workflows/sponsors.yaml @@ -9,6 +9,6 @@ jobs: name: is-sponsor-label runs-on: ubuntu-latest steps: - - uses: JasonEtco/is-sponsor-label-action@v1 + - uses: JasonEtco/is-sponsor-label-action@v1.2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 057d8e2..727d050 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,14 +6,14 @@ There are multiple ways to develop on the scrutiny codebase locally. The two mos ## Docker Development ``` -docker build -f docker/Dockerfile . -t analogj/scrutiny +docker build -f docker/Dockerfile . -t chcr.io/analogj/scrutiny:master-omnibus docker run -it --rm -p 8080:8080 \ -v /run/udev:/run/udev:ro \ --cap-add SYS_RAWIO \ --device=/dev/sda \ --device=/dev/sdb \ -analogj/scrutiny -/scrutiny/bin/scrutiny-collector-metrics run +ghcr.io/analogj/scrutiny:master-omnibus +/opt/scrutiny/bin/scrutiny-collector-metrics run ``` @@ -54,7 +54,8 @@ web: src: frontend: path: ./dist - + influxdb: + retention_policy: false log: file: 'web.log' #absolute or relative paths allowed, eg. web.log @@ -71,6 +72,39 @@ go run webapp/backend/cmd/scrutiny/scrutiny.go start --config ./scrutiny.yaml Now visit http://localhost:8080 +If you'd like to populate the database with some test data, you can run the following commands: + +> NOTE: you may need to update the `local_time` key within the JSON file, any timestamps older than ~3 weeks will be automatically ignored +> (since the downsampling & retention policy takes effect at 2 weeks) +> This is done automatically by the `webapp/backend/pkg/models/testdata/helper.go` script + +``` +docker run -p 8086:8086 --rm influxdb:2.2 + + +docker run --rm -p 8086:8086 \ + -e DOCKER_INFLUXDB_INIT_MODE=setup \ + -e DOCKER_INFLUXDB_INIT_USERNAME=admin \ + -e DOCKER_INFLUXDB_INIT_PASSWORD=password12345 \ + -e DOCKER_INFLUXDB_INIT_ORG=scrutiny \ + -e DOCKER_INFLUXDB_INIT_BUCKET=metrics \ + influxdb:2.2 + + +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/web/testdata/register-devices-req.json localhost:8080/api/devices/register +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-ata.json localhost:8080/api/device/0x5000cca264eb01d7/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-ata-date.json localhost:8080/api/device/0x5000cca264eb01d7/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-ata-date2.json localhost:8080/api/device/0x5000cca264eb01d7/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-fail2.json localhost:8080/api/device/0x5000cca264ec3183/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-nvme.json localhost:8080/api/device/0x5002538e40a22954/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-scsi.json localhost:8080/api/device/0x5000cca252c859cc/smart +# curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-scsi2.json localhost:8080/api/device/0x5000cca264ebc248/smart +go run webapp/backend/pkg/models/testdata/helper.go + +curl localhost:8080/api/summary + +``` + ### Collector ``` brew install smartmontools diff --git a/Makefile b/Makefile index c22f82e..360fa8f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,6 @@ BINARY=\ linux/arm-7 \ linux/arm64 \ - .PHONY: all $(BINARY) all: $(BINARY) windows/amd64 diff --git a/README.md b/README.md index b218b2c..2bebda4 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,11 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/AnalogJ/scrutiny?style=flat-square)](https://goreportcard.com/report/github.com/AnalogJ/scrutiny) [![GitHub release](http://img.shields.io/github/release/AnalogJ/scrutiny.svg?style=flat-square)](https://github.com/AnalogJ/scrutiny/releases) - WebUI for smartd S.M.A.R.T monitoring > NOTE: Scrutiny is a Work-in-Progress and still has some rough edges. +> +> WARNING: Once the [InfluxDB](https://github.com/AnalogJ/scrutiny/tree/influxdb) branch is merged, Scrutiny will use both sqlite and InfluxDB for data storage. Unfortunately, this may not be backwards compatible with the database structures in the master (sqlite only) branch. [![](docs/dashboard.png)](https://imgur.com/a/5k8qMzS) @@ -71,40 +72,48 @@ If you're using Docker, getting started is as simple as running the following co ```bash docker run -it --rm -p 8080:8080 \ --v /run/udev:/run/udev:ro \ ---cap-add SYS_RAWIO \ ---device=/dev/sda \ ---device=/dev/sdb \ ---name scrutiny \ -analogj/scrutiny + -v `pwd`/scrutiny:/opt/scrutiny/config \ + -v `pwd`/influxdb2:/opt/scrutiny/influxdb \ + -v /run/udev:/run/udev:ro \ + --cap-add SYS_RAWIO \ + --device=/dev/sda \ + --device=/dev/sdb \ + --name scrutiny \ + ghcr.io/analogj/scrutiny:master-omnibus ``` - `/run/udev` is necessary to provide the Scrutiny collector with access to your device metadata - `--cap-add SYS_RAWIO` is necessary to allow `smartctl` permission to query your device SMART data - NOTE: If you have **NVMe** drives, you must add `--cap-add SYS_ADMIN` as well. See issue [#26](https://github.com/AnalogJ/scrutiny/issues/26#issuecomment-696817130) - `--device` entries are required to ensure that your hard disk devices are accessible within the container. -- `analogj/scrutiny` is a omnibus image, containing both the webapp server (frontend & api) as well as the S.M.A.R.T metric collector. (see below) +- `ghcr.io/analogj/scrutiny:master-omnibus` is a omnibus image, containing both the webapp server (frontend & api) as well as the S.M.A.R.T metric collector. (see below) ### Hub/Spoke Deployment In addition to the Omnibus image (available under the `latest` tag) there are 2 other Docker images available: -- `analogj/scrutiny:collector` - Contains the Scrutiny data collector, `smartctl` binary and cron-like scheduler. You can run one collector on each server. -- `analogj/scrutiny:web` - Contains the Web UI, API and Database. Only one container necessary +- `ghcr.io/analogj/scrutiny:master-collector` - Contains the Scrutiny data collector, `smartctl` binary and cron-like scheduler. You can run one collector on each server. +- `ghcr.io/analogj/scrutiny:master-web` - Contains the Web UI, API and Database. Only one container necessary ```bash -docker run -it --rm -p 8080:8080 \ ---name scrutiny-web \ -analogj/scrutiny:web - -docker run -it --rm \ --v /run/udev:/run/udev:ro \ ---cap-add SYS_RAWIO \ ---device=/dev/sda \ ---device=/dev/sdb \ --e SCRUTINY_API_ENDPOINT=http://SCRUTINY_WEB_IPADDRESS:8080 \ ---name scrutiny-collector \ -analogj/scrutiny:collector +docker run --rm -p 8086:8086 \ + -v `pwd`/influxdb2:/var/lib/influxdb2 \ + --name scrutiny-influxdb \ + influxdb:2.2 + +docker run --rm -p 8080:8080 \ + -v `pwd`/scrutiny:/opt/scrutiny/config \ + --name scrutiny-web \ + ghcr.io/analogj/scrutiny:master-web + +docker run --rm \ + -v /run/udev:/run/udev:ro \ + --cap-add SYS_RAWIO \ + --device=/dev/sda \ + --device=/dev/sdb \ + -e SCRUTINY_API_ENDPOINT=http://SCRUTINY_WEB_IPADDRESS:8080 \ + --name scrutiny-collector \ + ghcr.io/analogj/scrutiny:master-collector ``` ## Manual Installation (without-Docker) @@ -125,12 +134,12 @@ drive that Scrutiny detected. The collector is configured to run once a day, but For users of the docker Hub/Spoke deployment or manual install: initially the dashboard will be empty. After the first collector run, you'll be greeted with a list of all your hard drives and their current smart status. -``` -docker exec scrutiny /scrutiny/bin/scrutiny-collector-metrics run +```bash +docker exec scrutiny /opt/scrutiny/bin/scrutiny-collector-metrics run ``` # Configuration -By default Scrutiny looks for its YAML configuration files in `/scrutiny/config` +By default Scrutiny looks for its YAML configuration files in `/opt/scrutiny/config` There are two configuration files available: @@ -139,6 +148,13 @@ There are two configuration files available: Neither file is required, however if provided, it allows you to configure how Scrutiny functions. +## Cron Schedule +Unfortunately the Cron schedule cannot be configured via the `collector.yaml` (as the collector binary needs to be trigged by a scheduler/cron). +However, if you are using the official `ghcr.io/analogj/scrutiny:master-collector` or `ghcr.io/analogj/scrutiny:master-omnibus` docker images, +you can use the `COLLECTOR_CRON_SCHEDULE` environmental variable to override the default cron schedule (daily @ midnight - `0 0 * * *`). + +`docker run -e COLLECTOR_CRON_SCHEDULE="0 0 * * *" ...` + ## Notifications Scrutiny supports sending SMART device failure notifications via the following services: @@ -164,7 +180,7 @@ Check the `notify.urls` section of [example.scrutiny.yml](example.scrutiny.yaml) You can test that your notifications are configured correctly by posting an empty payload to the notifications health check API. -``` +```bash curl -X POST http://localhost:8080/api/health/notify ``` @@ -175,14 +191,14 @@ Scrutiny provides various methods to change the log level to debug and generate You can use environmental variables to enable debug logging and/or log files for the web server: -``` +```bash DEBUG=true SCRUTINY_LOG_FILE=/tmp/web.log ``` You can configure the log level and log file in the config file: -``` +```yml log: file: '/tmp/web.log' level: DEBUG @@ -190,7 +206,7 @@ log: Or if you're not using docker, you can pass CLI arguments to the web server during startup: -``` +```bash scrutiny start --debug --log-file /tmp/web.log ``` @@ -198,14 +214,14 @@ scrutiny start --debug --log-file /tmp/web.log You can use environmental variables to enable debug logging and/or log files for the collector: -``` +```bash DEBUG=true COLLECTOR_LOG_FILE=/tmp/collector.log ``` Or if you're not using docker, you can pass CLI arguments to the collector during startup: -``` +```bash scrutiny-collector-metrics run --debug --log-file /tmp/collector.log ``` diff --git a/collector/cmd/collector-metrics/collector-metrics.go b/collector/cmd/collector-metrics/collector-metrics.go index cbf11a1..d06be83 100644 --- a/collector/cmd/collector-metrics/collector-metrics.go +++ b/collector/cmd/collector-metrics/collector-metrics.go @@ -29,8 +29,8 @@ func main() { } //we're going to load the config file manually, since we need to validate it. - err = config.ReadConfig("/scrutiny/config/collector.yaml") // Find and read the config file - if _, ok := err.(errors.ConfigFileMissingError); ok { // Handle errors reading the config file + err = config.ReadConfig("/opt/scrutiny/config/collector.yaml") // Find and read the config file + if _, ok := err.(errors.ConfigFileMissingError); ok { // Handle errors reading the config file //ignore "could not find config file" } else if err != nil { os.Exit(1) diff --git a/collector/pkg/collector/base.go b/collector/pkg/collector/base.go index ff1801f..3d4bdc9 100644 --- a/collector/pkg/collector/base.go +++ b/collector/pkg/collector/base.go @@ -40,6 +40,7 @@ func (c *BaseCollector) postJson(url string, body interface{}, target interface{ return json.NewDecoder(r.Body).Decode(target) } +// http://www.linuxguide.it/command_line/linux-manpage/do.php?file=smartctl#sect7 func (c *BaseCollector) LogSmartctlExitCode(exitCode int) { if exitCode&0x01 != 0 { c.logger.Errorln("smartctl could not parse commandline") diff --git a/collector/pkg/collector/metrics.go b/collector/pkg/collector/metrics.go index a83dd35..656aaad 100644 --- a/collector/pkg/collector/metrics.go +++ b/collector/pkg/collector/metrics.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/analogj/scrutiny/collector/pkg/common" + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/config" "github.com/analogj/scrutiny/collector/pkg/detect" "github.com/analogj/scrutiny/collector/pkg/errors" @@ -20,6 +20,7 @@ type MetricsCollector struct { config config.Interface BaseCollector apiEndpoint *url.URL + shell shell.Interface } func CreateMetricsCollector(appConfig config.Interface, logger *logrus.Entry, apiEndpoint string) (MetricsCollector, error) { @@ -34,6 +35,7 @@ func CreateMetricsCollector(appConfig config.Interface, logger *logrus.Entry, ap BaseCollector: BaseCollector{ logger: logger, }, + shell: shell.Create(), } return sc, nil @@ -107,6 +109,10 @@ func (mc *MetricsCollector) Validate() error { //func (mc *MetricsCollector) Collect(wg *sync.WaitGroup, deviceWWN string, deviceName string, deviceType string) { func (mc *MetricsCollector) Collect(deviceWWN string, deviceName string, deviceType string) { //defer wg.Done() + if len(deviceWWN) == 0 { + mc.logger.Errorf("no device WWN detected for %s. Skipping collection for this device (no data association possible).\n", deviceName) + return + } mc.logger.Infof("Collecting smartctl results for %s\n", deviceName) args := []string{"-x", "-j"} @@ -116,7 +122,7 @@ func (mc *MetricsCollector) Collect(deviceWWN string, deviceName string, deviceT } args = append(args, fmt.Sprintf("%s%s", detect.DevicePrefix(), deviceName)) - result, err := common.ExecCmd(mc.logger, "smartctl", args, "", os.Environ()) + result, err := mc.shell.Command(mc.logger, "smartctl", args, "", os.Environ()) resultBytes := []byte(result) if err != nil { if exitError, ok := err.(*exec.ExitError); ok { diff --git a/collector/pkg/common/shell/factory.go b/collector/pkg/common/shell/factory.go new file mode 100644 index 0000000..921008b --- /dev/null +++ b/collector/pkg/common/shell/factory.go @@ -0,0 +1,5 @@ +package shell + +func Create() Interface { + return new(localShell) +} diff --git a/collector/pkg/common/shell/interface.go b/collector/pkg/common/shell/interface.go new file mode 100644 index 0000000..34d88a2 --- /dev/null +++ b/collector/pkg/common/shell/interface.go @@ -0,0 +1,11 @@ +package shell + +import ( + "github.com/sirupsen/logrus" +) + +// Create mock using: +// mockgen -source=collector/pkg/common/shell/interface.go -destination=collector/pkg/common/shell/mock/mock_shell.go +type Interface interface { + Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) +} diff --git a/collector/pkg/common/exec.go b/collector/pkg/common/shell/local_shell.go similarity index 80% rename from collector/pkg/common/exec.go rename to collector/pkg/common/shell/local_shell.go index 085107a..906fd41 100644 --- a/collector/pkg/common/exec.go +++ b/collector/pkg/common/shell/local_shell.go @@ -1,4 +1,4 @@ -package common +package shell import ( "bytes" @@ -10,7 +10,9 @@ import ( "strings" ) -func ExecCmd(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) { +type localShell struct{} + +func (s *localShell) Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) { logger.Infof("Executing command: %s %s", cmdName, strings.Join(cmdArgs, " ")) cmd := exec.Command(cmdName, cmdArgs...) diff --git a/collector/pkg/common/exec_test.go b/collector/pkg/common/shell/local_shell_test.go similarity index 57% rename from collector/pkg/common/exec_test.go rename to collector/pkg/common/shell/local_shell_test.go index 846417c..19c8090 100644 --- a/collector/pkg/common/exec_test.go +++ b/collector/pkg/common/shell/local_shell_test.go @@ -1,33 +1,33 @@ -package common_test +package shell import ( - "github.com/analogj/scrutiny/collector/pkg/common" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "os/exec" "testing" ) -func TestExecCmd(t *testing.T) { +func TestLocalShellCommand(t *testing.T) { t.Parallel() //setup - + testShell := localShell{} //test - result, err := common.ExecCmd(logrus.WithField("exec", "test"), "echo", []string{"hello world"}, "", nil) + result, err := testShell.Command(logrus.WithField("exec", "test"), "echo", []string{"hello world"}, "", nil) //assert require.NoError(t, err) require.Equal(t, "hello world\n", result) } -func TestExecCmd_Date(t *testing.T) { +func TestLocalShellCommand_Date(t *testing.T) { t.Parallel() //setup + testShell := localShell{} //test - _, err := common.ExecCmd(logrus.WithField("exec", "test"), "date", []string{}, "", nil) + _, err := testShell.Command(logrus.WithField("exec", "test"), "date", []string{}, "", nil) //assert require.NoError(t, err) @@ -51,13 +51,14 @@ func TestExecCmd_Date(t *testing.T) { //} // -func TestExecCmd_InvalidCommand(t *testing.T) { +func TestLocalShellCommand_InvalidCommand(t *testing.T) { t.Parallel() //setup + testShell := localShell{} //test - _, err := common.ExecCmd(logrus.WithField("exec", "test"), "invalid_binary", []string{}, "", nil) + _, err := testShell.Command(logrus.WithField("exec", "test"), "invalid_binary", []string{}, "", nil) //assert _, castOk := err.(*exec.ExitError) diff --git a/collector/pkg/common/shell/mock/mock_shell.go b/collector/pkg/common/shell/mock/mock_shell.go new file mode 100644 index 0000000..c22adca --- /dev/null +++ b/collector/pkg/common/shell/mock/mock_shell.go @@ -0,0 +1,50 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: collector/pkg/common/shell/interface.go + +// Package mock_shell is a generated GoMock package. +package mock_shell + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + logrus "github.com/sirupsen/logrus" +) + +// MockInterface is a mock of Interface interface. +type MockInterface struct { + ctrl *gomock.Controller + recorder *MockInterfaceMockRecorder +} + +// MockInterfaceMockRecorder is the mock recorder for MockInterface. +type MockInterfaceMockRecorder struct { + mock *MockInterface +} + +// NewMockInterface creates a new mock instance. +func NewMockInterface(ctrl *gomock.Controller) *MockInterface { + mock := &MockInterface{ctrl: ctrl} + mock.recorder = &MockInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder { + return m.recorder +} + +// Command mocks base method. +func (m *MockInterface) Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Command", logger, cmdName, cmdArgs, workingDir, environ) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Command indicates an expected call of Command. +func (mr *MockInterfaceMockRecorder) Command(logger, cmdName, cmdArgs, workingDir, environ interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Command", reflect.TypeOf((*MockInterface)(nil).Command), logger, cmdName, cmdArgs, workingDir, environ) +} diff --git a/collector/pkg/config/config_test.go b/collector/pkg/config/config_test.go index 1e8fd6d..8511c14 100644 --- a/collector/pkg/config/config_test.go +++ b/collector/pkg/config/config_test.go @@ -8,6 +8,19 @@ import ( "testing" ) +func TestConfiguration_InvalidConfigPath(t *testing.T) { + t.Parallel() + + //setup + testConfig, _ := config.Create() + + //test + err := testConfig.ReadConfig("does_not_exist.yaml") + + //assert + require.Error(t, err, "should return an error") +} + func TestConfiguration_GetScanOverrides_Simple(t *testing.T) { t.Parallel() diff --git a/collector/pkg/detect/detect.go b/collector/pkg/detect/detect.go index 984bee3..1475453 100644 --- a/collector/pkg/detect/detect.go +++ b/collector/pkg/detect/detect.go @@ -3,7 +3,7 @@ package detect import ( "encoding/json" "fmt" - "github.com/analogj/scrutiny/collector/pkg/common" + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/config" "github.com/analogj/scrutiny/collector/pkg/models" "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" @@ -15,6 +15,7 @@ import ( type Detect struct { Logger *logrus.Entry Config config.Interface + Shell shell.Interface } //private/common functions @@ -27,7 +28,7 @@ type Detect struct { // models.Device returned from this function only contain the minimum data for smartctl to execute: device type and device name (device file). func (d *Detect) SmartctlScan() ([]models.Device, error) { //we use smartctl to detect all the drives available. - detectedDeviceConnJson, err := common.ExecCmd(d.Logger, "smartctl", []string{"--scan", "-j"}, "", os.Environ()) + detectedDeviceConnJson, err := d.Shell.Command(d.Logger, "smartctl", []string{"--scan", "-j"}, "", os.Environ()) if err != nil { d.Logger.Errorf("Error scanning for devices: %v", err) return nil, err @@ -58,7 +59,7 @@ func (d *Detect) SmartCtlInfo(device *models.Device) error { } args = append(args, fmt.Sprintf("%s%s", DevicePrefix(), device.DeviceName)) - availableDeviceInfoJson, err := common.ExecCmd(d.Logger, "smartctl", args, "", os.Environ()) + availableDeviceInfoJson, err := d.Shell.Command(d.Logger, "smartctl", args, "", os.Environ()) if err != nil { d.Logger.Errorf("Could not retrieve device information for %s: %v", device.DeviceName, err) return err @@ -100,6 +101,12 @@ func (d *Detect) SmartCtlInfo(device *models.Device) error { d.Logger.Info("Using WWN Fallback") d.wwnFallback(device) } + if len(device.WWN) == 0 { + // no WWN populated after WWN lookup and fallback. we need to throw an error + errMsg := fmt.Sprintf("no WWN (or fallback) populated for device: %s. Device will be registered, but no data will be published for this device. ", device.DeviceName) + d.Logger.Errorf(errMsg) + return fmt.Errorf(errMsg) + } return nil } diff --git a/collector/pkg/detect/detect_test.go b/collector/pkg/detect/detect_test.go index 6c034ec..1c00ee7 100644 --- a/collector/pkg/detect/detect_test.go +++ b/collector/pkg/detect/detect_test.go @@ -1,14 +1,103 @@ package detect_test import ( + mock_shell "github.com/analogj/scrutiny/collector/pkg/common/shell/mock" mock_config "github.com/analogj/scrutiny/collector/pkg/config/mock" "github.com/analogj/scrutiny/collector/pkg/detect" "github.com/analogj/scrutiny/collector/pkg/models" "github.com/golang/mock/gomock" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "io/ioutil" "testing" ) +func TestDetect_SmartctlScan(t *testing.T) { + //setup + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetScanOverrides().AnyTimes().Return([]models.ScanOverride{}) + + fakeShell := mock_shell.NewMockInterface(mockCtrl) + testScanResults, err := ioutil.ReadFile("testdata/smartctl_scan_simple.json") + fakeShell.EXPECT().Command(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(string(testScanResults), err) + + d := detect.Detect{ + Logger: logrus.WithFields(logrus.Fields{}), + Shell: fakeShell, + Config: fakeConfig, + } + + //test + scannedDevices, err := d.SmartctlScan() + + //assert + require.NoError(t, err) + require.Equal(t, 7, len(scannedDevices)) + require.Equal(t, "scsi", scannedDevices[0].DeviceType) +} + +func TestDetect_SmartctlScan_Megaraid(t *testing.T) { + //setup + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetScanOverrides().AnyTimes().Return([]models.ScanOverride{}) + + fakeShell := mock_shell.NewMockInterface(mockCtrl) + testScanResults, err := ioutil.ReadFile("testdata/smartctl_scan_megaraid.json") + fakeShell.EXPECT().Command(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(string(testScanResults), err) + + d := detect.Detect{ + Logger: logrus.WithFields(logrus.Fields{}), + Shell: fakeShell, + Config: fakeConfig, + } + + //test + scannedDevices, err := d.SmartctlScan() + + //assert + require.NoError(t, err) + require.Equal(t, 2, len(scannedDevices)) + require.Equal(t, []models.Device{ + models.Device{DeviceName: "bus/0", DeviceType: "megaraid,0"}, + models.Device{DeviceName: "bus/0", DeviceType: "megaraid,1"}, + }, scannedDevices) +} + +func TestDetect_SmartctlScan_Nvme(t *testing.T) { + //setup + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetScanOverrides().AnyTimes().Return([]models.ScanOverride{}) + + fakeShell := mock_shell.NewMockInterface(mockCtrl) + testScanResults, err := ioutil.ReadFile("testdata/smartctl_scan_nvme.json") + fakeShell.EXPECT().Command(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(string(testScanResults), err) + + d := detect.Detect{ + Logger: logrus.WithFields(logrus.Fields{}), + Shell: fakeShell, + Config: fakeConfig, + } + + //test + scannedDevices, err := d.SmartctlScan() + + //assert + require.NoError(t, err) + require.Equal(t, 1, len(scannedDevices)) + require.Equal(t, []models.Device{ + models.Device{DeviceName: "nvme0", DeviceType: "nvme"}, + }, scannedDevices) +} + func TestDetect_TransformDetectedDevices_Empty(t *testing.T) { //setup mockCtrl := gomock.NewController(t) diff --git a/collector/pkg/detect/devices_darwin.go b/collector/pkg/detect/devices_darwin.go index 6a70f67..928a38d 100644 --- a/collector/pkg/detect/devices_darwin.go +++ b/collector/pkg/detect/devices_darwin.go @@ -1,6 +1,7 @@ package detect import ( + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/models" "github.com/jaypipes/ghw" "strings" @@ -11,6 +12,7 @@ func DevicePrefix() string { } func (d *Detect) Start() ([]models.Device, error) { + d.Shell = shell.Create() // call the base/common functionality to get a list of devicess detectedDevices, err := d.SmartctlScan() if err != nil { diff --git a/collector/pkg/detect/devices_freebsd.go b/collector/pkg/detect/devices_freebsd.go index 93e9a00..ebe8e88 100644 --- a/collector/pkg/detect/devices_freebsd.go +++ b/collector/pkg/detect/devices_freebsd.go @@ -1,6 +1,7 @@ package detect import ( + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/models" "github.com/jaypipes/ghw" "strings" @@ -11,6 +12,7 @@ func DevicePrefix() string { } func (d *Detect) Start() ([]models.Device, error) { + d.Shell = shell.Create() // call the base/common functionality to get a list of devices detectedDevices, err := d.SmartctlScan() if err != nil { diff --git a/collector/pkg/detect/devices_linux.go b/collector/pkg/detect/devices_linux.go index 93e9a00..ebe8e88 100644 --- a/collector/pkg/detect/devices_linux.go +++ b/collector/pkg/detect/devices_linux.go @@ -1,6 +1,7 @@ package detect import ( + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/models" "github.com/jaypipes/ghw" "strings" @@ -11,6 +12,7 @@ func DevicePrefix() string { } func (d *Detect) Start() ([]models.Device, error) { + d.Shell = shell.Create() // call the base/common functionality to get a list of devices detectedDevices, err := d.SmartctlScan() if err != nil { diff --git a/collector/pkg/detect/devices_windows.go b/collector/pkg/detect/devices_windows.go index d9ddbaf..296578e 100644 --- a/collector/pkg/detect/devices_windows.go +++ b/collector/pkg/detect/devices_windows.go @@ -1,6 +1,7 @@ package detect import ( + "github.com/analogj/scrutiny/collector/pkg/common/shell" "github.com/analogj/scrutiny/collector/pkg/models" "strings" ) @@ -10,6 +11,7 @@ func DevicePrefix() string { } func (d *Detect) Start() ([]models.Device, error) { + d.Shell = shell.Create() // call the base/common functionality to get a list of devices detectedDevices, err := d.SmartctlScan() if err != nil { diff --git a/collector/pkg/detect/testdata/smartctl_scan_megaraid.json b/collector/pkg/detect/testdata/smartctl_scan_megaraid.json new file mode 100644 index 0000000..ed4f7f0 --- /dev/null +++ b/collector/pkg/detect/testdata/smartctl_scan_megaraid.json @@ -0,0 +1,35 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 1 + ], + "svn_revision": "5022", + "platform_info": "x86_64-linux-5.4.0-45-generic", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-j", + "--scan" + ], + "exit_status": 0 + }, + "devices": [ + { + "name": "/dev/bus/0", + "info_name": "/dev/bus/0 [megaraid_disk_00]", + "type": "megaraid,0", + "protocol": "SCSI" + }, + { + "name": "/dev/bus/0", + "info_name": "/dev/bus/0 [megaraid_disk_01]", + "type": "megaraid,1", + "protocol": "SCSI" + } + ] +} \ No newline at end of file diff --git a/collector/pkg/detect/testdata/smartctl_scan_nvme.json b/collector/pkg/detect/testdata/smartctl_scan_nvme.json new file mode 100644 index 0000000..edfb8f8 --- /dev/null +++ b/collector/pkg/detect/testdata/smartctl_scan_nvme.json @@ -0,0 +1,29 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-4.19.107-Unraid", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-j", + "--scan" + ], + "exit_status": 0 + }, + "devices": [ + { + "name": "/dev/nvme0", + "info_name": "/dev/nvme0", + "type": "nvme", + "protocol": "NVMe" + } + ] +} \ No newline at end of file diff --git a/collector/pkg/detect/testdata/smartctl_scan_simple.json b/collector/pkg/detect/testdata/smartctl_scan_simple.json new file mode 100644 index 0000000..83e6f2a --- /dev/null +++ b/collector/pkg/detect/testdata/smartctl_scan_simple.json @@ -0,0 +1,65 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-5.15.32-flatcar", + "build_info": "(local build)", + "argv": [ + "smartctl", + "--scan", + "-j" + ], + "exit_status": 0 + }, + "devices": [ + { + "name": "/dev/sda", + "info_name": "/dev/sda", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sdb", + "info_name": "/dev/sdb", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sdc", + "info_name": "/dev/sdc", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sdd", + "info_name": "/dev/sdd", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sde", + "info_name": "/dev/sde", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sdf", + "info_name": "/dev/sdf", + "type": "scsi", + "protocol": "SCSI" + }, + { + "name": "/dev/sdg", + "info_name": "/dev/sdg", + "type": "scsi", + "protocol": "SCSI" + } + ] +} \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index a4b1981..06d13a5 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -16,40 +16,50 @@ FROM node:lts-slim as frontendbuild #reduce logging, disable angular-cli analytics for ci environment ENV NPM_CONFIG_LOGLEVEL=warn NG_CLI_ANALYTICS=false -WORKDIR /scrutiny/src -COPY webapp/frontend /scrutiny/src +WORKDIR /opt/scrutiny/src +COPY webapp/frontend /opt/scrutiny/src RUN npm install -g @angular/cli@9.1.4 && \ mkdir -p /scrutiny/dist && \ npm install && \ - ng build --output-path=/scrutiny/dist --prod + ng build --output-path=/opt/scrutiny/dist --prod ######## FROM ubuntu:bionic as runtime +ARG TARGETARCH EXPOSE 8080 -WORKDIR /scrutiny -ENV PATH="/scrutiny/bin:${PATH}" +WORKDIR /opt/scrutiny +ENV PATH="/opt/scrutiny/bin:${PATH}" +ENV INFLUXD_CONFIG_PATH=/opt/scrutiny/influxdb -RUN apt-get update && apt-get install -y cron smartmontools=7.0-0ubuntu1~ubuntu18.04.1 ca-certificates curl && update-ca-certificates +RUN apt-get update && apt-get install -y cron smartmontools=7.0-0ubuntu1~ubuntu18.04.1 ca-certificates curl tzdata \ + && update-ca-certificates \ + && case ${TARGETARCH} in \ + "amd64") S6_ARCH=amd64 ;; \ + "arm64") S6_ARCH=aarch64 ;; \ + esac \ + && curl https://github.com/just-containers/s6-overlay/releases/download/v1.21.8.0/s6-overlay-${S6_ARCH}.tar.gz -L -s --output /tmp/s6-overlay-${S6_ARCH}.tar.gz \ + && tar xzf /tmp/s6-overlay-${S6_ARCH}.tar.gz -C / + +ADD https://dl.influxdata.com/influxdb/releases/influxdb2-2.2.0-${TARGETARCH}.deb /tmp/ +RUN dpkg -i /tmp/influxdb2-2.2.0-${TARGETARCH}.deb && rm -rf /tmp/influxdb2-2.2.0-${TARGETARCH}.deb -ADD https://github.com/just-containers/s6-overlay/releases/download/v1.21.8.0/s6-overlay-amd64.tar.gz /tmp/ -RUN tar xzf /tmp/s6-overlay-amd64.tar.gz -C / COPY /rootfs / COPY /rootfs/etc/cron.d/scrutiny /etc/cron.d/scrutiny -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny /scrutiny/bin/ -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-selftest /scrutiny/bin/ -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-metrics /scrutiny/bin/ -COPY --from=frontendbuild /scrutiny/dist /scrutiny/web -RUN chmod +x /scrutiny/bin/scrutiny && \ - chmod +x /scrutiny/bin/scrutiny-collector-selftest && \ - chmod +x /scrutiny/bin/scrutiny-collector-metrics && \ +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny /opt/scrutiny/bin/ +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-selftest /opt/scrutiny/bin/ +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-metrics /opt/scrutiny/bin/ +COPY --from=frontendbuild /opt/scrutiny/dist /opt/scrutiny/web +RUN chmod +x /opt/scrutiny/bin/scrutiny && \ + chmod +x /opt/scrutiny/bin/scrutiny-collector-selftest && \ + chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics && \ chmod 0644 /etc/cron.d/scrutiny && \ rm -f /etc/cron.daily/* && \ - mkdir -p /scrutiny/web && \ - mkdir -p /scrutiny/config && \ - chmod -R ugo+rwx /scrutiny/config + mkdir -p /opt/scrutiny/web && \ + mkdir -p /opt/scrutiny/config && \ + chmod -R ugo+rwx /opt/scrutiny/config CMD ["/init"] diff --git a/docker/Dockerfile.collector b/docker/Dockerfile.collector index 32361ba..d1cb698 100644 --- a/docker/Dockerfile.collector +++ b/docker/Dockerfile.collector @@ -12,16 +12,16 @@ RUN go mod vendor && \ ######## FROM ubuntu:bionic as runtime WORKDIR /scrutiny -ENV PATH="/scrutiny/bin:${PATH}" +ENV PATH="/opt/scrutiny/bin:${PATH}" -RUN apt-get update && apt-get install -y cron smartmontools=7.0-0ubuntu1~ubuntu18.04.1 ca-certificates && update-ca-certificates +RUN apt-get update && apt-get install -y cron smartmontools=7.0-0ubuntu1~ubuntu18.04.1 ca-certificates tzdata && update-ca-certificates COPY /docker/entrypoint-collector.sh /entrypoint-collector.sh COPY /rootfs/etc/cron.d/scrutiny /etc/cron.d/scrutiny -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-selftest /scrutiny/bin/ -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-metrics /scrutiny/bin/ -RUN chmod +x /scrutiny/bin/scrutiny-collector-selftest && \ - chmod +x /scrutiny/bin/scrutiny-collector-metrics && \ +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-selftest /opt/scrutiny/bin/ +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny-collector-metrics /opt/scrutiny/bin/ +RUN chmod +x /opt/scrutiny/bin/scrutiny-collector-selftest && \ + chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics && \ chmod +x /entrypoint-collector.sh && \ chmod 0644 /etc/cron.d/scrutiny && \ rm -f /etc/cron.daily/apt /etc/cron.daily/dpkg /etc/cron.daily/passwd diff --git a/docker/Dockerfile.web b/docker/Dockerfile.web index c9174a7..8307f01 100644 --- a/docker/Dockerfile.web +++ b/docker/Dockerfile.web @@ -14,27 +14,27 @@ FROM node:lts-slim as frontendbuild #reduce logging, disable angular-cli analytics for ci environment ENV NPM_CONFIG_LOGLEVEL=warn NG_CLI_ANALYTICS=false -WORKDIR /scrutiny/src -COPY webapp/frontend /scrutiny/src +WORKDIR /opt/scrutiny/src +COPY webapp/frontend /opt/scrutiny/src RUN npm install -g @angular/cli@9.1.4 && \ - mkdir -p /scrutiny/dist && \ + mkdir -p /opt/scrutiny/dist && \ npm install && \ - ng build --output-path=/scrutiny/dist --deploy-url="/web/" --base-href="/web/" --prod + ng build --output-path=/opt/scrutiny/dist --deploy-url="/web/" --base-href="/web/" --prod ######## FROM ubuntu:bionic as runtime EXPOSE 8080 -WORKDIR /scrutiny -ENV PATH="/scrutiny/bin:${PATH}" - -RUN apt-get update && apt-get install -y ca-certificates curl && update-ca-certificates - -COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny /scrutiny/bin/ -COPY --from=frontendbuild /scrutiny/dist /scrutiny/web -RUN chmod +x /scrutiny/bin/scrutiny && \ - mkdir -p /scrutiny/web && \ - mkdir -p /scrutiny/config && \ - chmod -R ugo+rwx /scrutiny/config -CMD ["/scrutiny/bin/scrutiny", "start"] +WORKDIR /opt/scrutiny +ENV PATH="/opt/scrutiny/bin:${PATH}" + +RUN apt-get update && apt-get install -y ca-certificates curl tzdata && update-ca-certificates + +COPY --from=backendbuild /go/src/github.com/analogj/scrutiny/scrutiny /opt/scrutiny/bin/ +COPY --from=frontendbuild /opt/scrutiny/dist /opt/scrutiny/web +RUN chmod +x /opt/scrutiny/bin/scrutiny && \ + mkdir -p /opt/scrutiny/web && \ + mkdir -p /opt/scrutiny/config && \ + chmod -R ugo+rwx /opt/scrutiny/config +CMD ["/opt/scrutiny/bin/scrutiny", "start"] diff --git a/docker/Dockerfile.xgo b/docker/Dockerfile.xgo index 1bb32bd..1487949 100644 --- a/docker/Dockerfile.xgo +++ b/docker/Dockerfile.xgo @@ -1,4 +1,4 @@ -FROM karalabe/xgo-1.13.x +FROM techknowlogick/xgo:go-1.13.x WORKDIR /go/src/github.com/analogj/scrutiny diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..0e11273 --- /dev/null +++ b/docker/README.md @@ -0,0 +1 @@ +`rootfs` is only used by Dockerfile and Dockerfile.collector diff --git a/docker/Vagrantfile b/docker/Vagrantfile index 4efaf98..52310af 100644 --- a/docker/Vagrantfile +++ b/docker/Vagrantfile @@ -1,3 +1,5 @@ +# This vagrant file is only used for local development & testing. + Vagrant.configure("2") do |config| config.vm.guest = :freebsd config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 00e3abd..7cba636 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -3,14 +3,15 @@ version: '3.5' services: scrutiny: container_name: scrutiny - image: analogj/scrutiny + image: ghcr.io/analogj/scrutiny:master-omnibus cap_add: - SYS_RAWIO ports: - "8080:8080" volumes: - /run/udev:/run/udev:ro - - ./config:/scrutiny/config + - ./config:/opt/scrutiny/config + - ./influxdb:/var/lib/influxdb2 devices: - "/dev/sda" - "/dev/sdb" diff --git a/docker/entrypoint-collector.sh b/docker/entrypoint-collector.sh index c838c19..69ed815 100755 --- a/docker/entrypoint-collector.sh +++ b/docker/entrypoint-collector.sh @@ -5,6 +5,10 @@ printenv | sed 's/^\(.*\)$/export \1/g' > /env.sh +# adding ability to customize the cron schedule. +COLLECTOR_CRON_SCHEDULE=${COLLECTOR_CRON_SCHEDULE:-"0 0 * * *"} +sed -i 's|{COLLECTOR_CRON_SCHEDULE}|'"${COLLECTOR_CRON_SCHEDULE}"'|g' /etc/cron.d/scrutiny + # now that we have the env start cron in the foreground echo "starting cron" -cron -f +su -c "cron -l 8 -f" root diff --git a/docs/DOWNSAMPLING.md b/docs/DOWNSAMPLING.md new file mode 100644 index 0000000..70eeea0 --- /dev/null +++ b/docs/DOWNSAMPLING.md @@ -0,0 +1,43 @@ +# Downsampling + +Scrutiny collects alot of data, that can cause the database to grow unbounded. + +- Smart data +- Smart test data +- Temperature data +- Disk metrics (capacity/usage) +- etc + +This data must be accurate in the short term, and is useful for doing trend analysis in the long term. +However, for trend analysis we only need aggregate data, individual data points are not as useful. + +Scrutiny will automatically downsample data on a schedule to ensure that the database size stays reasonable, while still +ensuring historical data is present for comparisons. + + +| Bucket Name | Retention Period | Downsampling Range | Downsampling Aggregation Window | Downsampling Cron | Comments | +| --- | --- | --- | --- | --- | --- | +| `metrics` | 15 days | `-2w -1w` | `1w` | main bucket, weekly on Sunday at 1:00am | +| `metrics_weekly` | 9 weeks | `-2mo -1mo` | `1mo` | monthly on first day of the month at 1:30am +| `metrics_monthly` | 25 months | `-2y -1y` | `1y` | yearly on the first day of the year at 2:00am +| `metrics_yearly` | forever | - | - | - | | + + +After 5 months, here's how may data points should exist in each bucket for one disk + +| Bucket Name | Datapoints | Comments | +| --- | --- | --- | +| `metrics` | 15 | 7 daily datapoints , up to 7 pending data, 1 buffer data point | +| `metrics_weekly` | 9 | 4 aggregated weekly data points, 4 pending datapoints, 1 buffer data point | +| `metrics_monthly` | 3 | 3 aggregated monthly data points | +| `metrics_yearly` | 0 | | + +After 5 years, here's how may data points should exist in each bucket for one disk + +| Bucket Name | Datapoints | Comments | +| --- | --- | --- | +| `metrics` | - | - | +| `metrics_weekly` | - | +| `metrics_monthly` | - | +| `metrics_yearly` | - | + diff --git a/docs/INSTALL_MANUAL.md b/docs/INSTALL_MANUAL.md index e6eb846..c6d26ec 100644 --- a/docs/INSTALL_MANUAL.md +++ b/docs/INSTALL_MANUAL.md @@ -132,6 +132,8 @@ chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 Next, we will manually trigger the collector, to populate the Scrutiny dashboard: +> NOTE: if you need to pass a config file to the scrutiny collector, you can provide it using the `--config` flag. + ``` /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 run --api-endpoint "http://localhost:8080" ``` diff --git a/docs/INSTALL_UNRAID.md b/docs/INSTALL_UNRAID.md index 7a22aaf..f8b9fe4 100644 --- a/docs/INSTALL_UNRAID.md +++ b/docs/INSTALL_UNRAID.md @@ -19,13 +19,13 @@ To install, simply click 'Install'; the configuration parameters should not need As a docker image can be created using various OS bases, the image choice is entirely the users choice. Recommendations of a specific image from a specific maintainer is beyond the scope of this guide. However, to provide some context given the number of questions posed regarding the various versions available: -- **analogj/scrutiny** +- **ghcr.io/analogj/scrutiny:master-omnibus** - `Image maintained directly by the application author` - `Debian based docker image` -- **linuxserver/scrutiny:** +- **linuxserver/scrutiny** - `Image maintained by the LinuxServer.io group` - `Alpine based docker image` -- **hotio/scrutiny:** +- **hotio/scrutiny** - `Image maintained by hotio` - `DETAILS TBD` diff --git a/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md new file mode 100644 index 0000000..50858f4 --- /dev/null +++ b/docs/TROUBLESHOOTING_DEVICE_COLLECTOR.md @@ -0,0 +1,127 @@ +# Scrutiny <-> SmartMonTools + +Scrutiny uses `smartctl --scan` to detect devices/drives. If your devices are not being detected by Scrutiny, or some +data is missing, this is probably due to a `smartctl` issue. +The following page will document commonly asked questions and troubleshooting steps for the Scrutiny S.M.A.R.T. data collector. + +## WWN vs Device name +As discussed in [`#117`](https://github.com/AnalogJ/scrutiny/issues/117), `/dev/sd*` device paths are ephemeral. + +> Device paths in Linux aren't guaranteed to be consistent across restarts. Device names consist of major numbers (letters) and minor numbers. When the Linux storage device driver detects a new device, the driver assigns major and minor numbers from the available range to the device. When a device is removed, the device numbers are freed for reuse. +> +> The problem occurs because device scanning in Linux is scheduled by the SCSI subsystem to happen asynchronously. As a result, a device path name can vary across restarts. +> +> https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-device-names-problems + +While the Docker Scrutiny collector does require devices to attached to the docker container by device name (using `--device=/dev/sd..`), internally +Scrutiny stores and references the devices by their `WWN` which is globally unique, and never changes. + +As such, passing devices to the Scrutiny collector container using `/dev/disk/by-id/`, `/dev/disk/by-label/`, `/dev/disk/by-path/` and `/dev/disk/by-uuid/` +paths are unnecessary, unless you'd like to ensure the docker run command never needs to change. + + +## Device Detection By Smartctl + +The first thing you'll want to do is run `smartctl` locally (not in Docker) and make sure the output shows all your drives as expected. +See the `Drive Types` section below for what this output should look like for `NVMe`/`ATA`/`RAID` drives. + +```bash +smartctl --scan + +/dev/sda -d scsi # /dev/sda, SCSI device +/dev/sdb -d scsi # /dev/sdb, SCSI device +/dev/sdc -d scsi # /dev/sdc, SCSI device +/dev/sdd -d scsi # /dev/sdd, SCSI device +``` + +Once you've verified that `smartctl` correctly detects your drives, make sure scrutiny is correctly detecting them as well. +> NOTE: make sure you specify all the devices you'd like scrutiny to process using `--device=` flags. + +```bash +docker run -it --rm \ + -v /run/udev:/run/udev:ro \ + --cap-add SYS_RAWIO \ + --device=/dev/sda \ + --device=/dev/sdb \ + ghcr.io/analogj/scrutiny:master-collector smartctl --scan +``` + +If the output is the same, your devices will be processed by Scrutiny. + +### Collector Config File +In some cases `--scan` does not correctly detect the device type, returning [incomplete SMART data](https://github.com/AnalogJ/scrutiny/issues/45). +Scrutiny will supports overriding the detected device type via the config file. + +### RAID Controllers (Megaraid/3ware/HBA/Adaptec/HPE/etc) +Smartctl has support for a large number of [RAID controllers](https://www.smartmontools.org/wiki/Supported_RAID-Controllers), however this +support is not automatic, and may require some additional device type hinting. You can provide this information to the Scrutiny collector +using a collector config file. See [example.collector.yaml](/example.collector.yaml) + +> NOTE: If you use docker, you **must** pass though the RAID virtual disk to the container using `--device` (see below) +> +> This device may be in `/dev/*` or `/dev/bus/*`. +> +> If you're unsure, run `smartctl --scan` on your host, and pass all listed devices to the container. + +```yaml +# /opt/scrutiny/config/collector.yaml +devices: + # Dell PERC/Broadcom Megaraid example: https://github.com/AnalogJ/scrutiny/issues/30 + - device: /dev/bus/0 + type: + - megaraid,14 + - megaraid,15 + - megaraid,18 + - megaraid,19 + - megaraid,20 + - megaraid,21 + + - device: /dev/twa0 + type: + - 3ware,0 + - 3ware,1 + - 3ware,2 + - 3ware,3 + - 3ware,4 + - 3ware,5 + + # Adapec RAID: https://github.com/AnalogJ/scrutiny/issues/189 + - device: /dev/sdb + type: + - aacraid,0,0,0 + - aacraid,0,0,1 + + # HPE Smart Array example: https://github.com/AnalogJ/scrutiny/issues/213 + - device: /dev/sda + type: + - 'cciss,0' + - 'cciss,1' +``` + +### NVMe Drives +As mentioned in the [README.md](/README.md), NVMe devices require both `--cap-add SYS_RAWIO` and `--cap-add SYS_ADMIN` +to allow smartctl permission to query your NVMe device SMART data [#26](https://github.com/AnalogJ/scrutiny/issues/26) + +When attaching NVMe devices using `--device=/dev/nvme..`, make sure to provide the device controller (`/dev/nvme0`) +instead of the block device (`/dev/nvme0n1`). See [#209](https://github.com/AnalogJ/scrutiny/issues/209). + +> The character device /dev/nvme0 is the NVME device controller, and block devices like /dev/nvme0n1 are the NVME storage namespaces: the devices you use for actual storage, which will behave essentially as disks. +> +> In enterprise-grade hardware, there might be support for several namespaces, thin provisioning within namespaces and other features. For now, you could think namespaces as sort of meta-partitions with extra features for enterprise use. + +### ATA + +### Standby/Sleeping Disks +- https://github.com/AnalogJ/scrutiny/issues/221 +- https://github.com/AnalogJ/scrutiny/issues/157 + +### Volume Mount All Devices (`/dev`) - Privileged + + +## Hub & Spoke model, with multiple Hosts. + +When deploying Scrutiny in a hub & spoke model, it can be difficult to determine exactly which node a set of devices are associated with. +Thankfully the collector has a special `--host-id` flag (or `COLLECTOR_HOST_ID` env variable) that can be used to associate devices with a friendly host name. + +See the [docs/INSTALL_HUB_SPOKE.md](/docs/INSTALL_HUB_SPOKE.md) guide for more information. + diff --git a/docs/dbdiagram.io.txt b/docs/dbdiagram.io.txt new file mode 100644 index 0000000..7d23af7 --- /dev/null +++ b/docs/dbdiagram.io.txt @@ -0,0 +1,62 @@ + +// SQLite Table(s) +Table device { + created_at timestamp + + wwn varchar [pk] + + //user provided + label varchar + host_id varchar + + // smartctl provided + device_name varchar + manufacturer varchar + model_name varchar + interface_type varchar + interface_speed varchar + serial_number varchar + firmware varchar + rotational_speed varchar + capacity varchar + form_factor varchar + smart_support varchar + device_protocol varchar + device_type varchar + +} + + +// InfluxDB Tables +Table device_temperature { + //timestamp + created_at timestamp + + //tags (indexed & queryable) + device_wwn varchar [pk] + + //fields + temp bigint + } + + +Table smart_ata_results { + //timestamp + created_at timestamp + + //tags (indexed & queryable) + device_wwn varchar [pk] + smart_status varchar + scrutiny_status varchar + + + + //fields + temp bigint + power_on_hours bigint + power_cycle_count bigint + + + } + +Ref: device.wwn < smart_ata_results.device_wwn diff --git a/example.collector.yaml b/example.collector.yaml index 8cf7abc..113aebf 100644 --- a/example.collector.yaml +++ b/example.collector.yaml @@ -1,6 +1,6 @@ # Commented Scrutiny Configuration File # -# The default location for this file is /scrutiny/config/collector.yaml. +# The default location for this file is /opt/scrutiny/config/collector.yaml. # In some cases to improve clarity default values are specified, # uncommented. Other example values are commented out. # diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index 3d20e9b..6c6df58 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -1,6 +1,6 @@ # Commented Scrutiny Configuration File # -# The default location for this file is /scrutiny/config/scrutiny.yaml. +# The default location for this file is /opt/scrutiny/config/scrutiny.yaml. # In some cases to improve clarity default values are specified, # uncommented. Other example values are commented out. # @@ -22,14 +22,20 @@ web: host: 0.0.0.0 database: # can also set absolute path here - location: /scrutiny/config/scrutiny.db + location: /opt/scrutiny/config/scrutiny.db src: frontend: - path: /scrutiny/web + path: /opt/scrutiny/web # leave empty unless behind a path prefixed proxy backend: basepath: # if behind a path prefixed proxy set to path value with leading / - + influxdb: + host: 0.0.0.0 + port: 8086 +# token: 'my-token' +# org: 'my-org' +# bucket: 'bucket' + retention_policy: true log: file: '' #absolute or relative paths allowed, eg. web.log diff --git a/go.mod b/go.mod index 013e908..ebc234b 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,12 @@ require ( github.com/containrrr/shoutrrr v0.4.4 github.com/fatih/color v1.10.0 github.com/gin-gonic/gin v1.6.3 + github.com/go-gormigrate/gormigrate/v2 v2.0.0 github.com/golang/mock v1.4.3 github.com/google/uuid v1.2.0 // indirect + github.com/influxdata/influxdb-client-go/v2 v2.2.3 github.com/jaypipes/ghw v0.6.1 + github.com/jinzhu/gorm v1.9.16 github.com/klauspost/compress v1.12.1 // indirect github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0 // indirect github.com/mattn/go-sqlite3 v1.14.4 // indirect diff --git a/go.sum b/go.sum deleted file mode 100644 index fbdbed6..0000000 --- a/go.sum +++ /dev/null @@ -1,586 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/agnivade/wasmbrowsertest v0.3.1/go.mod h1:zQt6ZTdl338xxRaMW395qccVE2eQm0SjC/SDz0mPWQI= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14 h1:wsrSjiqQtseStRIoLLxS4C5IEtXkazZVEPDHq8jW7r8= -github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14/go.mod h1:lJQVqFKMV5/oDGYR2bra2OljcF3CvolAoyDRyOA4k4E= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/chromedp/cdproto v0.0.0-20190614062957-d6d2f92b486d/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw= -github.com/chromedp/cdproto v0.0.0-20190621002710-8cbd498dd7a0/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw= -github.com/chromedp/cdproto v0.0.0-20190812224334-39ef923dcb8d/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0= -github.com/chromedp/cdproto v0.0.0-20190926234355-1b4886c6fad6/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0= -github.com/chromedp/chromedp v0.3.1-0.20190619195644-fd957a4d2901/go.mod h1:mJdvfrVn594N9tfiPecUidF6W5jPRKHymqHfzbobPsM= -github.com/chromedp/chromedp v0.4.0/go.mod h1:DC3QUn4mJ24dwjcaGQLoZrhm4X/uPHZ6spDbS2uFhm4= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/containrrr/shoutrrr v0.0.0-20200828202222-1da53231b05a h1:6ZMiughZYF6fJjFIf2X3D7AfImJeXnTMJ9qC2v75WPw= -github.com/containrrr/shoutrrr v0.0.0-20200828202222-1da53231b05a/go.mod h1:z3pUtEhu5zOpu+Q8wZWiEq+ZLL9hM0HiFNhttaI67Ks= -github.com/containrrr/shoutrrr v0.4.4 h1:vHZ4E/76pKVY+Jyn/qhBz3X540Bn8NI5ppPHK4PyILY= -github.com/containrrr/shoutrrr v0.4.4/go.mod h1:zqL2BvfC1W4FujrT4b3/ZCLxvD+uoeEpBL7rg9Dqpbg= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-interpreter/wagon v0.5.1-0.20190713202023-55a163980b6c/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= -github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= -github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190908185732-236ed259b199/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jarcoal/httpmock v1.0.4 h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA= -github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= -github.com/jaypipes/ghw v0.6.1 h1:Ewt3mdpiyhWotGyzg1ursV/6SnToGcG4215X6rR2af8= -github.com/jaypipes/ghw v0.6.1/go.mod h1:QOXppNRCLGYR1H+hu09FxZPqjNt09bqUZUnOL3Rcero= -github.com/jaypipes/pcidb v0.5.0 h1:4W5gZ+G7QxydevI8/MmmKdnIPJpURqJ2JNXTzfLxF5c= -github.com/jaypipes/pcidb v0.5.0/go.mod h1:L2RGk04sfRhp5wvHO0gfRAMoLY/F3PKv/nwJeVoho0o= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= -github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= -github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.1 h1:/+xsCsk06wE38cyiqOR/o7U2fSftcH72xD+BQXmja/g= -github.com/klauspost/compress v1.12.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0 h1:3tLzEnUizyN9YLWFTT9loC30lSBvh2y70LTDcZOTs1s= -github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0/go.mod h1:8/LTPeDLaklcUjgSQBHbhBF1ibKAFxzS5o+H7USfMSA= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA= -github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI= -github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= -github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.6 h1:11TGpSHY7Esh/i/qnq02Jo5oVrI1Gue8Slbq0ujPZFQ= -github.com/nxadm/tail v1.4.6/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54= -github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= -github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc/go.mod h1:NoCfSFWosfqMqmmD7hApkirIK9ozpHjxRnRxs1l413A= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= -github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.coder.com/go-tools v0.0.0-20190317003359-0c6a35b74a16/go.mod h1:iKV5yK9t+J5nG9O3uF6KYdPEz3dyfMyB15MN1rbQ8Qw= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190306220234-b354f8bf4d9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU= -golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ= -gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc= -gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= -gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.2 h1:bZzSEnq7NDGsrd+n3evOOedDrY5oLM5QPlCjZJUK2ro= -gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gosrc.io/xmpp v0.1.1 h1:iMtE9W3fx254+4E6rI34AOPJDqWvpfQR6EYaVMzhJ4s= -gosrc.io/xmpp v0.1.1/go.mod h1:4JgaXzw4MnEv2sGltONtK3GMhj+h9gpQ7cO8nwbFJLU= -gosrc.io/xmpp v0.5.1 h1:Rgrm5s2rt+npGggJH3HakQxQXR8ZZz3+QRzakRQqaq4= -gosrc.io/xmpp v0.5.1/go.mod h1:L3NFMqYOxyLz3JGmgFyWf7r9htE91zVGiK40oW4RwdY= -gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -mvdan.cc/sh v2.6.4+incompatible/go.mod h1:IeeQbZq+x2SUGBensq/jge5lLQbS3XT2ktyp3wrt4x8= -nhooyr.io/websocket v1.6.5/go.mod h1:F259lAzPRAH0htX2y3ehpJe09ih1aSHN7udWki1defY= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/rootfs/etc/cont-init.d/50-config b/rootfs/etc/cont-init.d/50-config new file mode 100644 index 0000000..8ff0d45 --- /dev/null +++ b/rootfs/etc/cont-init.d/50-config @@ -0,0 +1,4 @@ +#!/usr/bin/with-contenv bash + +COLLECTOR_CRON_SCHEDULE=${COLLECTOR_CRON_SCHEDULE:-"0 0 * * *"} +sed -i 's|{COLLECTOR_CRON_SCHEDULE}|'"${COLLECTOR_CRON_SCHEDULE}"'|g' /etc/cron.d/scrutiny \ No newline at end of file diff --git a/rootfs/etc/cron.d/scrutiny b/rootfs/etc/cron.d/scrutiny index f464d04..2ba9927 100644 --- a/rootfs/etc/cron.d/scrutiny +++ b/rootfs/etc/cron.d/scrutiny @@ -11,5 +11,5 @@ MAILTO="" # correctly route collector logs (STDOUT & STDERR) to Cron foreground (collectable by Docker STDOUT) # cron schedule to run daily at midnight: '0 0 * * *' # System environmental variables are stripped by cron, source our dump of the docker environmental variables before each command (/env.sh) -0 0 * * * root . /env.sh; /scrutiny/bin/scrutiny-collector-metrics run >/proc/1/fd/1 2>/proc/1/fd/2 +{COLLECTOR_CRON_SCHEDULE} root . /env.sh; /opt/scrutiny/bin/scrutiny-collector-metrics run >/proc/1/fd/1 2>/proc/1/fd/2 # An empty line is required at the end of this file for a valid cron file. diff --git a/rootfs/etc/services.d/collector-once/run b/rootfs/etc/services.d/collector-once/run index 46369a1..7bd73e8 100644 --- a/rootfs/etc/services.d/collector-once/run +++ b/rootfs/etc/services.d/collector-once/run @@ -7,8 +7,7 @@ s6-svwait -u /var/run/s6/services/scrutiny s6-svc -O /var/run/s6/services/collector-once # wait until scrutiny is "Ready" -while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://localhost:8080/api/health)" != "200" ]]; do sleep 5; done - +until $(curl --output /dev/null --silent --head --fail http://localhost:8080/api/health); do echo "scrutiny api not ready" && sleep 5; done echo "starting scrutiny collector" -/scrutiny/bin/scrutiny-collector-metrics run +/opt/scrutiny/bin/scrutiny-collector-metrics run diff --git a/rootfs/etc/services.d/influxdb/run b/rootfs/etc/services.d/influxdb/run new file mode 100644 index 0000000..99cf1e1 --- /dev/null +++ b/rootfs/etc/services.d/influxdb/run @@ -0,0 +1,17 @@ +#!/usr/bin/with-contenv bash + +mkdir -p /opt/scrutiny/influxdb/ + +if [ -f "/opt/scrutiny/influxdb/config.yaml" ]; then + echo "influxdb config file already exists. skipping." +else +cat << 'EOF' > /opt/scrutiny/influxdb/config.yaml +bolt-path: /opt/scrutiny/influxdb/influxd.bolt +engine-path: /opt/scrutiny/influxdb/engine +http-bind-address: ":8086" +reporting-disabled: true +EOF +fi + +echo "starting influxdb" +influxd run diff --git a/rootfs/etc/services.d/scrutiny/run b/rootfs/etc/services.d/scrutiny/run index 3b88505..3fac4a6 100644 --- a/rootfs/etc/services.d/scrutiny/run +++ b/rootfs/etc/services.d/scrutiny/run @@ -1,5 +1,7 @@ #!/usr/bin/with-contenv bash -echo "starting scrutiny" +echo "waiting for influxdb" +until $(curl --output /dev/null --silent --head --fail http://localhost:8086/health); do echo "influxdb not ready" && sleep 5; done +echo "starting scrutiny" scrutiny start diff --git a/rootfs/scrutiny/.gitinclude b/rootfs/scrutiny/.gitinclude deleted file mode 100644 index e69de29..0000000 diff --git a/webapp/backend/cmd/scrutiny/scrutiny.go b/webapp/backend/cmd/scrutiny/scrutiny.go index b02475e..103fd6b 100644 --- a/webapp/backend/cmd/scrutiny/scrutiny.go +++ b/webapp/backend/cmd/scrutiny/scrutiny.go @@ -27,8 +27,8 @@ func main() { } //we're going to load the config file manually, since we need to validate it. - err = config.ReadConfig("/scrutiny/config/scrutiny.yaml") // Find and read the config file - if _, ok := err.(errors.ConfigFileMissingError); ok { // Handle errors reading the config file + err = config.ReadConfig("/opt/scrutiny/config/scrutiny.yaml") // Find and read the config file + if _, ok := err.(errors.ConfigFileMissingError); ok { // Handle errors reading the config file //ignore "could not find config file" } else if err != nil { os.Exit(1) diff --git a/webapp/backend/pkg/config/config.go b/webapp/backend/pkg/config/config.go index 2116e37..4d71b4e 100644 --- a/webapp/backend/pkg/config/config.go +++ b/webapp/backend/pkg/config/config.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/viper" "log" "os" + "strings" ) // When initializing this class the following methods must be called: @@ -29,21 +30,29 @@ func (c *configuration) Init() error { //set defaults c.SetDefault("web.listen.port", "8080") c.SetDefault("web.listen.host", "0.0.0.0") - c.SetDefault("web.src.frontend.path", "/scrutiny/web") + c.SetDefault("web.src.frontend.path", "/opt/scrutiny/web") c.SetDefault("web.src.backend.basepath", "") - c.SetDefault("web.database.location", "/scrutiny/config/scrutiny.db") + c.SetDefault("web.database.location", "/opt/scrutiny/config/scrutiny.db") c.SetDefault("log.level", "INFO") c.SetDefault("log.file", "") c.SetDefault("notify.urls", []string{}) + c.SetDefault("web.influxdb.host", "0.0.0.0") + c.SetDefault("web.influxdb.port", "8086") + c.SetDefault("web.influxdb.org", "scrutiny") + c.SetDefault("web.influxdb.bucket", "metrics") + c.SetDefault("web.influxdb.init_username", "admin") + c.SetDefault("web.influxdb.init_password", "password12345") + c.SetDefault("web.influxdb.retention_policy", true) + //c.SetDefault("disks.include", []string{}) //c.SetDefault("disks.exclude", []string{}) - //c.SetDefault("notify.metric.script", "/scrutiny/config/notify-metrics.sh") - //c.SetDefault("notify.long.script", "/scrutiny/config/notify-long-test.sh") - //c.SetDefault("notify.short.script", "/scrutiny/config/notify-short-test.sh") + //c.SetDefault("notify.metric.script", "/opt/scrutiny/config/notify-metrics.sh") + //c.SetDefault("notify.long.script", "/opt/scrutiny/config/notify-long-test.sh") + //c.SetDefault("notify.short.script", "/opt/scrutiny/config/notify-short-test.sh") //c.SetDefault("collect.metric.enable", true) //c.SetDefault("collect.metric.command", "-a -o on -S on") @@ -57,11 +66,19 @@ func (c *configuration) Init() error { //c.SetConfigName("drawbridge") //c.AddConfigPath("$HOME/") + //configure env variable parsing. + c.SetEnvPrefix("SCRUTINY") + c.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_")) + c.AutomaticEnv() + //CLI options will be added via the `Set()` function return nil } func (c *configuration) ReadConfig(configFilePath string) error { + //make sure that we specify that this is the correct config path (for eventual WriteConfig() calls) + c.SetConfigFile(configFilePath) + configFilePath, err := utils.ExpandPath(configFilePath) if err != nil { return err diff --git a/webapp/backend/pkg/config/interface.go b/webapp/backend/pkg/config/interface.go index fabe8af..8f0b773 100644 --- a/webapp/backend/pkg/config/interface.go +++ b/webapp/backend/pkg/config/interface.go @@ -9,6 +9,7 @@ import ( type Interface interface { Init() error ReadConfig(configFilePath string) error + WriteConfig() error Set(key string, value interface{}) SetDefault(key string, value interface{}) diff --git a/webapp/backend/pkg/config/mock/mock_config.go b/webapp/backend/pkg/config/mock/mock_config.go index c9ee399..8e54f6f 100644 --- a/webapp/backend/pkg/config/mock/mock_config.go +++ b/webapp/backend/pkg/config/mock/mock_config.go @@ -5,185 +5,186 @@ package mock_config import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" viper "github.com/spf13/viper" - reflect "reflect" ) -// MockInterface is a mock of Interface interface +// MockInterface is a mock of Interface interface. type MockInterface struct { ctrl *gomock.Controller recorder *MockInterfaceMockRecorder } -// MockInterfaceMockRecorder is the mock recorder for MockInterface +// MockInterfaceMockRecorder is the mock recorder for MockInterface. type MockInterfaceMockRecorder struct { mock *MockInterface } -// NewMockInterface creates a new mock instance +// NewMockInterface creates a new mock instance. func NewMockInterface(ctrl *gomock.Controller) *MockInterface { mock := &MockInterface{ctrl: ctrl} mock.recorder = &MockInterfaceMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder { return m.recorder } -// Init mocks base method -func (m *MockInterface) Init() error { +// AllSettings mocks base method. +func (m *MockInterface) AllSettings() map[string]interface{} { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init") - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "AllSettings") + ret0, _ := ret[0].(map[string]interface{}) return ret0 } -// Init indicates an expected call of Init -func (mr *MockInterfaceMockRecorder) Init() *gomock.Call { +// AllSettings indicates an expected call of AllSettings. +func (mr *MockInterfaceMockRecorder) AllSettings() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockInterface)(nil).Init)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllSettings", reflect.TypeOf((*MockInterface)(nil).AllSettings)) } -// ReadConfig mocks base method -func (m *MockInterface) ReadConfig(configFilePath string) error { +// Get mocks base method. +func (m *MockInterface) Get(key string) interface{} { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadConfig", configFilePath) - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "Get", key) + ret0, _ := ret[0].(interface{}) return ret0 } -// ReadConfig indicates an expected call of ReadConfig -func (mr *MockInterfaceMockRecorder) ReadConfig(configFilePath interface{}) *gomock.Call { +// Get indicates an expected call of Get. +func (mr *MockInterfaceMockRecorder) Get(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadConfig", reflect.TypeOf((*MockInterface)(nil).ReadConfig), configFilePath) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), key) } -// Set mocks base method -func (m *MockInterface) Set(key string, value interface{}) { +// GetBool mocks base method. +func (m *MockInterface) GetBool(key string) bool { m.ctrl.T.Helper() - m.ctrl.Call(m, "Set", key, value) + ret := m.ctrl.Call(m, "GetBool", key) + ret0, _ := ret[0].(bool) + return ret0 } -// Set indicates an expected call of Set -func (mr *MockInterfaceMockRecorder) Set(key, value interface{}) *gomock.Call { +// GetBool indicates an expected call of GetBool. +func (mr *MockInterfaceMockRecorder) GetBool(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockInterface)(nil).Set), key, value) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBool", reflect.TypeOf((*MockInterface)(nil).GetBool), key) } -// SetDefault mocks base method -func (m *MockInterface) SetDefault(key string, value interface{}) { +// GetInt mocks base method. +func (m *MockInterface) GetInt(key string) int { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDefault", key, value) + ret := m.ctrl.Call(m, "GetInt", key) + ret0, _ := ret[0].(int) + return ret0 } -// SetDefault indicates an expected call of SetDefault -func (mr *MockInterfaceMockRecorder) SetDefault(key, value interface{}) *gomock.Call { +// GetInt indicates an expected call of GetInt. +func (mr *MockInterfaceMockRecorder) GetInt(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDefault", reflect.TypeOf((*MockInterface)(nil).SetDefault), key, value) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInt", reflect.TypeOf((*MockInterface)(nil).GetInt), key) } -// AllSettings mocks base method -func (m *MockInterface) AllSettings() map[string]interface{} { +// GetString mocks base method. +func (m *MockInterface) GetString(key string) string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AllSettings") - ret0, _ := ret[0].(map[string]interface{}) + ret := m.ctrl.Call(m, "GetString", key) + ret0, _ := ret[0].(string) return ret0 } -// AllSettings indicates an expected call of AllSettings -func (mr *MockInterfaceMockRecorder) AllSettings() *gomock.Call { +// GetString indicates an expected call of GetString. +func (mr *MockInterfaceMockRecorder) GetString(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllSettings", reflect.TypeOf((*MockInterface)(nil).AllSettings)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetString", reflect.TypeOf((*MockInterface)(nil).GetString), key) } -// IsSet mocks base method -func (m *MockInterface) IsSet(key string) bool { +// GetStringSlice mocks base method. +func (m *MockInterface) GetStringSlice(key string) []string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsSet", key) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "GetStringSlice", key) + ret0, _ := ret[0].([]string) return ret0 } -// IsSet indicates an expected call of IsSet -func (mr *MockInterfaceMockRecorder) IsSet(key interface{}) *gomock.Call { +// GetStringSlice indicates an expected call of GetStringSlice. +func (mr *MockInterfaceMockRecorder) GetStringSlice(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSet", reflect.TypeOf((*MockInterface)(nil).IsSet), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStringSlice", reflect.TypeOf((*MockInterface)(nil).GetStringSlice), key) } -// Get mocks base method -func (m *MockInterface) Get(key string) interface{} { +// Init mocks base method. +func (m *MockInterface) Init() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", key) - ret0, _ := ret[0].(interface{}) + ret := m.ctrl.Call(m, "Init") + ret0, _ := ret[0].(error) return ret0 } -// Get indicates an expected call of Get -func (mr *MockInterfaceMockRecorder) Get(key interface{}) *gomock.Call { +// Init indicates an expected call of Init. +func (mr *MockInterfaceMockRecorder) Init() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockInterface)(nil).Init)) } -// GetBool mocks base method -func (m *MockInterface) GetBool(key string) bool { +// IsSet mocks base method. +func (m *MockInterface) IsSet(key string) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBool", key) + ret := m.ctrl.Call(m, "IsSet", key) ret0, _ := ret[0].(bool) return ret0 } -// GetBool indicates an expected call of GetBool -func (mr *MockInterfaceMockRecorder) GetBool(key interface{}) *gomock.Call { +// IsSet indicates an expected call of IsSet. +func (mr *MockInterfaceMockRecorder) IsSet(key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBool", reflect.TypeOf((*MockInterface)(nil).GetBool), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSet", reflect.TypeOf((*MockInterface)(nil).IsSet), key) } -// GetInt mocks base method -func (m *MockInterface) GetInt(key string) int { +// ReadConfig mocks base method. +func (m *MockInterface) ReadConfig(configFilePath string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetInt", key) - ret0, _ := ret[0].(int) + ret := m.ctrl.Call(m, "ReadConfig", configFilePath) + ret0, _ := ret[0].(error) return ret0 } -// GetInt indicates an expected call of GetInt -func (mr *MockInterfaceMockRecorder) GetInt(key interface{}) *gomock.Call { +// ReadConfig indicates an expected call of ReadConfig. +func (mr *MockInterfaceMockRecorder) ReadConfig(configFilePath interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInt", reflect.TypeOf((*MockInterface)(nil).GetInt), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadConfig", reflect.TypeOf((*MockInterface)(nil).ReadConfig), configFilePath) } -// GetString mocks base method -func (m *MockInterface) GetString(key string) string { +// Set mocks base method. +func (m *MockInterface) Set(key string, value interface{}) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetString", key) - ret0, _ := ret[0].(string) - return ret0 + m.ctrl.Call(m, "Set", key, value) } -// GetString indicates an expected call of GetString -func (mr *MockInterfaceMockRecorder) GetString(key interface{}) *gomock.Call { +// Set indicates an expected call of Set. +func (mr *MockInterfaceMockRecorder) Set(key, value interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetString", reflect.TypeOf((*MockInterface)(nil).GetString), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockInterface)(nil).Set), key, value) } -// GetStringSlice mocks base method -func (m *MockInterface) GetStringSlice(key string) []string { +// SetDefault mocks base method. +func (m *MockInterface) SetDefault(key string, value interface{}) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStringSlice", key) - ret0, _ := ret[0].([]string) - return ret0 + m.ctrl.Call(m, "SetDefault", key, value) } -// GetStringSlice indicates an expected call of GetStringSlice -func (mr *MockInterfaceMockRecorder) GetStringSlice(key interface{}) *gomock.Call { +// SetDefault indicates an expected call of SetDefault. +func (mr *MockInterfaceMockRecorder) SetDefault(key, value interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStringSlice", reflect.TypeOf((*MockInterface)(nil).GetStringSlice), key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDefault", reflect.TypeOf((*MockInterface)(nil).SetDefault), key, value) } -// UnmarshalKey mocks base method +// UnmarshalKey mocks base method. func (m *MockInterface) UnmarshalKey(key string, rawVal interface{}, decoderOpts ...viper.DecoderConfigOption) error { m.ctrl.T.Helper() varargs := []interface{}{key, rawVal} @@ -195,9 +196,23 @@ func (m *MockInterface) UnmarshalKey(key string, rawVal interface{}, decoderOpts return ret0 } -// UnmarshalKey indicates an expected call of UnmarshalKey +// UnmarshalKey indicates an expected call of UnmarshalKey. func (mr *MockInterfaceMockRecorder) UnmarshalKey(key, rawVal interface{}, decoderOpts ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]interface{}{key, rawVal}, decoderOpts...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnmarshalKey", reflect.TypeOf((*MockInterface)(nil).UnmarshalKey), varargs...) } + +// WriteConfig mocks base method. +func (m *MockInterface) WriteConfig() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteConfig") + ret0, _ := ret[0].(error) + return ret0 +} + +// WriteConfig indicates an expected call of WriteConfig. +func (mr *MockInterfaceMockRecorder) WriteConfig() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteConfig", reflect.TypeOf((*MockInterface)(nil).WriteConfig)) +} diff --git a/webapp/backend/pkg/constants.go b/webapp/backend/pkg/constants.go new file mode 100644 index 0000000..abccc06 --- /dev/null +++ b/webapp/backend/pkg/constants.go @@ -0,0 +1,28 @@ +package pkg + +const DeviceProtocolAta = "ATA" +const DeviceProtocolScsi = "SCSI" +const DeviceProtocolNvme = "NVMe" + +const SmartAttributeStatusPassed = 0 +const SmartAttributeStatusFailed = 1 +const SmartAttributeStatusWarning = 2 + +const SmartWhenFailedFailingNow = "FAILING_NOW" +const SmartWhenFailedInThePast = "IN_THE_PAST" + +//const SmartStatusPassed = "passed" +//const SmartStatusFailed = "failed" + +type DeviceStatus int + +const ( + DeviceStatusPassed DeviceStatus = 0 + DeviceStatusFailedSmart DeviceStatus = iota + DeviceStatusFailedScrutiny DeviceStatus = iota +) + +func Set(b, flag DeviceStatus) DeviceStatus { return b | flag } +func Clear(b, flag DeviceStatus) DeviceStatus { return b &^ flag } +func Toggle(b, flag DeviceStatus) DeviceStatus { return b ^ flag } +func Has(b, flag DeviceStatus) bool { return b&flag != 0 } diff --git a/webapp/backend/pkg/database/interface.go b/webapp/backend/pkg/database/interface.go new file mode 100644 index 0000000..2d4eba4 --- /dev/null +++ b/webapp/backend/pkg/database/interface.go @@ -0,0 +1,30 @@ +package database + +import ( + "context" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" +) + +type DeviceRepo interface { + Close() error + + //GetSettings() + //SaveSetting() + + RegisterDevice(ctx context.Context, dev models.Device) error + GetDevices(ctx context.Context) ([]models.Device, error) + UpdateDevice(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (models.Device, error) + UpdateDeviceStatus(ctx context.Context, wwn string, status pkg.DeviceStatus) (models.Device, error) + GetDeviceDetails(ctx context.Context, wwn string) (models.Device, error) + + SaveSmartAttributes(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (measurements.Smart, error) + GetSmartAttributeHistory(ctx context.Context, wwn string, durationKey string, attributes []string) ([]measurements.Smart, error) + + SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error + + GetSummary(ctx context.Context) (map[string]*models.DeviceSummary, error) + GetSmartTemperatureHistory(ctx context.Context, durationKey string) (map[string][]measurements.SmartTemperature, error) +} diff --git a/webapp/backend/pkg/database/migrations/m20201107210306/device.go b/webapp/backend/pkg/database/migrations/m20201107210306/device.go new file mode 100644 index 0000000..11600c3 --- /dev/null +++ b/webapp/backend/pkg/database/migrations/m20201107210306/device.go @@ -0,0 +1,47 @@ +package m20201107210306 + +import ( + "time" +) + +// Deprecated: m20201107210306.Device is deprecated, only used by db migrations +type Device struct { + //GORM attributes, see: http://gorm.io/docs/conventions.html + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt *time.Time + + WWN string `json:"wwn" gorm:"primary_key"` + HostId string `json:"host_id"` + + DeviceName string `json:"device_name"` + Manufacturer string `json:"manufacturer"` + ModelName string `json:"model_name"` + InterfaceType string `json:"interface_type"` + InterfaceSpeed string `json:"interface_speed"` + SerialNumber string `json:"serial_number"` + Firmware string `json:"firmware"` + RotationSpeed int `json:"rotational_speed"` + Capacity int64 `json:"capacity"` + FormFactor string `json:"form_factor"` + SmartSupport bool `json:"smart_support"` + DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) + DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. + SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"` +} + +const DeviceProtocolAta = "ATA" +const DeviceProtocolScsi = "SCSI" +const DeviceProtocolNvme = "NVMe" + +func (dv *Device) IsAta() bool { + return dv.DeviceProtocol == DeviceProtocolAta +} + +func (dv *Device) IsScsi() bool { + return dv.DeviceProtocol == DeviceProtocolScsi +} + +func (dv *Device) IsNvme() bool { + return dv.DeviceProtocol == DeviceProtocolNvme +} diff --git a/webapp/backend/pkg/database/migrations/m20201107210306/smart.go b/webapp/backend/pkg/database/migrations/m20201107210306/smart.go new file mode 100644 index 0000000..f0e615b --- /dev/null +++ b/webapp/backend/pkg/database/migrations/m20201107210306/smart.go @@ -0,0 +1,26 @@ +package m20201107210306 + +import ( + "gorm.io/gorm" + "time" +) + +// Deprecated: m20201107210306.Smart is deprecated, only used by db migrations +type Smart struct { + gorm.Model + + DeviceWWN string `json:"device_wwn"` + Device Device `json:"-" gorm:"foreignkey:DeviceWWN"` // use DeviceWWN as foreign key + + TestDate time.Time `json:"date"` + SmartStatus string `json:"smart_status"` // SmartStatusPassed or SmartStatusFailed + + //Metrics + Temp int64 `json:"temp"` + PowerOnHours int64 `json:"power_on_hours"` + PowerCycleCount int64 `json:"power_cycle_count"` + + AtaAttributes []SmartAtaAttribute `json:"ata_attributes" gorm:"foreignkey:SmartId"` + NvmeAttributes []SmartNvmeAttribute `json:"nvme_attributes" gorm:"foreignkey:SmartId"` + ScsiAttributes []SmartScsiAttribute `json:"scsi_attributes" gorm:"foreignkey:SmartId"` +} diff --git a/webapp/backend/pkg/database/migrations/m20201107210306/smart_ata_attribute.go b/webapp/backend/pkg/database/migrations/m20201107210306/smart_ata_attribute.go new file mode 100644 index 0000000..d20bac4 --- /dev/null +++ b/webapp/backend/pkg/database/migrations/m20201107210306/smart_ata_attribute.go @@ -0,0 +1,26 @@ +package m20201107210306 + +import "gorm.io/gorm" + +// Deprecated: m20201107210306.SmartAtaAttribute is deprecated, only used by db migrations +type SmartAtaAttribute struct { + gorm.Model + + SmartId int `json:"smart_id"` + Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key + + AttributeId int `json:"attribute_id"` + Name string `json:"name"` + Value int `json:"value"` + Worst int `json:"worst"` + Threshold int `json:"thresh"` + RawValue int64 `json:"raw_value"` + RawString string `json:"raw_string"` + WhenFailed string `json:"when_failed"` + + TransformedValue int64 `json:"transformed_value"` + Status string `gorm:"-" json:"status,omitempty"` + StatusReason string `gorm:"-" json:"status_reason,omitempty"` + FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` + History []SmartAtaAttribute `gorm:"-" json:"history,omitempty"` +} diff --git a/webapp/backend/pkg/database/migrations/m20201107210306/smart_nvme_attribute.go b/webapp/backend/pkg/database/migrations/m20201107210306/smart_nvme_attribute.go new file mode 100644 index 0000000..3fe944a --- /dev/null +++ b/webapp/backend/pkg/database/migrations/m20201107210306/smart_nvme_attribute.go @@ -0,0 +1,22 @@ +package m20201107210306 + +import "gorm.io/gorm" + +// Deprecated: m20201107210306.SmartNvmeAttribute is deprecated, only used by db migrations +type SmartNvmeAttribute struct { + gorm.Model + + SmartId int `json:"smart_id"` + Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key + + AttributeId string `json:"attribute_id"` //json string from smartctl + Name string `json:"name"` + Value int `json:"value"` + Threshold int `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status string `gorm:"-" json:"status,omitempty"` + StatusReason string `gorm:"-" json:"status_reason,omitempty"` + FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` + History []SmartNvmeAttribute `gorm:"-" json:"history,omitempty"` +} diff --git a/webapp/backend/pkg/database/migrations/m20201107210306/smart_scsci_attribute.go b/webapp/backend/pkg/database/migrations/m20201107210306/smart_scsci_attribute.go new file mode 100644 index 0000000..2a5be46 --- /dev/null +++ b/webapp/backend/pkg/database/migrations/m20201107210306/smart_scsci_attribute.go @@ -0,0 +1,22 @@ +package m20201107210306 + +import "gorm.io/gorm" + +// Deprecated: m20201107210306.SmartScsiAttribute is deprecated, only used by db migrations +type SmartScsiAttribute struct { + gorm.Model + + SmartId int `json:"smart_id"` + Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key + + AttributeId string `json:"attribute_id"` //json string from smartctl + Name string `json:"name"` + Value int `json:"value"` + Threshold int `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status string `gorm:"-" json:"status,omitempty"` + StatusReason string `gorm:"-" json:"status_reason,omitempty"` + FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` + History []SmartScsiAttribute `gorm:"-" json:"history,omitempty"` +} diff --git a/webapp/backend/pkg/database/scrutiny_repository.go b/webapp/backend/pkg/database/scrutiny_repository.go new file mode 100644 index 0000000..4968eeb --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository.go @@ -0,0 +1,407 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "github.com/influxdata/influxdb-client-go/v2/api" + "github.com/influxdata/influxdb-client-go/v2/domain" + "github.com/sirupsen/logrus" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "time" +) + +const ( + // 60seconds * 60minutes * 24hours * 15 days + RETENTION_PERIOD_15_DAYS_IN_SECONDS = 1_296_000 + + // 60seconds * 60minutes * 24hours * 7 days * 9 weeks + RETENTION_PERIOD_9_WEEKS_IN_SECONDS = 5_443_200 + + // 60seconds * 60minutes * 24hours * 7 days * (52 + 52 + 4)weeks + RETENTION_PERIOD_25_MONTHS_IN_SECONDS = 65_318_400 + + DURATION_KEY_WEEK = "week" + DURATION_KEY_MONTH = "month" + DURATION_KEY_YEAR = "year" + DURATION_KEY_FOREVER = "forever" +) + +//// GormLogger is a custom logger for Gorm, making it use logrus. +//type GormLogger struct{ Logger logrus.FieldLogger } +// +//// Print handles log events from Gorm for the custom logger. +//func (gl *GormLogger) Print(v ...interface{}) { +// switch v[0] { +// case "sql": +// gl.Logger.WithFields( +// logrus.Fields{ +// "module": "gorm", +// "type": "sql", +// "rows": v[5], +// "src_ref": v[1], +// "values": v[4], +// }, +// ).Debug(v[3]) +// case "log": +// gl.Logger.WithFields(logrus.Fields{"module": "gorm", "type": "log"}).Print(v[2]) +// } +//} + +func NewScrutinyRepository(appConfig config.Interface, globalLogger logrus.FieldLogger) (DeviceRepo, error) { + backgroundContext := context.Background() + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Gorm/SQLite setup + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + globalLogger.Infof("Trying to connect to scrutiny sqlite db: %s\n", appConfig.GetString("web.database.location")) + database, err := gorm.Open(sqlite.Open(appConfig.GetString("web.database.location")), &gorm.Config{ + //TODO: figure out how to log database queries again. + //Logger: logger + DisableForeignKeyConstraintWhenMigrating: true, + }) + if err != nil { + return nil, fmt.Errorf("Failed to connect to database! - %v", err) + } + globalLogger.Infof("Successfully connected to scrutiny sqlite db: %s\n", appConfig.GetString("web.database.location")) + + //database.SetLogger() + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // InfluxDB setup + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Create a new client using an InfluxDB server base URL and an authentication token + influxdbUrl := fmt.Sprintf("http://%s:%s", appConfig.GetString("web.influxdb.host"), appConfig.GetString("web.influxdb.port")) + globalLogger.Debugf("InfluxDB url: %s", influxdbUrl) + + client := influxdb2.NewClient(influxdbUrl, appConfig.GetString("web.influxdb.token")) + + if !appConfig.IsSet("web.influxdb.token") { + globalLogger.Debugf("No influxdb token found, running first-time setup...") + + // if no token is provided, but we have a valid server, we're going to assume this is the first setup of our server. + // we will initialize with a predetermined username & password, that you should change. + + // metrics bucket will have a retention period of 8 days (since it will be down-sampled once a week) + // in seconds (60seconds * 60minutes * 24hours * 15 days) = 1_296_000 (see EnsureBucket() function) + onboardingResponse, err := client.Setup( + backgroundContext, + appConfig.GetString("web.influxdb.init_username"), + appConfig.GetString("web.influxdb.init_password"), + appConfig.GetString("web.influxdb.org"), + appConfig.GetString("web.influxdb.bucket"), + 0) + if err != nil { + return nil, err + } + + appConfig.Set("web.influxdb.token", *onboardingResponse.Auth.Token) + // we should write the config file out here. Ignore failures. + err = appConfig.WriteConfig() + if err != nil { + globalLogger.Infof("ignoring error while writing influxdb info to config: %v", err) + } + } + + // Use blocking write client for writes to desired bucket + writeAPI := client.WriteAPIBlocking(appConfig.GetString("web.influxdb.org"), appConfig.GetString("web.influxdb.bucket")) + + // Get query client + queryAPI := client.QueryAPI(appConfig.GetString("web.influxdb.org")) + + // Get task client + taskAPI := client.TasksAPI() + + if writeAPI == nil || queryAPI == nil || taskAPI == nil { + return nil, fmt.Errorf("Failed to connect to influxdb!") + } + + deviceRepo := scrutinyRepository{ + appConfig: appConfig, + logger: globalLogger, + influxClient: client, + influxWriteApi: writeAPI, + influxQueryApi: queryAPI, + influxTaskApi: taskAPI, + gormClient: database, + } + + orgInfo, err := client.OrganizationsAPI().FindOrganizationByName(backgroundContext, appConfig.GetString("web.influxdb.org")) + if err != nil { + return nil, err + } + + // Initialize Buckets (if necessary) + err = deviceRepo.EnsureBuckets(backgroundContext, orgInfo) + if err != nil { + return nil, err + } + + // Initialize Background Tasks + err = deviceRepo.EnsureTasks(backgroundContext, *orgInfo.Id) + if err != nil { + return nil, err + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // InfluxDB & SQLite migrations + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //database.AutoMigrate(&models.Device{}) + err = deviceRepo.Migrate(backgroundContext) + if err != nil { + return nil, err + } + + return &deviceRepo, nil +} + +type scrutinyRepository struct { + appConfig config.Interface + logger logrus.FieldLogger + + influxWriteApi api.WriteAPIBlocking + influxQueryApi api.QueryAPI + influxTaskApi api.TasksAPI + influxClient influxdb2.Client + + gormClient *gorm.DB +} + +func (sr *scrutinyRepository) Close() error { + sr.influxClient.Close() + return nil +} + +func (sr *scrutinyRepository) EnsureBuckets(ctx context.Context, org *domain.Organization) error { + + var mainBucketRetentionRule domain.RetentionRule + var weeklyBucketRetentionRule domain.RetentionRule + var monthlyBucketRetentionRule domain.RetentionRule + if sr.appConfig.GetBool("web.influxdb.retention_policy") { + + // in tests, we may not want to set a retention policy. If "false", we can set data with old timestamps, + // then manually run the down sampling scripts. This should be true for production environments. + mainBucketRetentionRule = domain.RetentionRule{EverySeconds: RETENTION_PERIOD_15_DAYS_IN_SECONDS} + weeklyBucketRetentionRule = domain.RetentionRule{EverySeconds: RETENTION_PERIOD_9_WEEKS_IN_SECONDS} + monthlyBucketRetentionRule = domain.RetentionRule{EverySeconds: RETENTION_PERIOD_25_MONTHS_IN_SECONDS} + } + + mainBucket := sr.appConfig.GetString("web.influxdb.bucket") + if foundMainBucket, foundErr := sr.influxClient.BucketsAPI().FindBucketByName(ctx, mainBucket); foundErr != nil { + // metrics bucket will have a retention period of 15 days (since it will be down-sampled once a week) + _, err := sr.influxClient.BucketsAPI().CreateBucketWithName(ctx, org, mainBucket, mainBucketRetentionRule) + if err != nil { + return err + } + } else if sr.appConfig.GetBool("web.influxdb.retention_policy") { + //correctly set the retention period for the main bucket (cant do it during setup/creation) + foundMainBucket.RetentionRules = domain.RetentionRules{mainBucketRetentionRule} + sr.influxClient.BucketsAPI().UpdateBucket(ctx, foundMainBucket) + } + + //create buckets (used for downsampling) + weeklyBucket := fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket")) + if _, foundErr := sr.influxClient.BucketsAPI().FindBucketByName(ctx, weeklyBucket); foundErr != nil { + // metrics_weekly bucket will have a retention period of 8+1 weeks (since it will be down-sampled once a month) + _, err := sr.influxClient.BucketsAPI().CreateBucketWithName(ctx, org, weeklyBucket, weeklyBucketRetentionRule) + if err != nil { + return err + } + } + + monthlyBucket := fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket")) + if _, foundErr := sr.influxClient.BucketsAPI().FindBucketByName(ctx, monthlyBucket); foundErr != nil { + // metrics_monthly bucket will have a retention period of 24+1 months (since it will be down-sampled once a year) + _, err := sr.influxClient.BucketsAPI().CreateBucketWithName(ctx, org, monthlyBucket, monthlyBucketRetentionRule) + if err != nil { + return err + } + } + + yearlyBucket := fmt.Sprintf("%s_yearly", sr.appConfig.GetString("web.influxdb.bucket")) + if _, foundErr := sr.influxClient.BucketsAPI().FindBucketByName(ctx, yearlyBucket); foundErr != nil { + // metrics_yearly bucket will have an infinite retention period + _, err := sr.influxClient.BucketsAPI().CreateBucketWithName(ctx, org, yearlyBucket) + if err != nil { + return err + } + } + + return nil +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DeviceSummary +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// get a map of all devices and associated SMART data +func (sr *scrutinyRepository) GetSummary(ctx context.Context) (map[string]*models.DeviceSummary, error) { + devices, err := sr.GetDevices(ctx) + if err != nil { + return nil, err + } + + summaries := map[string]*models.DeviceSummary{} + + for _, device := range devices { + summaries[device.WWN] = &models.DeviceSummary{Device: device} + } + + // Get parser flux query result + //appConfig.GetString("web.influxdb.bucket") + queryStr := fmt.Sprintf(` + import "influxdata/influxdb/schema" + bucketBaseName = "%s" + + dailyData = from(bucket: bucketBaseName) + |> range(start: -10y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["_field"] == "temp" or r["_field"] == "power_on_hours" or r["_field"] == "date") + |> last() + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + + weeklyData = from(bucket: bucketBaseName + "_weekly") + |> range(start: -10y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["_field"] == "temp" or r["_field"] == "power_on_hours" or r["_field"] == "date") + |> last() + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + + monthlyData = from(bucket: bucketBaseName + "_monthly") + |> range(start: -10y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["_field"] == "temp" or r["_field"] == "power_on_hours" or r["_field"] == "date") + |> last() + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + + yearlyData = from(bucket: bucketBaseName + "_yearly") + |> range(start: -10y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["_field"] == "temp" or r["_field"] == "power_on_hours" or r["_field"] == "date") + |> last() + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + + union(tables: [dailyData, weeklyData, monthlyData, yearlyData]) + |> sort(columns: ["_time"], desc: false) + |> group(columns: ["device_wwn"]) + |> last(column: "device_wwn") + |> yield(name: "last") + `, + sr.appConfig.GetString("web.influxdb.bucket"), + ) + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + // Use Next() to iterate over query result lines + for result.Next() { + // Observe when there is new grouping key producing new table + if result.TableChanged() { + //fmt.Printf("table: %s\n", result.TableMetadata().String()) + } + // read result + + //get summary data from Influxdb. + //result.Record().Values() + if deviceWWN, ok := result.Record().Values()["device_wwn"]; ok { + + //ensure summaries is intialized for this wwn + if _, exists := summaries[deviceWWN.(string)]; !exists { + summaries[deviceWWN.(string)] = &models.DeviceSummary{} + } + + summaries[deviceWWN.(string)].SmartResults = &models.SmartSummary{ + Temp: result.Record().Values()["temp"].(int64), + PowerOnHours: result.Record().Values()["power_on_hours"].(int64), + CollectorDate: result.Record().Values()["_time"].(time.Time), + } + } + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + + deviceTempHistory, err := sr.GetSmartTemperatureHistory(ctx, DURATION_KEY_FOREVER) + if err != nil { + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("Error: %v", err) + } + for wwn, tempHistory := range deviceTempHistory { + summaries[wwn].TempHistory = tempHistory + } + + return summaries, nil +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper Methods +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +func (sr *scrutinyRepository) lookupBucketName(durationKey string) string { + switch durationKey { + case DURATION_KEY_WEEK: + //data stored in the last week + return sr.appConfig.GetString("web.influxdb.bucket") + case DURATION_KEY_MONTH: + // data stored in the last month (after the first week) + return fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket")) + case DURATION_KEY_YEAR: + // data stored in the last year (after the first month) + return fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket")) + case DURATION_KEY_FOREVER: + //data stored before the last year + return fmt.Sprintf("%s_yearly", sr.appConfig.GetString("web.influxdb.bucket")) + } + return sr.appConfig.GetString("web.influxdb.bucket") +} + +func (sr *scrutinyRepository) lookupDuration(durationKey string) []string { + + switch durationKey { + case DURATION_KEY_WEEK: + //data stored in the last week + return []string{"-1w", "now()"} + case DURATION_KEY_MONTH: + // data stored in the last month (after the first week) + return []string{"-1mo", "-1w"} + case DURATION_KEY_YEAR: + // data stored in the last year (after the first month) + return []string{"-1y", "-1mo"} + case DURATION_KEY_FOREVER: + //data stored before the last year + return []string{"-10y", "-1y"} + } + return []string{"-1w", "now()"} +} + +func (sr *scrutinyRepository) lookupNestedDurationKeys(durationKey string) []string { + switch durationKey { + case DURATION_KEY_WEEK: + //all data is stored in a single bucket + return []string{DURATION_KEY_WEEK} + case DURATION_KEY_MONTH: + //data is stored in the week bucket and the month bucket + return []string{DURATION_KEY_WEEK, DURATION_KEY_MONTH} + case DURATION_KEY_YEAR: + // data stored in the last year (after the first month) + return []string{DURATION_KEY_WEEK, DURATION_KEY_MONTH, DURATION_KEY_YEAR} + case DURATION_KEY_FOREVER: + //data stored before the last year + return []string{DURATION_KEY_WEEK, DURATION_KEY_MONTH, DURATION_KEY_YEAR, DURATION_KEY_FOREVER} + } + return []string{DURATION_KEY_WEEK} +} diff --git a/webapp/backend/pkg/database/scrutiny_repository_device.go b/webapp/backend/pkg/database/scrutiny_repository_device.go new file mode 100644 index 0000000..27346f3 --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository_device.go @@ -0,0 +1,74 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "gorm.io/gorm/clause" +) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Device +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//insert device into DB (and update specified columns if device is already registered) +// update device fields that may change: (DeviceType, HostID) +func (sr *scrutinyRepository) RegisterDevice(ctx context.Context, dev models.Device) error { + if err := sr.gormClient.WithContext(ctx).Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "wwn"}}, + DoUpdates: clause.AssignmentColumns([]string{"host_id", "device_name", "device_type"}), + }).Create(&dev).Error; err != nil { + return err + } + return nil +} + +// get a list of all devices (only device metadata, no SMART data) +func (sr *scrutinyRepository) GetDevices(ctx context.Context) ([]models.Device, error) { + //Get a list of all the active devices. + devices := []models.Device{} + if err := sr.gormClient.WithContext(ctx).Find(&devices).Error; err != nil { + return nil, fmt.Errorf("Could not get device summary from DB: %v", err) + } + return devices, nil +} + +// update device (only metadata) from collector +func (sr *scrutinyRepository) UpdateDevice(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (models.Device, error) { + var device models.Device + if err := sr.gormClient.WithContext(ctx).Where("wwn = ?", wwn).First(&device).Error; err != nil { + return device, fmt.Errorf("Could not get device from DB: %v", err) + } + + //TODO catch GormClient err + err := device.UpdateFromCollectorSmartInfo(collectorSmartData) + if err != nil { + return device, err + } + return device, sr.gormClient.Model(&device).Updates(device).Error +} + +//Update Device Status +func (sr *scrutinyRepository) UpdateDeviceStatus(ctx context.Context, wwn string, status pkg.DeviceStatus) (models.Device, error) { + var device models.Device + if err := sr.gormClient.WithContext(ctx).Where("wwn = ?", wwn).First(&device).Error; err != nil { + return device, fmt.Errorf("Could not get device from DB: %v", err) + } + + device.DeviceStatus = pkg.Set(device.DeviceStatus, status) + return device, sr.gormClient.Model(&device).Updates(device).Error +} + +func (sr *scrutinyRepository) GetDeviceDetails(ctx context.Context, wwn string) (models.Device, error) { + var device models.Device + + fmt.Println("GetDeviceDetails from GORM") + + if err := sr.gormClient.WithContext(ctx).Where("wwn = ?", wwn).First(&device).Error; err != nil { + return models.Device{}, err + } + + return device, nil +} diff --git a/webapp/backend/pkg/database/scrutiny_repository_device_smart_attributes.go b/webapp/backend/pkg/database/scrutiny_repository_device_smart_attributes.go new file mode 100644 index 0000000..18960cb --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository_device_smart_attributes.go @@ -0,0 +1,169 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "github.com/influxdata/influxdb-client-go/v2/api" + log "github.com/sirupsen/logrus" + "strings" + "time" +) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SMART +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +func (sr *scrutinyRepository) SaveSmartAttributes(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (measurements.Smart, error) { + deviceSmartData := measurements.Smart{} + err := deviceSmartData.FromCollectorSmartInfo(wwn, collectorSmartData) + if err != nil { + sr.logger.Errorln("Could not process SMART metrics", err) + return measurements.Smart{}, err + } + + tags, fields := deviceSmartData.Flatten() + + // write point immediately + return deviceSmartData, sr.saveDatapoint(sr.influxWriteApi, "smart", tags, fields, deviceSmartData.Date, ctx) +} + +func (sr *scrutinyRepository) GetSmartAttributeHistory(ctx context.Context, wwn string, durationKey string, attributes []string) ([]measurements.Smart, error) { + // Get SMartResults from InfluxDB + + //TODO: change the filter startrange to a real number. + + // Get parser flux query result + //appConfig.GetString("web.influxdb.bucket") + queryStr := sr.aggregateSmartAttributesQuery(wwn, durationKey) + log.Infoln(queryStr) + + smartResults := []measurements.Smart{} + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + // Use Next() to iterate over query result lines + for result.Next() { + // Observe when there is new grouping key producing new table + if result.TableChanged() { + //fmt.Printf("table: %s\n", result.TableMetadata().String()) + } + + smartData, err := measurements.NewSmartFromInfluxDB(result.Record().Values()) + if err != nil { + return nil, err + } + smartResults = append(smartResults, *smartData) + + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + + return smartResults, nil + + //if err := device.SquashHistory(); err != nil { + // logger.Errorln("An error occurred while squashing device history", err) + // c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + // return + //} + // + //if err := device.ApplyMetadataRules(); err != nil { + // logger.Errorln("An error occurred while applying scrutiny thresholds & rules", err) + // c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + // return + //} + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper Methods +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +func (sr *scrutinyRepository) saveDatapoint(influxWriteApi api.WriteAPIBlocking, measurement string, tags map[string]string, fields map[string]interface{}, date time.Time, ctx context.Context) error { + //sr.logger.Debugf("Storing datapoint in measurement '%s'. tags: %d fields: %d", measurement, len(tags), len(fields)) + p := influxdb2.NewPoint(measurement, + tags, + fields, + date) + + // write point immediately + return influxWriteApi.WritePoint(ctx, p) +} + +func (sr *scrutinyRepository) aggregateSmartAttributesQuery(wwn string, durationKey string) string { + + /* + + import "influxdata/influxdb/schema" + weekData = from(bucket: "metrics") + |> range(start: -1w, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["device_wwn"] == "0x5000c5002df89099" ) + |> schema.fieldsAsCols() + + monthData = from(bucket: "metrics_weekly") + |> range(start: -1mo, stop: -1w) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["device_wwn"] == "0x5000c5002df89099" ) + |> schema.fieldsAsCols() + + yearData = from(bucket: "metrics_monthly") + |> range(start: -1y, stop: -1mo) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["device_wwn"] == "0x5000c5002df89099" ) + |> schema.fieldsAsCols() + + foreverData = from(bucket: "metrics_yearly") + |> range(start: -10y, stop: -1y) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["device_wwn"] == "0x5000c5002df89099" ) + |> schema.fieldsAsCols() + + union(tables: [weekData, monthData, yearData, foreverData]) + |> sort(columns: ["_time"], desc: false) + |> yield(name: "last") + + */ + + partialQueryStr := []string{ + `import "influxdata/influxdb/schema"`, + } + + nestedDurationKeys := sr.lookupNestedDurationKeys(durationKey) + + subQueryNames := []string{} + for _, nestedDurationKey := range nestedDurationKeys { + bucketName := sr.lookupBucketName(nestedDurationKey) + durationRange := sr.lookupDuration(nestedDurationKey) + + subQueryNames = append(subQueryNames, fmt.Sprintf(`%sData`, nestedDurationKey)) + partialQueryStr = append(partialQueryStr, []string{ + fmt.Sprintf(`%sData = from(bucket: "%s")`, nestedDurationKey, bucketName), + fmt.Sprintf(`|> range(start: %s, stop: %s)`, durationRange[0], durationRange[1]), + `|> filter(fn: (r) => r["_measurement"] == "smart" )`, + fmt.Sprintf(`|> filter(fn: (r) => r["device_wwn"] == "%s" )`, wwn), + "|> schema.fieldsAsCols()", + }...) + } + + if len(subQueryNames) == 1 { + //there's only one bucket being queried, no need to union, just aggregate the dataset and return + partialQueryStr = append(partialQueryStr, []string{ + subQueryNames[0], + `|> yield()`, + }...) + } else { + partialQueryStr = append(partialQueryStr, []string{ + fmt.Sprintf("union(tables: [%s])", strings.Join(subQueryNames, ", ")), + `|> sort(columns: ["_time"], desc: false)`, + `|> yield(name: "last")`, + }...) + } + + return strings.Join(partialQueryStr, "\n") +} diff --git a/webapp/backend/pkg/database/scrutiny_repository_migrations.go b/webapp/backend/pkg/database/scrutiny_repository_migrations.go new file mode 100644 index 0000000..f431145 --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository_migrations.go @@ -0,0 +1,451 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/database/migrations/m20201107210306" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "github.com/go-gormigrate/gormigrate/v2" + _ "github.com/jinzhu/gorm/dialects/sqlite" + "gorm.io/gorm" + "strconv" + "time" +) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SQLite migrations +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//database.AutoMigrate(&models.Device{}) + +func (sr *scrutinyRepository) Migrate(ctx context.Context) error { + + sr.logger.Infoln("Database migration starting") + + m := gormigrate.New(sr.gormClient, gormigrate.DefaultOptions, []*gormigrate.Migration{ + { + ID: "20201107210306", // v0.3.13 (pre-influxdb schema). 9fac3c6308dc6cb6cd5bbc43a68cd93e8fb20b87 + Migrate: func(tx *gorm.DB) error { + // it's a good practice to copy the struct inside the function, + + return tx.AutoMigrate( + &m20201107210306.Device{}, + &m20201107210306.Smart{}, + &m20201107210306.SmartAtaAttribute{}, + &m20201107210306.SmartNvmeAttribute{}, + &m20201107210306.SmartNvmeAttribute{}, + ) + }, + Rollback: func(tx *gorm.DB) error { + return tx.Migrator().DropTable( + &m20201107210306.Device{}, + &m20201107210306.Smart{}, + &m20201107210306.SmartAtaAttribute{}, + &m20201107210306.SmartNvmeAttribute{}, + &m20201107210306.SmartNvmeAttribute{}, + "self_tests", + ) + }, + }, + { + ID: "20220503113100", // backwards compatible - influxdb schema + Migrate: func(tx *gorm.DB) error { + // delete unnecessary table. + err := tx.Migrator().DropTable("self_tests") + if err != nil { + return err + } + + //add columns to the Device schema, so we can start adding data to the database & influxdb + err = tx.Migrator().AddColumn(&models.Device{}, "Label") //Label string `json:"label"` + if err != nil { + return err + } + err = tx.Migrator().AddColumn(&models.Device{}, "DeviceStatus") //DeviceStatus pkg.DeviceStatus `json:"device_status"` + if err != nil { + return err + } + + //TODO: migrate the data from GORM to influxdb. + //get a list of all devices: + // get a list of all smart scans in the last 2 weeks: + // get a list of associated smart attribute data: + // translate to a measurements.Smart{} object + // call CUSTOM INFLUXDB SAVE FUNCTION (taking bucket as parameter) + // get a list of all smart scans in the last 9 weeks: + // do same as above (select 1 scan per week) + // get a list of all smart scans in the last 25 months: + // do same as above (select 1 scan per month) + // get a list of all smart scans: + // do same as above (select 1 scan per year) + + preDevices := []m20201107210306.Device{} //pre-migration device information + if err = tx.Preload("SmartResults", func(db *gorm.DB) *gorm.DB { + return db.Order("smarts.created_at ASC") //OLD: .Limit(devicesCount) + }).Find(&preDevices).Error; err != nil { + sr.logger.Errorln("Could not get device summary from DB", err) + return err + } + + //calculate bucket oldest dates + today := time.Now() + dailyBucketMax := today.Add(-RETENTION_PERIOD_15_DAYS_IN_SECONDS * time.Second) //15 days + weeklyBucketMax := today.Add(-RETENTION_PERIOD_9_WEEKS_IN_SECONDS * time.Second) //9 weeks + monthlyBucketMax := today.Add(-RETENTION_PERIOD_25_MONTHS_IN_SECONDS * time.Second) //25 weeks + + for _, preDevice := range preDevices { + sr.logger.Debugf("====================================") + sr.logger.Infof("begin processing device: %s", preDevice.WWN) + + //weekly, monthly, yearly lookup storage, so we don't add more data to the buckets than necessary. + weeklyLookup := map[string]bool{} + monthlyLookup := map[string]bool{} + yearlyLookup := map[string]bool{} + for _, preSmartResult := range preDevice.SmartResults { //pre-migration smart results + + //we're looping in ASC mode, so from oldest entry to most current. + + err, postSmartResults := m20201107210306_FromPreInfluxDBSmartResultsCreatePostInfluxDBSmartResults(tx, preDevice, preSmartResult) + if err != nil { + return err + } + smartTags, smartFields := postSmartResults.Flatten() + + err, postSmartTemp := m20201107210306_FromPreInfluxDBTempCreatePostInfluxDBTemp(preDevice, preSmartResult) + if err != nil { + return err + } + tempTags, tempFields := postSmartTemp.Flatten() + tempTags["device_wwn"] = preDevice.WWN + + year, week := postSmartResults.Date.ISOWeek() + month := postSmartResults.Date.Month() + + yearStr := strconv.Itoa(year) + yearMonthStr := fmt.Sprintf("%d-%d", year, month) + yearWeekStr := fmt.Sprintf("%d-%d", year, week) + + //write data to daily bucket if in the last 15 days + if postSmartResults.Date.After(dailyBucketMax) { + sr.logger.Debugf("device (%s) smart data added to bucket: daily", preDevice.WWN) + // write point immediately + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), sr.appConfig.GetString("web.influxdb.bucket")), + "smart", + smartTags, + smartFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), sr.appConfig.GetString("web.influxdb.bucket")), + "temp", + tempTags, + tempFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + } + + //write data to the weekly bucket if in the last 9 weeks, and week has not been processed yet + if _, weekExists := weeklyLookup[yearWeekStr]; !weekExists && postSmartResults.Date.After(weeklyBucketMax) { + sr.logger.Debugf("device (%s) smart data added to bucket: weekly", preDevice.WWN) + + //this week/year pair has not been processed + weeklyLookup[yearWeekStr] = true + // write point immediately + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket"))), + "smart", + smartTags, + smartFields, + postSmartResults.Date, ctx) + + if err != nil { + return err + } + + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket"))), + "temp", + tempTags, + tempFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + } + + //write data to the monthly bucket if in the last 9 weeks, and week has not been processed yet + if _, monthExists := monthlyLookup[yearMonthStr]; !monthExists && postSmartResults.Date.After(monthlyBucketMax) { + sr.logger.Debugf("device (%s) smart data added to bucket: monthly", preDevice.WWN) + + //this month/year pair has not been processed + monthlyLookup[yearMonthStr] = true + // write point immediately + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket"))), + "smart", + smartTags, + smartFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket"))), + "temp", + tempTags, + tempFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + } + + if _, yearExists := yearlyLookup[yearStr]; !yearExists && year != today.Year() { + sr.logger.Debugf("device (%s) smart data added to bucket: yearly", preDevice.WWN) + + //this year has not been processed + yearlyLookup[yearStr] = true + // write point immediately + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_yearly", sr.appConfig.GetString("web.influxdb.bucket"))), + "smart", + smartTags, + smartFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + + err = sr.saveDatapoint( + sr.influxClient.WriteAPIBlocking(sr.appConfig.GetString("web.influxdb.org"), fmt.Sprintf("%s_yearly", sr.appConfig.GetString("web.influxdb.bucket"))), + "temp", + tempTags, + tempFields, + postSmartResults.Date, ctx) + if err != nil { + return err + } + } + } + sr.logger.Infof("finished processing device %s. weekly: %d, monthly: %d, yearly: %d", preDevice.WWN, len(weeklyLookup), len(monthlyLookup), len(yearlyLookup)) + + } + + return nil + }, + }, + { + ID: "20220503120000", // cleanup - v0.4.0 - influxdb schema + Migrate: func(tx *gorm.DB) error { + // delete unnecessary tables. + err := tx.Migrator().DropTable( + &m20201107210306.Smart{}, + &m20201107210306.SmartAtaAttribute{}, + &m20201107210306.SmartNvmeAttribute{}, + &m20201107210306.SmartScsiAttribute{}, + ) + if err != nil { + return err + } + + //migrate the device database to the final version + return tx.AutoMigrate(models.Device{}) + }, + }, + }) + + if err := m.Migrate(); err != nil { + sr.logger.Errorf("Database migration failed with error: %w", err) + return err + } + sr.logger.Infoln("Database migration completed successfully") + return nil +} + +// Deprecated +func m20201107210306_FromPreInfluxDBTempCreatePostInfluxDBTemp(preDevice m20201107210306.Device, preSmartResult m20201107210306.Smart) (error, measurements.SmartTemperature) { + //extract temperature data for every datapoint + postSmartTemp := measurements.SmartTemperature{ + Date: preSmartResult.TestDate, + Temp: preSmartResult.Temp, + } + + return nil, postSmartTemp +} + +// Deprecated +func m20201107210306_FromPreInfluxDBSmartResultsCreatePostInfluxDBSmartResults(database *gorm.DB, preDevice m20201107210306.Device, preSmartResult m20201107210306.Smart) (error, measurements.Smart) { + //create a measurements.Smart object (which we will then push to the InfluxDB) + postDeviceSmartData := measurements.Smart{ + Date: preSmartResult.TestDate, + DeviceWWN: preDevice.WWN, + DeviceProtocol: preDevice.DeviceProtocol, + Temp: preSmartResult.Temp, + PowerOnHours: preSmartResult.PowerOnHours, + PowerCycleCount: preSmartResult.PowerCycleCount, + + // this needs to be populated using measurements.Smart.ProcessAtaSmartInfo, ProcessScsiSmartInfo or ProcessNvmeSmartInfo + // because those functions will take into account thresholds (which we didn't consider correctly previously) + Attributes: map[string]measurements.SmartAttribute{}, + } + + result := database.Preload("AtaAttributes").Preload("NvmeAttributes").Preload("ScsiAttributes").Find(&preSmartResult) + if result.Error != nil { + return result.Error, postDeviceSmartData + } + + if preDevice.IsAta() { + preAtaSmartAttributesTable := []collector.AtaSmartAttributesTableItem{} + for _, preAtaAttribute := range preSmartResult.AtaAttributes { + preAtaSmartAttributesTable = append(preAtaSmartAttributesTable, collector.AtaSmartAttributesTableItem{ + ID: preAtaAttribute.AttributeId, + Name: preAtaAttribute.Name, + Value: int64(preAtaAttribute.Value), + Worst: int64(preAtaAttribute.Worst), + Thresh: int64(preAtaAttribute.Threshold), + WhenFailed: preAtaAttribute.WhenFailed, + Flags: struct { + Value int `json:"value"` + String string `json:"string"` + Prefailure bool `json:"prefailure"` + UpdatedOnline bool `json:"updated_online"` + Performance bool `json:"performance"` + ErrorRate bool `json:"error_rate"` + EventCount bool `json:"event_count"` + AutoKeep bool `json:"auto_keep"` + }{ + Value: 0, + String: "", + Prefailure: false, + UpdatedOnline: false, + Performance: false, + ErrorRate: false, + EventCount: false, + AutoKeep: false, + }, + Raw: struct { + Value int64 `json:"value"` + String string `json:"string"` + }{ + Value: preAtaAttribute.RawValue, + String: preAtaAttribute.RawString, + }, + }) + } + + postDeviceSmartData.ProcessAtaSmartInfo(preAtaSmartAttributesTable) + + } else if preDevice.IsNvme() { + //info collector.SmartInfo + postNvmeSmartHealthInformation := collector.NvmeSmartHealthInformationLog{} + + for _, preNvmeAttribute := range preSmartResult.NvmeAttributes { + switch preNvmeAttribute.AttributeId { + case "critical_warning": + postNvmeSmartHealthInformation.CriticalWarning = int64(preNvmeAttribute.Value) + case "temperature": + postNvmeSmartHealthInformation.Temperature = int64(preNvmeAttribute.Value) + case "available_spare": + postNvmeSmartHealthInformation.AvailableSpare = int64(preNvmeAttribute.Value) + case "available_spare_threshold": + postNvmeSmartHealthInformation.AvailableSpareThreshold = int64(preNvmeAttribute.Value) + case "percentage_used": + postNvmeSmartHealthInformation.PercentageUsed = int64(preNvmeAttribute.Value) + case "data_units_read": + postNvmeSmartHealthInformation.DataUnitsWritten = int64(preNvmeAttribute.Value) + case "data_units_written": + postNvmeSmartHealthInformation.DataUnitsWritten = int64(preNvmeAttribute.Value) + case "host_reads": + postNvmeSmartHealthInformation.HostReads = int64(preNvmeAttribute.Value) + case "host_writes": + postNvmeSmartHealthInformation.HostWrites = int64(preNvmeAttribute.Value) + case "controller_busy_time": + postNvmeSmartHealthInformation.ControllerBusyTime = int64(preNvmeAttribute.Value) + case "power_cycles": + postNvmeSmartHealthInformation.PowerCycles = int64(preNvmeAttribute.Value) + case "power_on_hours": + postNvmeSmartHealthInformation.PowerOnHours = int64(preNvmeAttribute.Value) + case "unsafe_shutdowns": + postNvmeSmartHealthInformation.UnsafeShutdowns = int64(preNvmeAttribute.Value) + case "media_errors": + postNvmeSmartHealthInformation.MediaErrors = int64(preNvmeAttribute.Value) + case "num_err_log_entries": + postNvmeSmartHealthInformation.NumErrLogEntries = int64(preNvmeAttribute.Value) + case "warning_temp_time": + postNvmeSmartHealthInformation.WarningTempTime = int64(preNvmeAttribute.Value) + case "critical_comp_time": + postNvmeSmartHealthInformation.CriticalCompTime = int64(preNvmeAttribute.Value) + } + } + + postDeviceSmartData.ProcessNvmeSmartInfo(postNvmeSmartHealthInformation) + + } else if preDevice.IsScsi() { + //info collector.SmartInfo + var postScsiGrownDefectList int64 + postScsiErrorCounterLog := collector.ScsiErrorCounterLog{ + Read: struct { + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` + GigabytesProcessed string `json:"gigabytes_processed"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` + }{}, + Write: struct { + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` + GigabytesProcessed string `json:"gigabytes_processed"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` + }{}, + } + + for _, preScsiAttribute := range preSmartResult.ScsiAttributes { + switch preScsiAttribute.AttributeId { + case "scsi_grown_defect_list": + postScsiGrownDefectList = int64(preScsiAttribute.Value) + case "read.errors_corrected_by_eccfast": + postScsiErrorCounterLog.Read.ErrorsCorrectedByEccfast = int64(preScsiAttribute.Value) + case "read.errors_corrected_by_eccdelayed": + postScsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed = int64(preScsiAttribute.Value) + case "read.errors_corrected_by_rereads_rewrites": + postScsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites = int64(preScsiAttribute.Value) + case "read.total_errors_corrected": + postScsiErrorCounterLog.Read.TotalErrorsCorrected = int64(preScsiAttribute.Value) + case "read.correction_algorithm_invocations": + postScsiErrorCounterLog.Read.CorrectionAlgorithmInvocations = int64(preScsiAttribute.Value) + case "read.total_uncorrected_errors": + postScsiErrorCounterLog.Read.TotalUncorrectedErrors = int64(preScsiAttribute.Value) + case "write.errors_corrected_by_eccfast": + postScsiErrorCounterLog.Write.ErrorsCorrectedByEccfast = int64(preScsiAttribute.Value) + case "write.errors_corrected_by_eccdelayed": + postScsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed = int64(preScsiAttribute.Value) + case "write.errors_corrected_by_rereads_rewrites": + postScsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites = int64(preScsiAttribute.Value) + case "write.total_errors_corrected": + postScsiErrorCounterLog.Write.TotalErrorsCorrected = int64(preScsiAttribute.Value) + case "write.correction_algorithm_invocations": + postScsiErrorCounterLog.Write.CorrectionAlgorithmInvocations = int64(preScsiAttribute.Value) + case "write.total_uncorrected_errors": + postScsiErrorCounterLog.Write.TotalUncorrectedErrors = int64(preScsiAttribute.Value) + } + } + postDeviceSmartData.ProcessScsiSmartInfo(postScsiGrownDefectList, postScsiErrorCounterLog) + } else { + return fmt.Errorf("Unknown device protocol: %s", preDevice.DeviceProtocol), postDeviceSmartData + } + + return nil, postDeviceSmartData +} diff --git a/webapp/backend/pkg/database/scrutiny_repository_tasks.go b/webapp/backend/pkg/database/scrutiny_repository_tasks.go new file mode 100644 index 0000000..b7f487a --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository_tasks.go @@ -0,0 +1,122 @@ +package database + +import ( + "context" + "fmt" + "github.com/influxdata/influxdb-client-go/v2/api" +) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Tasks +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +func (sr *scrutinyRepository) EnsureTasks(ctx context.Context, orgID string) error { + weeklyTaskName := "tsk-weekly-aggr" + if found, findErr := sr.influxTaskApi.FindTasks(ctx, &api.TaskFilter{Name: weeklyTaskName}); findErr == nil && len(found) == 0 { + //weekly on Sunday at 1:00am + _, err := sr.influxTaskApi.CreateTaskWithCron(ctx, weeklyTaskName, sr.DownsampleScript("weekly"), "0 1 * * 0", orgID) + if err != nil { + return err + } + } + + monthlyTaskName := "tsk-monthly-aggr" + if found, findErr := sr.influxTaskApi.FindTasks(ctx, &api.TaskFilter{Name: monthlyTaskName}); findErr == nil && len(found) == 0 { + //monthly on first day of the month at 1:30am + _, err := sr.influxTaskApi.CreateTaskWithCron(ctx, monthlyTaskName, sr.DownsampleScript("monthly"), "30 1 1 * *", orgID) + if err != nil { + return err + } + } + + yearlyTaskName := "tsk-yearly-aggr" + if found, findErr := sr.influxTaskApi.FindTasks(ctx, &api.TaskFilter{Name: yearlyTaskName}); findErr == nil && len(found) == 0 { + //yearly on the first day of the year at 2:00am + _, err := sr.influxTaskApi.CreateTaskWithCron(ctx, yearlyTaskName, sr.DownsampleScript("yearly"), "0 2 1 1 *", orgID) + if err != nil { + return err + } + } + return nil +} + +func (sr *scrutinyRepository) DownsampleScript(aggregationType string) string { + var sourceBucket string // the source of the data + var destBucket string // the destination for the aggregated data + var rangeStart string + var rangeEnd string + var aggWindow string + switch aggregationType { + case "weekly": + sourceBucket = sr.appConfig.GetString("web.influxdb.bucket") + destBucket = fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket")) + rangeStart = "-2w" + rangeEnd = "-1w" + aggWindow = "1w" + case "monthly": + sourceBucket = fmt.Sprintf("%s_weekly", sr.appConfig.GetString("web.influxdb.bucket")) + destBucket = fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket")) + rangeStart = "-2mo" + rangeEnd = "-1mo" + aggWindow = "1mo" + case "yearly": + sourceBucket = fmt.Sprintf("%s_monthly", sr.appConfig.GetString("web.influxdb.bucket")) + destBucket = fmt.Sprintf("%s_yearly", sr.appConfig.GetString("web.influxdb.bucket")) + rangeStart = "-2y" + rangeEnd = "-1y" + aggWindow = "1y" + } + + // TODO: using "last" function for aggregation. This should eventually be replaced with a more accurate represenation + /* + import "types" + smart_data = from(bucket: sourceBucket) + |> range(start: rangeStart, stop: rangeEnd) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> group(columns: ["device_wwn", "_field"]) + + non_numeric_smart_data = smart_data + |> filter(fn: (r) => types.isType(v: r._value, type: "string") or types.isType(v: r._value, type: "bool")) + |> aggregateWindow(every: aggWindow, fn: last, createEmpty: false) + + numeric_smart_data = smart_data + |> filter(fn: (r) => types.isType(v: r._value, type: "int") or types.isType(v: r._value, type: "float")) + |> aggregateWindow(every: aggWindow, fn: mean, createEmpty: false) + + union(tables: [non_numeric_smart_data, numeric_smart_data]) + |> to(bucket: destBucket, org: destOrg) + + */ + + return fmt.Sprintf(` + sourceBucket = "%s" + rangeStart = %s + rangeEnd = %s + aggWindow = %s + destBucket = "%s" + destOrg = "%s" + + from(bucket: sourceBucket) + |> range(start: rangeStart, stop: rangeEnd) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> group(columns: ["device_wwn", "_field"]) + |> aggregateWindow(every: aggWindow, fn: last, createEmpty: false) + |> to(bucket: destBucket, org: destOrg) + + temp_data = from(bucket: sourceBucket) + |> range(start: rangeStart, stop: rangeEnd) + |> filter(fn: (r) => r["_measurement"] == "temp") + |> group(columns: ["device_wwn"]) + |> toInt() + + temp_data + |> aggregateWindow(fn: mean, every: aggWindow) + |> to(bucket: destBucket, org: destOrg) + `, + sourceBucket, + rangeStart, + rangeEnd, + aggWindow, + destBucket, + sr.appConfig.GetString("web.influxdb.org"), + ) +} diff --git a/webapp/backend/pkg/database/scrutiny_repository_temperature.go b/webapp/backend/pkg/database/scrutiny_repository_temperature.go new file mode 100644 index 0000000..fb3be6a --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository_temperature.go @@ -0,0 +1,167 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "strings" + "time" +) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Temperature Data +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +func (sr *scrutinyRepository) SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error { + if len(collectorSmartData.AtaSctTemperatureHistory.Table) > 0 { + + for ndx, temp := range collectorSmartData.AtaSctTemperatureHistory.Table { + + minutesOffset := collectorSmartData.AtaSctTemperatureHistory.LoggingIntervalMinutes * int64(ndx) * 60 + smartTemp := measurements.SmartTemperature{ + Date: time.Unix(collectorSmartData.LocalTime.TimeT-minutesOffset, 0), + Temp: temp, + } + + tags, fields := smartTemp.Flatten() + tags["device_wwn"] = wwn + p := influxdb2.NewPoint("temp", + tags, + fields, + smartTemp.Date) + err := sr.influxWriteApi.WritePoint(ctx, p) + if err != nil { + return err + } + } + // also add the current temperature. + } else { + + smartTemp := measurements.SmartTemperature{ + Date: time.Unix(collectorSmartData.LocalTime.TimeT, 0), + Temp: collectorSmartData.Temperature.Current, + } + + tags, fields := smartTemp.Flatten() + tags["device_wwn"] = wwn + p := influxdb2.NewPoint("temp", + tags, + fields, + smartTemp.Date) + return sr.influxWriteApi.WritePoint(ctx, p) + } + return nil +} + +func (sr *scrutinyRepository) GetSmartTemperatureHistory(ctx context.Context, durationKey string) (map[string][]measurements.SmartTemperature, error) { + //we can get temp history for "week", "month", DURATION_KEY_YEAR, "forever" + + deviceTempHistory := map[string][]measurements.SmartTemperature{} + + //TODO: change the query range to a variable. + queryStr := sr.aggregateTempQuery(durationKey) + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + // Use Next() to iterate over query result lines + for result.Next() { + + if deviceWWN, ok := result.Record().Values()["device_wwn"]; ok { + + //check if deviceWWN has been seen and initialized already + if _, ok := deviceTempHistory[deviceWWN.(string)]; !ok { + deviceTempHistory[deviceWWN.(string)] = []measurements.SmartTemperature{} + } + + currentTempHistory := deviceTempHistory[deviceWWN.(string)] + smartTemp := measurements.SmartTemperature{} + + for key, val := range result.Record().Values() { + smartTemp.Inflate(key, val) + } + smartTemp.Date = result.Record().Values()["_time"].(time.Time) + currentTempHistory = append(currentTempHistory, smartTemp) + deviceTempHistory[deviceWWN.(string)] = currentTempHistory + } + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + return deviceTempHistory, nil + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper Methods +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +func (sr *scrutinyRepository) aggregateTempQuery(durationKey string) string { + + /* + import "influxdata/influxdb/schema" + weekData = from(bucket: "metrics") + |> range(start: -1w, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "temp" ) + |> aggregateWindow(every: 1h, fn: mean, createEmpty: false) + |> group(columns: ["device_wwn"]) + |> toInt() + + monthData = from(bucket: "metrics_weekly") + |> range(start: -1mo, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "temp" ) + |> aggregateWindow(every: 1h, fn: mean, createEmpty: false) + |> group(columns: ["device_wwn"]) + |> toInt() + + union(tables: [weekData, monthData]) + |> group(columns: ["device_wwn"]) + |> sort(columns: ["_time"], desc: false) + |> schema.fieldsAsCols() + + */ + + partialQueryStr := []string{ + `import "influxdata/influxdb/schema"`, + } + + nestedDurationKeys := sr.lookupNestedDurationKeys(durationKey) + + subQueryNames := []string{} + for _, nestedDurationKey := range nestedDurationKeys { + bucketName := sr.lookupBucketName(nestedDurationKey) + durationRange := sr.lookupDuration(nestedDurationKey) + + subQueryNames = append(subQueryNames, fmt.Sprintf(`%sData`, nestedDurationKey)) + partialQueryStr = append(partialQueryStr, []string{ + fmt.Sprintf(`%sData = from(bucket: "%s")`, nestedDurationKey, bucketName), + fmt.Sprintf(`|> range(start: %s, stop: %s)`, durationRange[0], durationRange[1]), + `|> filter(fn: (r) => r["_measurement"] == "temp" )`, + `|> aggregateWindow(every: 1h, fn: mean, createEmpty: false)`, + `|> group(columns: ["device_wwn"])`, + `|> toInt()`, + "", + }...) + } + + if len(subQueryNames) == 1 { + //there's only one bucket being queried, no need to union, just aggregate the dataset and return + partialQueryStr = append(partialQueryStr, []string{ + subQueryNames[0], + "|> schema.fieldsAsCols()", + "|> yield()", + }...) + } else { + partialQueryStr = append(partialQueryStr, []string{ + fmt.Sprintf("union(tables: [%s])", strings.Join(subQueryNames, ", ")), + `|> group(columns: ["device_wwn"])`, + `|> sort(columns: ["_time"], desc: false)`, + "|> schema.fieldsAsCols()", + }...) + } + + return strings.Join(partialQueryStr, "\n") +} diff --git a/webapp/backend/pkg/models/collector/smart.go b/webapp/backend/pkg/models/collector/smart.go index 04d5e4c..4f7ae3d 100644 --- a/webapp/backend/pkg/models/collector/smart.go +++ b/webapp/backend/pkg/models/collector/smart.go @@ -119,30 +119,23 @@ type SmartInfo struct { FeatureControlSupported bool `json:"feature_control_supported"` DataTableSupported bool `json:"data_table_supported"` } `json:"ata_sct_capabilities"` + AtaSctTemperatureHistory struct { + Version int `json:"version"` + SamplingPeriodMinutes int64 `json:"sampling_period_minutes"` + LoggingIntervalMinutes int64 `json:"logging_interval_minutes"` + Temperature struct { + OpLimitMin int `json:"op_limit_min"` + OpLimitMax int `json:"op_limit_max"` + LimitMin int `json:"limit_min"` + LimitMax int `json:"limit_max"` + } `json:"temperature"` + Size int `json:"size"` + Index int `json:"index"` + Table []int64 `json:"table"` + } `json:"ata_sct_temperature_history"` AtaSmartAttributes struct { - Revision int `json:"revision"` - Table []struct { - ID int `json:"id"` - Name string `json:"name"` - Value int `json:"value"` - Worst int `json:"worst"` - Thresh int `json:"thresh"` - WhenFailed string `json:"when_failed"` - Flags struct { - Value int `json:"value"` - String string `json:"string"` - Prefailure bool `json:"prefailure"` - UpdatedOnline bool `json:"updated_online"` - Performance bool `json:"performance"` - ErrorRate bool `json:"error_rate"` - EventCount bool `json:"event_count"` - AutoKeep bool `json:"auto_keep"` - } `json:"flags"` - Raw struct { - Value int64 `json:"value"` - String string `json:"string"` - } `json:"raw"` - } `json:"table"` + Revision int `json:"revision"` + Table []AtaSmartAttributesTableItem `json:"table"` } `json:"ata_smart_attributes"` AtaSmartErrorLog struct { Summary struct { @@ -236,49 +229,77 @@ type SmartInfo struct { } `json:"utilization"` FormattedLbaSize int `json:"formatted_lba_size"` } `json:"nvme_namespaces"` - NvmeSmartHealthInformationLog struct { - CriticalWarning int `json:"critical_warning"` - Temperature int `json:"temperature"` - AvailableSpare int `json:"available_spare"` - AvailableSpareThreshold int `json:"available_spare_threshold"` - PercentageUsed int `json:"percentage_used"` - DataUnitsRead int `json:"data_units_read"` - DataUnitsWritten int `json:"data_units_written"` - HostReads int `json:"host_reads"` - HostWrites int `json:"host_writes"` - ControllerBusyTime int `json:"controller_busy_time"` - PowerCycles int `json:"power_cycles"` - PowerOnHours int `json:"power_on_hours"` - UnsafeShutdowns int `json:"unsafe_shutdowns"` - MediaErrors int `json:"media_errors"` - NumErrLogEntries int `json:"num_err_log_entries"` - WarningTempTime int `json:"warning_temp_time"` - CriticalCompTime int `json:"critical_comp_time"` - } `json:"nvme_smart_health_information_log"` + NvmeSmartHealthInformationLog NvmeSmartHealthInformationLog `json:"nvme_smart_health_information_log"` // SCSI Protocol Specific Fields - Vendor string `json:"vendor"` - Product string `json:"product"` - ScsiVersion string `json:"scsi_version"` - ScsiGrownDefectList int `json:"scsi_grown_defect_list"` - ScsiErrorCounterLog struct { - Read struct { - ErrorsCorrectedByEccfast int `json:"errors_corrected_by_eccfast"` - ErrorsCorrectedByEccdelayed int `json:"errors_corrected_by_eccdelayed"` - ErrorsCorrectedByRereadsRewrites int `json:"errors_corrected_by_rereads_rewrites"` - TotalErrorsCorrected int `json:"total_errors_corrected"` - CorrectionAlgorithmInvocations int `json:"correction_algorithm_invocations"` - GigabytesProcessed string `json:"gigabytes_processed"` - TotalUncorrectedErrors int `json:"total_uncorrected_errors"` - } `json:"read"` - Write struct { - ErrorsCorrectedByEccfast int `json:"errors_corrected_by_eccfast"` - ErrorsCorrectedByEccdelayed int `json:"errors_corrected_by_eccdelayed"` - ErrorsCorrectedByRereadsRewrites int `json:"errors_corrected_by_rereads_rewrites"` - TotalErrorsCorrected int `json:"total_errors_corrected"` - CorrectionAlgorithmInvocations int `json:"correction_algorithm_invocations"` - GigabytesProcessed string `json:"gigabytes_processed"` - TotalUncorrectedErrors int `json:"total_uncorrected_errors"` - } `json:"write"` - } `json:"scsi_error_counter_log"` + Vendor string `json:"vendor"` + Product string `json:"product"` + ScsiVersion string `json:"scsi_version"` + ScsiGrownDefectList int64 `json:"scsi_grown_defect_list"` + ScsiErrorCounterLog ScsiErrorCounterLog `json:"scsi_error_counter_log"` +} + +//Primary Attribute Structs +type AtaSmartAttributesTableItem struct { + ID int `json:"id"` + Name string `json:"name"` + Value int64 `json:"value"` + Worst int64 `json:"worst"` + Thresh int64 `json:"thresh"` + WhenFailed string `json:"when_failed"` + Flags struct { + Value int `json:"value"` + String string `json:"string"` + Prefailure bool `json:"prefailure"` + UpdatedOnline bool `json:"updated_online"` + Performance bool `json:"performance"` + ErrorRate bool `json:"error_rate"` + EventCount bool `json:"event_count"` + AutoKeep bool `json:"auto_keep"` + } `json:"flags"` + Raw struct { + Value int64 `json:"value"` + String string `json:"string"` + } `json:"raw"` +} + +type NvmeSmartHealthInformationLog struct { + CriticalWarning int64 `json:"critical_warning"` + Temperature int64 `json:"temperature"` + AvailableSpare int64 `json:"available_spare"` + AvailableSpareThreshold int64 `json:"available_spare_threshold"` + PercentageUsed int64 `json:"percentage_used"` + DataUnitsRead int64 `json:"data_units_read"` + DataUnitsWritten int64 `json:"data_units_written"` + HostReads int64 `json:"host_reads"` + HostWrites int64 `json:"host_writes"` + ControllerBusyTime int64 `json:"controller_busy_time"` + PowerCycles int64 `json:"power_cycles"` + PowerOnHours int64 `json:"power_on_hours"` + UnsafeShutdowns int64 `json:"unsafe_shutdowns"` + MediaErrors int64 `json:"media_errors"` + NumErrLogEntries int64 `json:"num_err_log_entries"` + WarningTempTime int64 `json:"warning_temp_time"` + CriticalCompTime int64 `json:"critical_comp_time"` +} + +type ScsiErrorCounterLog struct { + Read struct { + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` + GigabytesProcessed string `json:"gigabytes_processed"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` + } `json:"read"` + Write struct { + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` + GigabytesProcessed string `json:"gigabytes_processed"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` + } `json:"write"` } diff --git a/webapp/backend/pkg/models/db/device.go b/webapp/backend/pkg/models/db/device.go deleted file mode 100644 index 2786103..0000000 --- a/webapp/backend/pkg/models/db/device.go +++ /dev/null @@ -1,160 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "time" -) - -type DeviceWrapper struct { - Success bool `json:"success"` - Errors []error `json:"errors"` - Data []Device `json:"data"` -} - -const DeviceProtocolAta = "ATA" -const DeviceProtocolScsi = "SCSI" -const DeviceProtocolNvme = "NVMe" - -type Device struct { - //GORM attributes, see: http://gorm.io/docs/conventions.html - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt *time.Time - - WWN string `json:"wwn" gorm:"primary_key"` - HostId string `json:"host_id"` - - DeviceName string `json:"device_name"` - Manufacturer string `json:"manufacturer"` - ModelName string `json:"model_name"` - InterfaceType string `json:"interface_type"` - InterfaceSpeed string `json:"interface_speed"` - SerialNumber string `json:"serial_number"` - Firmware string `json:"firmware"` - RotationSpeed int `json:"rotational_speed"` - Capacity int64 `json:"capacity"` - FormFactor string `json:"form_factor"` - SmartSupport bool `json:"smart_support"` - DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) - DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. - SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"` -} - -func (dv *Device) IsAta() bool { - return dv.DeviceProtocol == DeviceProtocolAta -} - -func (dv *Device) IsScsi() bool { - return dv.DeviceProtocol == DeviceProtocolScsi -} - -func (dv *Device) IsNvme() bool { - return dv.DeviceProtocol == DeviceProtocolNvme -} - -//This method requires a device with an array of SmartResults. -//It will remove all SmartResults other than the first (the latest one) -//All removed SmartResults, will be processed, grouping SmartAtaAttribute by attribute_id -// and adding theme to an array called History. -func (dv *Device) SquashHistory() error { - if len(dv.SmartResults) <= 1 { - return nil //no ataHistory found. ignore - } - - latestSmartResultSlice := dv.SmartResults[0:1] - historicalSmartResultSlice := dv.SmartResults[1:] - - //re-assign the latest slice to the SmartResults field - dv.SmartResults = latestSmartResultSlice - - //process the historical slice for ATA data - if len(dv.SmartResults[0].AtaAttributes) > 0 { - ataHistory := map[int][]SmartAtaAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.AtaAttributes { - if _, ok := ataHistory[smartAttribute.AttributeId]; !ok { - ataHistory[smartAttribute.AttributeId] = []SmartAtaAttribute{} - } - ataHistory[smartAttribute.AttributeId] = append(ataHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].AtaAttributes { - if attributeHistory, ok := ataHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].AtaAttributes[sandx].History = attributeHistory - } - } - } - - //process the historical slice for Nvme data - if len(dv.SmartResults[0].NvmeAttributes) > 0 { - nvmeHistory := map[string][]SmartNvmeAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.NvmeAttributes { - if _, ok := nvmeHistory[smartAttribute.AttributeId]; !ok { - nvmeHistory[smartAttribute.AttributeId] = []SmartNvmeAttribute{} - } - nvmeHistory[smartAttribute.AttributeId] = append(nvmeHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].NvmeAttributes { - if attributeHistory, ok := nvmeHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].NvmeAttributes[sandx].History = attributeHistory - } - } - } - //process the historical slice for Scsi data - if len(dv.SmartResults[0].ScsiAttributes) > 0 { - scsiHistory := map[string][]SmartScsiAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.ScsiAttributes { - if _, ok := scsiHistory[smartAttribute.AttributeId]; !ok { - scsiHistory[smartAttribute.AttributeId] = []SmartScsiAttribute{} - } - scsiHistory[smartAttribute.AttributeId] = append(scsiHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].ScsiAttributes { - if attributeHistory, ok := scsiHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].ScsiAttributes[sandx].History = attributeHistory - } - } - } - return nil -} - -func (dv *Device) ApplyMetadataRules() error { - - //embed metadata in the latest smart attributes object - if len(dv.SmartResults) > 0 { - for ndx, attr := range dv.SmartResults[0].AtaAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].AtaAttributes[ndx] = attr - } - - for ndx, attr := range dv.SmartResults[0].NvmeAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].NvmeAttributes[ndx] = attr - - } - - for ndx, attr := range dv.SmartResults[0].ScsiAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].ScsiAttributes[ndx] = attr - - } - } - return nil -} - -// This function is called every time the collector sends SMART data to the API. -// It can be used to update device data that can change over time. -func (dv *Device) UpdateFromCollectorSmartInfo(info collector.SmartInfo) error { - dv.Firmware = info.FirmwareVersion - return nil -} diff --git a/webapp/backend/pkg/models/db/selftest.go b/webapp/backend/pkg/models/db/selftest.go deleted file mode 100644 index 9e3d89d..0000000 --- a/webapp/backend/pkg/models/db/selftest.go +++ /dev/null @@ -1,15 +0,0 @@ -package db - -import "time" - -type SelfTest struct { - //GORM attributes, see: http://gorm.io/docs/conventions.html - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt *time.Time - - DeviceWWN string - Device Device `json:"-" gorm:"foreignkey:DeviceWWN"` // use DeviceWWN as foreign key - - Date time.Time -} diff --git a/webapp/backend/pkg/models/db/smart.go b/webapp/backend/pkg/models/db/smart.go deleted file mode 100644 index 510dcb2..0000000 --- a/webapp/backend/pkg/models/db/smart.go +++ /dev/null @@ -1,127 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "gorm.io/gorm" - "time" -) - -const SmartWhenFailedFailingNow = "FAILING_NOW" -const SmartWhenFailedInThePast = "IN_THE_PAST" - -const SmartStatusPassed = "passed" -const SmartStatusFailed = "failed" - -type Smart struct { - gorm.Model - - DeviceWWN string `json:"device_wwn"` - Device Device `json:"-" gorm:"foreignkey:DeviceWWN"` // use DeviceWWN as foreign key - - TestDate time.Time `json:"date"` - SmartStatus string `json:"smart_status"` // SmartStatusPassed or SmartStatusFailed - - //Metrics - Temp int64 `json:"temp"` - PowerOnHours int64 `json:"power_on_hours"` - PowerCycleCount int64 `json:"power_cycle_count"` - - AtaAttributes []SmartAtaAttribute `json:"ata_attributes" gorm:"foreignkey:SmartId"` - NvmeAttributes []SmartNvmeAttribute `json:"nvme_attributes" gorm:"foreignkey:SmartId"` - ScsiAttributes []SmartScsiAttribute `json:"scsi_attributes" gorm:"foreignkey:SmartId"` -} - -//Parse Collector SMART data results and create Smart object (and associated SmartAtaAttribute entries) -func (sm *Smart) FromCollectorSmartInfo(wwn string, info collector.SmartInfo) error { - sm.DeviceWWN = wwn - sm.TestDate = time.Unix(info.LocalTime.TimeT, 0) - - //smart metrics - sm.Temp = info.Temperature.Current - sm.PowerCycleCount = info.PowerCycleCount - sm.PowerOnHours = info.PowerOnTime.Hours - - // process ATA/NVME/SCSI protocol data - if info.Device.Protocol == DeviceProtocolAta { - sm.ProcessAtaSmartInfo(info) - } else if info.Device.Protocol == DeviceProtocolNvme { - sm.ProcessNvmeSmartInfo(info) - } else if info.Device.Protocol == DeviceProtocolScsi { - sm.ProcessScsiSmartInfo(info) - } - - if info.SmartStatus.Passed { - sm.SmartStatus = SmartStatusPassed - } else { - sm.SmartStatus = SmartStatusFailed - } - return nil -} - -//generate SmartAtaAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessAtaSmartInfo(info collector.SmartInfo) { - sm.AtaAttributes = []SmartAtaAttribute{} - for _, collectorAttr := range info.AtaSmartAttributes.Table { - attrModel := SmartAtaAttribute{ - AttributeId: collectorAttr.ID, - Name: collectorAttr.Name, - Value: collectorAttr.Value, - Worst: collectorAttr.Worst, - Threshold: collectorAttr.Thresh, - RawValue: collectorAttr.Raw.Value, - RawString: collectorAttr.Raw.String, - WhenFailed: collectorAttr.WhenFailed, - } - - //now that we've parsed the data from the smartctl response, lets match it against our metadata rules and add additional Scrutiny specific data. - if smartMetadata, ok := metadata.AtaMetadata[collectorAttr.ID]; ok { - attrModel.Name = smartMetadata.DisplayName - if smartMetadata.Transform != nil { - attrModel.TransformedValue = smartMetadata.Transform(attrModel.Value, attrModel.RawValue, attrModel.RawString) - } - } - sm.AtaAttributes = append(sm.AtaAttributes, attrModel) - } -} - -//generate SmartNvmeAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessNvmeSmartInfo(info collector.SmartInfo) { - sm.NvmeAttributes = []SmartNvmeAttribute{ - {AttributeId: "critical_warning", Name: "Critical Warning", Value: info.NvmeSmartHealthInformationLog.CriticalWarning, Threshold: 0}, - {AttributeId: "temperature", Name: "Temperature", Value: info.NvmeSmartHealthInformationLog.Temperature, Threshold: -1}, - {AttributeId: "available_spare", Name: "Available Spare", Value: info.NvmeSmartHealthInformationLog.AvailableSpare, Threshold: info.NvmeSmartHealthInformationLog.AvailableSpareThreshold}, - {AttributeId: "percentage_used", Name: "Percentage Used", Value: info.NvmeSmartHealthInformationLog.PercentageUsed, Threshold: 100}, - {AttributeId: "data_units_read", Name: "Data Units Read", Value: info.NvmeSmartHealthInformationLog.DataUnitsRead, Threshold: -1}, - {AttributeId: "data_units_written", Name: "Data Units Written", Value: info.NvmeSmartHealthInformationLog.DataUnitsWritten, Threshold: -1}, - {AttributeId: "host_reads", Name: "Host Reads", Value: info.NvmeSmartHealthInformationLog.HostReads, Threshold: -1}, - {AttributeId: "host_writes", Name: "Host Writes", Value: info.NvmeSmartHealthInformationLog.HostWrites, Threshold: -1}, - {AttributeId: "controller_busy_time", Name: "Controller Busy Time", Value: info.NvmeSmartHealthInformationLog.ControllerBusyTime, Threshold: -1}, - {AttributeId: "power_cycles", Name: "Power Cycles", Value: info.NvmeSmartHealthInformationLog.PowerCycles, Threshold: -1}, - {AttributeId: "power_on_hours", Name: "Power on Hours", Value: info.NvmeSmartHealthInformationLog.PowerOnHours, Threshold: -1}, - {AttributeId: "unsafe_shutdowns", Name: "Unsafe Shutdowns", Value: info.NvmeSmartHealthInformationLog.UnsafeShutdowns, Threshold: -1}, - {AttributeId: "media_errors", Name: "Media Errors", Value: info.NvmeSmartHealthInformationLog.MediaErrors, Threshold: 0}, - {AttributeId: "num_err_log_entries", Name: "Numb Err Log Entries", Value: info.NvmeSmartHealthInformationLog.NumErrLogEntries, Threshold: 0}, - {AttributeId: "warning_temp_time", Name: "Warning Temp Time", Value: info.NvmeSmartHealthInformationLog.WarningTempTime, Threshold: -1}, - {AttributeId: "critical_comp_time", Name: "Critical CompTime", Value: info.NvmeSmartHealthInformationLog.CriticalCompTime, Threshold: -1}, - } -} - -//generate SmartScsiAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessScsiSmartInfo(info collector.SmartInfo) { - sm.ScsiAttributes = []SmartScsiAttribute{ - {AttributeId: "scsi_grown_defect_list", Name: "Grown Defect List", Value: info.ScsiGrownDefectList, Threshold: 0}, - {AttributeId: "read.errors_corrected_by_eccfast", Name: "Read Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccfast, Threshold: -1}, - {AttributeId: "read.errors_corrected_by_eccdelayed", Name: "Read Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed, Threshold: -1}, - {AttributeId: "read.errors_corrected_by_rereads_rewrites", Name: "Read Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, - {AttributeId: "read.total_errors_corrected", Name: "Read Total Errors Corrected", Value: info.ScsiErrorCounterLog.Read.TotalErrorsCorrected, Threshold: -1}, - {AttributeId: "read.correction_algorithm_invocations", Name: "Read Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Read.CorrectionAlgorithmInvocations, Threshold: -1}, - {AttributeId: "read.total_uncorrected_errors", Name: "Read Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Read.TotalUncorrectedErrors, Threshold: 0}, - {AttributeId: "write.errors_corrected_by_eccfast", Name: "Write Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccfast, Threshold: -1}, - {AttributeId: "write.errors_corrected_by_eccdelayed", Name: "Write Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed, Threshold: -1}, - {AttributeId: "write.errors_corrected_by_rereads_rewrites", Name: "Write Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, - {AttributeId: "write.total_errors_corrected", Name: "Write Total Errors Corrected", Value: info.ScsiErrorCounterLog.Write.TotalErrorsCorrected, Threshold: -1}, - {AttributeId: "write.correction_algorithm_invocations", Name: "Write Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Write.CorrectionAlgorithmInvocations, Threshold: -1}, - {AttributeId: "write.total_uncorrected_errors", Name: "Write Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Write.TotalUncorrectedErrors, Threshold: 0}, - } -} diff --git a/webapp/backend/pkg/models/db/smart_ata_attribute.go b/webapp/backend/pkg/models/db/smart_ata_attribute.go deleted file mode 100644 index 510672d..0000000 --- a/webapp/backend/pkg/models/db/smart_ata_attribute.go +++ /dev/null @@ -1,111 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" - "strings" -) - -const SmartAttributeStatusPassed = "passed" -const SmartAttributeStatusFailed = "failed" -const SmartAttributeStatusWarning = "warn" - -type SmartAtaAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId int `json:"attribute_id"` - Name string `json:"name"` - Value int `json:"value"` - Worst int `json:"worst"` - Threshold int `json:"thresh"` - RawValue int64 `json:"raw_value"` - RawString string `json:"raw_string"` - WhenFailed string `json:"when_failed"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartAtaAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartAtaAttribute) PopulateAttributeStatus() { - if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedFailingNow { - //this attribute has previously failed - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing manufacturer SMART threshold" - - } else if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedInThePast { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Attribute has previously failed manufacturer SMART threshold" - } - - if smartMetadata, ok := metadata.AtaMetadata[sa.AttributeId]; ok { - sa.MetadataObservedThresholdStatus(smartMetadata) - } - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} - -// compare the attribute (raw, normalized, transformed) value to observed thresholds, and update status if necessary -func (sa *SmartAtaAttribute) MetadataObservedThresholdStatus(smartMetadata metadata.AtaAttributeMetadata) { - //TODO: multiple rules - // try to predict the failure rates for observed thresholds that have 0 failure rate and error bars. - // - if the attribute is critical - // - the failure rate is over 10 - set to failed - // - the attribute does not match any threshold, set to warn - // - if the attribute is not critical - // - if failure rate is above 20 - set to failed - // - if failure rate is above 10 but below 20 - set to warn - - //update the smart attribute status based on Observed thresholds. - var value int64 - if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeNormalized { - value = int64(sa.Value) - } else if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeTransformed { - value = sa.TransformedValue - } else { - value = sa.RawValue - } - - for _, obsThresh := range smartMetadata.ObservedThresholds { - - //check if "value" is in this bucket - if ((obsThresh.Low == obsThresh.High) && value == obsThresh.Low) || - (obsThresh.Low < value && value <= obsThresh.High) { - sa.FailureRate = obsThresh.AnnualFailureRate - - if smartMetadata.Critical { - if obsThresh.AnnualFailureRate >= 0.10 { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Observed Failure Rate for Critical Attribute is greater than 10%" - } - } else { - if obsThresh.AnnualFailureRate >= 0.20 { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Observed Failure Rate for Attribute is greater than 20%" - } else if obsThresh.AnnualFailureRate >= 0.10 { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Observed Failure Rate for Attribute is greater than 10%" - } - } - - //we've found the correct bucket, we can drop out of this loop - return - } - } - // no bucket found - if smartMetadata.Critical { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Could not determine Observed Failure Rate for Critical Attribute" - } - - return -} diff --git a/webapp/backend/pkg/models/db/smart_nvme_attribute.go b/webapp/backend/pkg/models/db/smart_nvme_attribute.go deleted file mode 100644 index b681181..0000000 --- a/webapp/backend/pkg/models/db/smart_nvme_attribute.go +++ /dev/null @@ -1,46 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" -) - -type SmartNvmeAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId string `json:"attribute_id"` //json string from smartctl - Name string `json:"name"` - Value int `json:"value"` - Threshold int `json:"thresh"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartNvmeAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartNvmeAttribute) PopulateAttributeStatus() { - - //-1 is a special number meaning no threshold. - if sa.Threshold != -1 { - if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { - //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold - if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || - (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing recommended SMART threshold" - } - } - } - //TODO: eventually figure out the critical_warning bits and determine correct error messages here. - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} diff --git a/webapp/backend/pkg/models/db/smart_scsci_attribute.go b/webapp/backend/pkg/models/db/smart_scsci_attribute.go deleted file mode 100644 index c6b1325..0000000 --- a/webapp/backend/pkg/models/db/smart_scsci_attribute.go +++ /dev/null @@ -1,45 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" -) - -type SmartScsiAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId string `json:"attribute_id"` //json string from smartctl - Name string `json:"name"` - Value int `json:"value"` - Threshold int `json:"thresh"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartScsiAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartScsiAttribute) PopulateAttributeStatus() { - - //-1 is a special number meaning no threshold. - if sa.Threshold != -1 { - if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { - //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold - if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || - (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing recommended SMART threshold" - } - } - } - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} diff --git a/webapp/backend/pkg/models/db/smart_test.go b/webapp/backend/pkg/models/db/smart_test.go deleted file mode 100644 index 0f03715..0000000 --- a/webapp/backend/pkg/models/db/smart_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package db_test - -import ( - "encoding/json" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" - "github.com/stretchr/testify/require" - "io/ioutil" - "os" - "testing" -) - -func TestFromCollectorSmartInfo(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-ata.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 18, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) - - //check that temperature was correctly parsed - for _, attr := range smartMdl.AtaAttributes { - if attr.AttributeId == 194 { - require.Equal(t, int64(163210330144), attr.RawValue) - require.Equal(t, int64(32), attr.TransformedValue) - } - } -} - -func TestFromCollectorSmartInfo_Fail(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-fail.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "failed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) -} - -func TestFromCollectorSmartInfo_Fail2(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-fail2.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "failed", smartMdl.SmartStatus) - require.Equal(t, 17, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) -} - -func TestFromCollectorSmartInfo_Nvme(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-nvme.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 16, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) - - require.Equal(t, 111303174, smartMdl.NvmeAttributes[6].Value) - require.Equal(t, 83170961, smartMdl.NvmeAttributes[7].Value) -} - -func TestFromCollectorSmartInfo_Scsi(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-scsi.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 13, len(smartMdl.ScsiAttributes)) - - require.Equal(t, 56, smartMdl.ScsiAttributes[0].Value) - require.Equal(t, 300357663, smartMdl.ScsiAttributes[4].Value) //total_errors_corrected -} diff --git a/webapp/backend/pkg/models/device.go b/webapp/backend/pkg/models/device.go new file mode 100644 index 0000000..c5272b4 --- /dev/null +++ b/webapp/backend/pkg/models/device.go @@ -0,0 +1,169 @@ +package models + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "time" +) + +type DeviceWrapper struct { + Success bool `json:"success"` + Errors []error `json:"errors"` + Data []Device `json:"data"` +} + +type Device struct { + //GORM attributes, see: http://gorm.io/docs/conventions.html + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt *time.Time + + WWN string `json:"wwn" gorm:"primary_key"` + + DeviceName string `json:"device_name"` + Manufacturer string `json:"manufacturer"` + ModelName string `json:"model_name"` + InterfaceType string `json:"interface_type"` + InterfaceSpeed string `json:"interface_speed"` + SerialNumber string `json:"serial_number"` + Firmware string `json:"firmware"` + RotationSpeed int `json:"rotational_speed"` + Capacity int64 `json:"capacity"` + FormFactor string `json:"form_factor"` + SmartSupport bool `json:"smart_support"` + DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) + DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. + + // User provided metadata + Label string `json:"label"` + HostId string `json:"host_id"` + + // Data set by Scrutiny + DeviceStatus pkg.DeviceStatus `json:"device_status"` +} + +func (dv *Device) IsAta() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolAta +} + +func (dv *Device) IsScsi() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolScsi +} + +func (dv *Device) IsNvme() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolNvme +} + +// +////This method requires a device with an array of SmartResults. +////It will remove all SmartResults other than the first (the latest one) +////All removed SmartResults, will be processed, grouping SmartAtaAttribute by attribute_id +//// and adding theme to an array called History. +//func (dv *Device) SquashHistory() error { +// if len(dv.SmartResults) <= 1 { +// return nil //no ataHistory found. ignore +// } +// +// latestSmartResultSlice := dv.SmartResults[0:1] +// historicalSmartResultSlice := dv.SmartResults[1:] +// +// //re-assign the latest slice to the SmartResults field +// dv.SmartResults = latestSmartResultSlice +// +// //process the historical slice for ATA data +// if len(dv.SmartResults[0].AtaAttributes) > 0 { +// ataHistory := map[int][]SmartAtaAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.AtaAttributes { +// if _, ok := ataHistory[smartAttribute.AttributeId]; !ok { +// ataHistory[smartAttribute.AttributeId] = []SmartAtaAttribute{} +// } +// ataHistory[smartAttribute.AttributeId] = append(ataHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].AtaAttributes { +// if attributeHistory, ok := ataHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].AtaAttributes[sandx].History = attributeHistory +// } +// } +// } +// +// //process the historical slice for Nvme data +// if len(dv.SmartResults[0].NvmeAttributes) > 0 { +// nvmeHistory := map[string][]SmartNvmeAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.NvmeAttributes { +// if _, ok := nvmeHistory[smartAttribute.AttributeId]; !ok { +// nvmeHistory[smartAttribute.AttributeId] = []SmartNvmeAttribute{} +// } +// nvmeHistory[smartAttribute.AttributeId] = append(nvmeHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].NvmeAttributes { +// if attributeHistory, ok := nvmeHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].NvmeAttributes[sandx].History = attributeHistory +// } +// } +// } +// //process the historical slice for Scsi data +// if len(dv.SmartResults[0].ScsiAttributes) > 0 { +// scsiHistory := map[string][]SmartScsiAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.ScsiAttributes { +// if _, ok := scsiHistory[smartAttribute.AttributeId]; !ok { +// scsiHistory[smartAttribute.AttributeId] = []SmartScsiAttribute{} +// } +// scsiHistory[smartAttribute.AttributeId] = append(scsiHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].ScsiAttributes { +// if attributeHistory, ok := scsiHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].ScsiAttributes[sandx].History = attributeHistory +// } +// } +// } +// return nil +//} +// +//func (dv *Device) ApplyMetadataRules() error { +// +// //embed metadata in the latest smart attributes object +// if len(dv.SmartResults) > 0 { +// for ndx, attr := range dv.SmartResults[0].AtaAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].AtaAttributes[ndx] = attr +// } +// +// for ndx, attr := range dv.SmartResults[0].NvmeAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].NvmeAttributes[ndx] = attr +// +// } +// +// for ndx, attr := range dv.SmartResults[0].ScsiAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].ScsiAttributes[ndx] = attr +// +// } +// } +// return nil +//} + +// This function is called every time the collector sends SMART data to the API. +// It can be used to update device data that can change over time. +func (dv *Device) UpdateFromCollectorSmartInfo(info collector.SmartInfo) error { + dv.Firmware = info.FirmwareVersion + dv.DeviceProtocol = info.Device.Protocol + + if !info.SmartStatus.Passed { + dv.DeviceStatus = pkg.Set(dv.DeviceStatus, pkg.DeviceStatusFailedSmart) + } + + return nil +} diff --git a/webapp/backend/pkg/models/device_summary.go b/webapp/backend/pkg/models/device_summary.go new file mode 100644 index 0000000..f4ca323 --- /dev/null +++ b/webapp/backend/pkg/models/device_summary.go @@ -0,0 +1,27 @@ +package models + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "time" +) + +type DeviceSummaryWrapper struct { + Success bool `json:"success"` + Errors []error `json:"errors"` + Data struct { + Summary map[string]*DeviceSummary `json:"summary"` + } `json:"data"` +} + +type DeviceSummary struct { + Device Device `json:"device"` + + SmartResults *SmartSummary `json:"smart,omitempty"` + TempHistory []measurements.SmartTemperature `json:"temp_history,omitempty"` +} +type SmartSummary struct { + // Collector Summary Data + CollectorDate time.Time `json:"collector_date,omitempty"` + Temp int64 `json:"temp,omitempty"` + PowerOnHours int64 `json:"power_on_hours,omitempty"` +} diff --git a/webapp/backend/pkg/models/measurements/smart.go b/webapp/backend/pkg/models/measurements/smart.go new file mode 100644 index 0000000..aadba20 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart.go @@ -0,0 +1,211 @@ +package measurements + +import ( + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" + "log" + "strconv" + "strings" + "time" +) + +type Smart struct { + Date time.Time `json:"date"` + DeviceWWN string `json:"device_wwn"` //(tag) + DeviceProtocol string `json:"device_protocol"` + + //Metrics (fields) + Temp int64 `json:"temp"` + PowerOnHours int64 `json:"power_on_hours"` + PowerCycleCount int64 `json:"power_cycle_count"` + + //Attributes (fields) + Attributes map[string]SmartAttribute `json:"attrs"` + + //status + Status pkg.DeviceStatus +} + +func (sm *Smart) Flatten() (tags map[string]string, fields map[string]interface{}) { + tags = map[string]string{ + "device_wwn": sm.DeviceWWN, + "device_protocol": sm.DeviceProtocol, + } + + fields = map[string]interface{}{ + "temp": sm.Temp, + "power_on_hours": sm.PowerOnHours, + "power_cycle_count": sm.PowerCycleCount, + } + + for _, attr := range sm.Attributes { + for attrKey, attrVal := range attr.Flatten() { + fields[attrKey] = attrVal + } + } + + return tags, fields +} + +func NewSmartFromInfluxDB(attrs map[string]interface{}) (*Smart, error) { + //go though the massive map returned from influxdb. If a key is associated with the Smart struct, assign it. If it starts with "attr.*" group it by attributeId, and pass to attribute inflate. + + sm := Smart{ + //required fields + Date: attrs["_time"].(time.Time), + DeviceWWN: attrs["device_wwn"].(string), + DeviceProtocol: attrs["device_protocol"].(string), + + Attributes: map[string]SmartAttribute{}, + } + + for key, val := range attrs { + switch key { + case "temp": + sm.Temp = val.(int64) + case "power_on_hours": + sm.PowerOnHours = val.(int64) + case "power_cycle_count": + sm.PowerCycleCount = val.(int64) + default: + // this key is unknown. + if !strings.HasPrefix(key, "attr.") { + continue + } + //this is a attribute, lets group it with its related "siblings", populating a SmartAttribute object + keyParts := strings.Split(key, ".") + attributeId := keyParts[1] + if _, ok := sm.Attributes[attributeId]; !ok { + // init the attribute group + if sm.DeviceProtocol == pkg.DeviceProtocolAta { + sm.Attributes[attributeId] = &SmartAtaAttribute{} + } else if sm.DeviceProtocol == pkg.DeviceProtocolNvme { + sm.Attributes[attributeId] = &SmartNvmeAttribute{} + } else if sm.DeviceProtocol == pkg.DeviceProtocolScsi { + sm.Attributes[attributeId] = &SmartScsiAttribute{} + } else { + return nil, fmt.Errorf("Unknown Device Protocol: %s", sm.DeviceProtocol) + } + } + + sm.Attributes[attributeId].Inflate(key, val) + } + + } + + log.Printf("Found Smart Device (%s) Attributes (%v)", sm.DeviceWWN, len(sm.Attributes)) + + return &sm, nil +} + +//Parse Collector SMART data results and create Smart object (and associated SmartAtaAttribute entries) +func (sm *Smart) FromCollectorSmartInfo(wwn string, info collector.SmartInfo) error { + sm.DeviceWWN = wwn + sm.Date = time.Unix(info.LocalTime.TimeT, 0) + + //smart metrics + sm.Temp = info.Temperature.Current + sm.PowerCycleCount = info.PowerCycleCount + sm.PowerOnHours = info.PowerOnTime.Hours + if !info.SmartStatus.Passed { + sm.Status = pkg.DeviceStatusFailedSmart + } + + sm.DeviceProtocol = info.Device.Protocol + // process ATA/NVME/SCSI protocol data + sm.Attributes = map[string]SmartAttribute{} + if sm.DeviceProtocol == pkg.DeviceProtocolAta { + sm.ProcessAtaSmartInfo(info.AtaSmartAttributes.Table) + } else if sm.DeviceProtocol == pkg.DeviceProtocolNvme { + sm.ProcessNvmeSmartInfo(info.NvmeSmartHealthInformationLog) + } else if sm.DeviceProtocol == pkg.DeviceProtocolScsi { + sm.ProcessScsiSmartInfo(info.ScsiGrownDefectList, info.ScsiErrorCounterLog) + } + + return nil +} + +//generate SmartAtaAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessAtaSmartInfo(tableItems []collector.AtaSmartAttributesTableItem) { + for _, collectorAttr := range tableItems { + attrModel := SmartAtaAttribute{ + AttributeId: collectorAttr.ID, + Value: collectorAttr.Value, + Worst: collectorAttr.Worst, + Threshold: collectorAttr.Thresh, + RawValue: collectorAttr.Raw.Value, + RawString: collectorAttr.Raw.String, + WhenFailed: collectorAttr.WhenFailed, + } + + //now that we've parsed the data from the smartctl response, lets match it against our metadata rules and add additional Scrutiny specific data. + if smartMetadata, ok := thresholds.AtaMetadata[collectorAttr.ID]; ok { + if smartMetadata.Transform != nil { + attrModel.TransformedValue = smartMetadata.Transform(attrModel.Value, attrModel.RawValue, attrModel.RawString) + } + } + attrModel.PopulateAttributeStatus() + sm.Attributes[strconv.Itoa(collectorAttr.ID)] = &attrModel + if attrModel.Status == pkg.SmartAttributeStatusFailed { + sm.Status = pkg.Set(sm.Status, pkg.DeviceStatusFailedScrutiny) + } + } +} + +//generate SmartNvmeAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessNvmeSmartInfo(nvmeSmartHealthInformationLog collector.NvmeSmartHealthInformationLog) { + + sm.Attributes = map[string]SmartAttribute{ + "critical_warning": (&SmartNvmeAttribute{AttributeId: "critical_warning", Value: nvmeSmartHealthInformationLog.CriticalWarning, Threshold: 0}).PopulateAttributeStatus(), + "temperature": (&SmartNvmeAttribute{AttributeId: "temperature", Value: nvmeSmartHealthInformationLog.Temperature, Threshold: -1}).PopulateAttributeStatus(), + "available_spare": (&SmartNvmeAttribute{AttributeId: "available_spare", Value: nvmeSmartHealthInformationLog.AvailableSpare, Threshold: nvmeSmartHealthInformationLog.AvailableSpareThreshold}).PopulateAttributeStatus(), + "percentage_used": (&SmartNvmeAttribute{AttributeId: "percentage_used", Value: nvmeSmartHealthInformationLog.PercentageUsed, Threshold: 100}).PopulateAttributeStatus(), + "data_units_read": (&SmartNvmeAttribute{AttributeId: "data_units_read", Value: nvmeSmartHealthInformationLog.DataUnitsRead, Threshold: -1}).PopulateAttributeStatus(), + "data_units_written": (&SmartNvmeAttribute{AttributeId: "data_units_written", Value: nvmeSmartHealthInformationLog.DataUnitsWritten, Threshold: -1}).PopulateAttributeStatus(), + "host_reads": (&SmartNvmeAttribute{AttributeId: "host_reads", Value: nvmeSmartHealthInformationLog.HostReads, Threshold: -1}).PopulateAttributeStatus(), + "host_writes": (&SmartNvmeAttribute{AttributeId: "host_writes", Value: nvmeSmartHealthInformationLog.HostWrites, Threshold: -1}).PopulateAttributeStatus(), + "controller_busy_time": (&SmartNvmeAttribute{AttributeId: "controller_busy_time", Value: nvmeSmartHealthInformationLog.ControllerBusyTime, Threshold: -1}).PopulateAttributeStatus(), + "power_cycles": (&SmartNvmeAttribute{AttributeId: "power_cycles", Value: nvmeSmartHealthInformationLog.PowerCycles, Threshold: -1}).PopulateAttributeStatus(), + "power_on_hours": (&SmartNvmeAttribute{AttributeId: "power_on_hours", Value: nvmeSmartHealthInformationLog.PowerOnHours, Threshold: -1}).PopulateAttributeStatus(), + "unsafe_shutdowns": (&SmartNvmeAttribute{AttributeId: "unsafe_shutdowns", Value: nvmeSmartHealthInformationLog.UnsafeShutdowns, Threshold: -1}).PopulateAttributeStatus(), + "media_errors": (&SmartNvmeAttribute{AttributeId: "media_errors", Value: nvmeSmartHealthInformationLog.MediaErrors, Threshold: 0}).PopulateAttributeStatus(), + "num_err_log_entries": (&SmartNvmeAttribute{AttributeId: "num_err_log_entries", Value: nvmeSmartHealthInformationLog.NumErrLogEntries, Threshold: 0}).PopulateAttributeStatus(), + "warning_temp_time": (&SmartNvmeAttribute{AttributeId: "warning_temp_time", Value: nvmeSmartHealthInformationLog.WarningTempTime, Threshold: -1}).PopulateAttributeStatus(), + "critical_comp_time": (&SmartNvmeAttribute{AttributeId: "critical_comp_time", Value: nvmeSmartHealthInformationLog.CriticalCompTime, Threshold: -1}).PopulateAttributeStatus(), + } + + //find analyzed attribute status + for _, val := range sm.Attributes { + if val.GetStatus() == pkg.SmartAttributeStatusFailed { + sm.Status = pkg.Set(sm.Status, pkg.DeviceStatusFailedScrutiny) + } + } +} + +//generate SmartScsiAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessScsiSmartInfo(defectGrownList int64, scsiErrorCounterLog collector.ScsiErrorCounterLog) { + sm.Attributes = map[string]SmartAttribute{ + "scsi_grown_defect_list": (&SmartScsiAttribute{AttributeId: "scsi_grown_defect_list", Value: defectGrownList, Threshold: 0}).PopulateAttributeStatus(), + "read_errors_corrected_by_eccfast": (&SmartScsiAttribute{AttributeId: "read_errors_corrected_by_eccfast", Value: scsiErrorCounterLog.Read.ErrorsCorrectedByEccfast, Threshold: -1}).PopulateAttributeStatus(), + "read_errors_corrected_by_eccdelayed": (&SmartScsiAttribute{AttributeId: "read_errors_corrected_by_eccdelayed", Value: scsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed, Threshold: -1}).PopulateAttributeStatus(), + "read_errors_corrected_by_rereads_rewrites": (&SmartScsiAttribute{AttributeId: "read_errors_corrected_by_rereads_rewrites", Value: scsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites, Threshold: 0}).PopulateAttributeStatus(), + "read_total_errors_corrected": (&SmartScsiAttribute{AttributeId: "read_total_errors_corrected", Value: scsiErrorCounterLog.Read.TotalErrorsCorrected, Threshold: -1}).PopulateAttributeStatus(), + "read_correction_algorithm_invocations": (&SmartScsiAttribute{AttributeId: "read_correction_algorithm_invocations", Value: scsiErrorCounterLog.Read.CorrectionAlgorithmInvocations, Threshold: -1}).PopulateAttributeStatus(), + "read_total_uncorrected_errors": (&SmartScsiAttribute{AttributeId: "read_total_uncorrected_errors", Value: scsiErrorCounterLog.Read.TotalUncorrectedErrors, Threshold: 0}).PopulateAttributeStatus(), + "write_errors_corrected_by_eccfast": (&SmartScsiAttribute{AttributeId: "write_errors_corrected_by_eccfast", Value: scsiErrorCounterLog.Write.ErrorsCorrectedByEccfast, Threshold: -1}).PopulateAttributeStatus(), + "write_errors_corrected_by_eccdelayed": (&SmartScsiAttribute{AttributeId: "write_errors_corrected_by_eccdelayed", Value: scsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed, Threshold: -1}).PopulateAttributeStatus(), + "write_errors_corrected_by_rereads_rewrites": (&SmartScsiAttribute{AttributeId: "write_errors_corrected_by_rereads_rewrites", Value: scsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites, Threshold: 0}).PopulateAttributeStatus(), + "write_total_errors_corrected": (&SmartScsiAttribute{AttributeId: "write_total_errors_corrected", Value: scsiErrorCounterLog.Write.TotalErrorsCorrected, Threshold: -1}).PopulateAttributeStatus(), + "write_correction_algorithm_invocations": (&SmartScsiAttribute{AttributeId: "write_correction_algorithm_invocations", Value: scsiErrorCounterLog.Write.CorrectionAlgorithmInvocations, Threshold: -1}).PopulateAttributeStatus(), + "write_total_uncorrected_errors": (&SmartScsiAttribute{AttributeId: "write_total_uncorrected_errors", Value: scsiErrorCounterLog.Write.TotalUncorrectedErrors, Threshold: 0}).PopulateAttributeStatus(), + } + + //find analyzed attribute status + for _, val := range sm.Attributes { + if val.GetStatus() == pkg.SmartAttributeStatusFailed { + sm.Status = pkg.Set(sm.Status, pkg.DeviceStatusFailedScrutiny) + } + } +} diff --git a/webapp/backend/pkg/models/measurements/smart_ata_attribute.go b/webapp/backend/pkg/models/measurements/smart_ata_attribute.go new file mode 100644 index 0000000..7b0606c --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_ata_attribute.go @@ -0,0 +1,163 @@ +package measurements + +import ( + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" + "strconv" + "strings" +) + +type SmartAtaAttribute struct { + AttributeId int `json:"attribute_id"` + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + Worst int64 `json:"worst"` + RawValue int64 `json:"raw_value"` + RawString string `json:"raw_string"` + WhenFailed string `json:"when_failed"` + + //Generated data + TransformedValue int64 `json:"transformed_value"` + Status int64 `json:"status"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartAtaAttribute) GetStatus() int64 { + return sa.Status +} + +func (sa *SmartAtaAttribute) Flatten() map[string]interface{} { + + idString := strconv.Itoa(sa.AttributeId) + + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", idString): idString, + fmt.Sprintf("attr.%s.value", idString): sa.Value, + fmt.Sprintf("attr.%s.worst", idString): sa.Worst, + fmt.Sprintf("attr.%s.thresh", idString): sa.Threshold, + fmt.Sprintf("attr.%s.raw_value", idString): sa.RawValue, + fmt.Sprintf("attr.%s.raw_string", idString): sa.RawString, + fmt.Sprintf("attr.%s.when_failed", idString): sa.WhenFailed, + + //Generated Data + fmt.Sprintf("attr.%s.transformed_value", idString): sa.TransformedValue, + fmt.Sprintf("attr.%s.status", idString): sa.Status, + fmt.Sprintf("attr.%s.status_reason", idString): sa.StatusReason, + fmt.Sprintf("attr.%s.failure_rate", idString): sa.FailureRate, + } +} +func (sa *SmartAtaAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + attrId, err := strconv.Atoi(val.(string)) + if err == nil { + sa.AttributeId = attrId + } + case "value": + sa.Value = val.(int64) + case "worst": + sa.Worst = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + case "raw_value": + sa.RawValue = val.(int64) + case "raw_string": + sa.RawString = val.(string) + case "when_failed": + sa.WhenFailed = val.(string) + + //generated + case "transformed_value": + sa.TransformedValue = val.(int64) + case "status": + sa.Status = val.(int64) + case "status_reason": + sa.StatusReason = val.(string) + case "failure_rate": + sa.FailureRate = val.(float64) + + } +} + +//populate attribute status, using SMART Thresholds & Observed Metadata +// Chainable +func (sa *SmartAtaAttribute) PopulateAttributeStatus() *SmartAtaAttribute { + if strings.ToUpper(sa.WhenFailed) == pkg.SmartWhenFailedFailingNow { + //this attribute has previously failed + sa.Status = pkg.SmartAttributeStatusFailed + sa.StatusReason = "Attribute is failing manufacturer SMART threshold" + + } else if strings.ToUpper(sa.WhenFailed) == pkg.SmartWhenFailedInThePast { + sa.Status = pkg.SmartAttributeStatusWarning + sa.StatusReason = "Attribute has previously failed manufacturer SMART threshold" + } + + if smartMetadata, ok := thresholds.AtaMetadata[sa.AttributeId]; ok { + sa.ValidateThreshold(smartMetadata) + } + + return sa +} + +// compare the attribute (raw, normalized, transformed) value to observed thresholds, and update status if necessary +func (sa *SmartAtaAttribute) ValidateThreshold(smartMetadata thresholds.AtaAttributeMetadata) { + //TODO: multiple rules + // try to predict the failure rates for observed thresholds that have 0 failure rate and error bars. + // - if the attribute is critical + // - the failure rate is over 10 - set to failed + // - the attribute does not match any threshold, set to warn + // - if the attribute is not critical + // - if failure rate is above 20 - set to failed + // - if failure rate is above 10 but below 20 - set to warn + + //update the smart attribute status based on Observed thresholds. + var value int64 + if smartMetadata.DisplayType == thresholds.AtaSmartAttributeDisplayTypeNormalized { + value = int64(sa.Value) + } else if smartMetadata.DisplayType == thresholds.AtaSmartAttributeDisplayTypeTransformed { + value = sa.TransformedValue + } else { + value = sa.RawValue + } + + for _, obsThresh := range smartMetadata.ObservedThresholds { + + //check if "value" is in this bucket + if ((obsThresh.Low == obsThresh.High) && value == obsThresh.Low) || + (obsThresh.Low < value && value <= obsThresh.High) { + sa.FailureRate = obsThresh.AnnualFailureRate + + if smartMetadata.Critical { + if obsThresh.AnnualFailureRate >= 0.10 { + sa.Status = pkg.SmartAttributeStatusFailed + sa.StatusReason = "Observed Failure Rate for Critical Attribute is greater than 10%" + } + } else { + if obsThresh.AnnualFailureRate >= 0.20 { + sa.Status = pkg.SmartAttributeStatusFailed + sa.StatusReason = "Observed Failure Rate for Attribute is greater than 20%" + } else if obsThresh.AnnualFailureRate >= 0.10 { + sa.Status = pkg.SmartAttributeStatusWarning + sa.StatusReason = "Observed Failure Rate for Attribute is greater than 10%" + } + } + + //we've found the correct bucket, we can drop out of this loop + return + } + } + // no bucket found + if smartMetadata.Critical { + sa.Status = pkg.SmartAttributeStatusWarning + sa.StatusReason = "Could not determine Observed Failure Rate for Critical Attribute" + } + + return +} diff --git a/webapp/backend/pkg/models/measurements/smart_attribute.go b/webapp/backend/pkg/models/measurements/smart_attribute.go new file mode 100644 index 0000000..02a4fa7 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_attribute.go @@ -0,0 +1,7 @@ +package measurements + +type SmartAttribute interface { + Flatten() (fields map[string]interface{}) + Inflate(key string, val interface{}) + GetStatus() int64 +} diff --git a/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go b/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go new file mode 100644 index 0000000..c4fbe0e --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go @@ -0,0 +1,83 @@ +package measurements + +import ( + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" + "strings" +) + +type SmartNvmeAttribute struct { + AttributeId string `json:"attribute_id"` //json string from smartctl + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status int64 `json:"status"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartNvmeAttribute) GetStatus() int64 { + return sa.Status +} + +func (sa *SmartNvmeAttribute) Flatten() map[string]interface{} { + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", sa.AttributeId): sa.AttributeId, + fmt.Sprintf("attr.%s.value", sa.AttributeId): sa.Value, + fmt.Sprintf("attr.%s.thresh", sa.AttributeId): sa.Threshold, + + //Generated Data + fmt.Sprintf("attr.%s.transformed_value", sa.AttributeId): sa.TransformedValue, + fmt.Sprintf("attr.%s.status", sa.AttributeId): sa.Status, + fmt.Sprintf("attr.%s.status_reason", sa.AttributeId): sa.StatusReason, + fmt.Sprintf("attr.%s.failure_rate", sa.AttributeId): sa.FailureRate, + } +} +func (sa *SmartNvmeAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + sa.AttributeId = val.(string) + case "value": + sa.Value = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + + //generated + case "transformed_value": + sa.TransformedValue = val.(int64) + case "status": + sa.Status = val.(int64) + case "status_reason": + sa.StatusReason = val.(string) + case "failure_rate": + sa.FailureRate = val.(float64) + } +} + +//populate attribute status, using SMART Thresholds & Observed Metadata +// Chainable +func (sa *SmartNvmeAttribute) PopulateAttributeStatus() *SmartNvmeAttribute { + + //-1 is a special number meaning no threshold. + if sa.Threshold != -1 { + if smartMetadata, ok := thresholds.NmveMetadata[sa.AttributeId]; ok { + //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold + if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || + (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { + sa.Status = pkg.SmartAttributeStatusFailed + sa.StatusReason = "Attribute is failing recommended SMART threshold" + } + } + } + //TODO: eventually figure out the critical_warning bits and determine correct error messages here. + + return sa +} diff --git a/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go b/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go new file mode 100644 index 0000000..f9049a6 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go @@ -0,0 +1,83 @@ +package measurements + +import ( + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" + "strings" +) + +type SmartScsiAttribute struct { + AttributeId string `json:"attribute_id"` //json string from smartctl + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status int64 `json:"status"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartScsiAttribute) GetStatus() int64 { + return sa.Status +} + +func (sa *SmartScsiAttribute) Flatten() map[string]interface{} { + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", sa.AttributeId): sa.AttributeId, + fmt.Sprintf("attr.%s.value", sa.AttributeId): sa.Value, + fmt.Sprintf("attr.%s.thresh", sa.AttributeId): sa.Threshold, + + //Generated Data + fmt.Sprintf("attr.%s.transformed_value", sa.AttributeId): sa.TransformedValue, + fmt.Sprintf("attr.%s.status", sa.AttributeId): sa.Status, + fmt.Sprintf("attr.%s.status_reason", sa.AttributeId): sa.StatusReason, + fmt.Sprintf("attr.%s.failure_rate", sa.AttributeId): sa.FailureRate, + } +} +func (sa *SmartScsiAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + sa.AttributeId = val.(string) + case "value": + sa.Value = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + + //generated + case "transformed_value": + sa.TransformedValue = val.(int64) + case "status": + sa.Status = val.(int64) + case "status_reason": + sa.StatusReason = val.(string) + case "failure_rate": + sa.FailureRate = val.(float64) + } +} + +// +//populate attribute status, using SMART Thresholds & Observed Metadata +//Chainable +func (sa *SmartScsiAttribute) PopulateAttributeStatus() *SmartScsiAttribute { + + //-1 is a special number meaning no threshold. + if sa.Threshold != -1 { + if smartMetadata, ok := thresholds.NmveMetadata[sa.AttributeId]; ok { + //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold + if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || + (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { + sa.Status = pkg.SmartAttributeStatusFailed + sa.StatusReason = "Attribute is failing recommended SMART threshold" + } + } + } + + return sa +} diff --git a/webapp/backend/pkg/models/measurements/smart_temperature.go b/webapp/backend/pkg/models/measurements/smart_temperature.go new file mode 100644 index 0000000..e29e79e --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_temperature.go @@ -0,0 +1,34 @@ +package measurements + +import ( + "time" +) + +type SmartTemperature struct { + Date time.Time `json:"date"` + Temp int64 `json:"temp"` +} + +func (st *SmartTemperature) Flatten() (tags map[string]string, fields map[string]interface{}) { + fields = map[string]interface{}{ + "temp": st.Temp, + } + tags = map[string]string{} + + return tags, fields +} + +func (st *SmartTemperature) Inflate(key string, val interface{}) { + if val == nil { + return + } + + if key == "temp" { + switch t := val.(type) { + case int64: + st.Temp = t + case float64: + st.Temp = int64(t) + } + } +} diff --git a/webapp/backend/pkg/models/measurements/smart_test.go b/webapp/backend/pkg/models/measurements/smart_test.go new file mode 100644 index 0000000..320528e --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_test.go @@ -0,0 +1,436 @@ +package measurements_test + +import ( + "encoding/json" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "github.com/stretchr/testify/require" + "io/ioutil" + "os" + "testing" + "time" +) + +func TestSmart_Flatten(t *testing.T) { + //setup + timeNow := time.Now() + smart := measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: pkg.DeviceProtocolAta, + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Attributes: nil, + Status: 0, + } + + //test + tags, fields := smart.Flatten() + + //assert + require.Equal(t, map[string]string{"device_protocol": "ATA", "device_wwn": "test-wwn"}, tags) + require.Equal(t, map[string]interface{}{"power_cycle_count": int64(10), "power_on_hours": int64(10), "temp": int64(50)}, fields) +} + +func TestSmart_Flatten_ATA(t *testing.T) { + //setup + timeNow := time.Now() + smart := measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: pkg.DeviceProtocolAta, + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Status: 0, + Attributes: map[string]measurements.SmartAttribute{ + "1": &measurements.SmartAtaAttribute{ + AttributeId: 1, + Value: 100, + Threshold: 1, + Worst: 100, + RawValue: 0, + RawString: "0", + WhenFailed: "", + }, + "2": &measurements.SmartAtaAttribute{ + AttributeId: 2, + Value: 135, + Threshold: 54, + Worst: 135, + RawValue: 108, + RawString: "108", + WhenFailed: "", + }, + }, + } + + //test + tags, fields := smart.Flatten() + + //assert + require.Equal(t, map[string]string{"device_protocol": "ATA", "device_wwn": "test-wwn"}, tags) + require.Equal(t, map[string]interface{}{ + "attr.1.attribute_id": "1", + "attr.1.failure_rate": float64(0), + "attr.1.raw_string": "0", + "attr.1.raw_value": int64(0), + "attr.1.status": int64(0), + "attr.1.status_reason": "", + "attr.1.thresh": int64(1), + "attr.1.transformed_value": int64(0), + "attr.1.value": int64(100), + "attr.1.when_failed": "", + "attr.1.worst": int64(100), + + "attr.2.attribute_id": "2", + "attr.2.failure_rate": float64(0), + "attr.2.raw_string": "108", + "attr.2.raw_value": int64(108), + "attr.2.status": int64(0), + "attr.2.status_reason": "", + "attr.2.thresh": int64(54), + "attr.2.transformed_value": int64(0), + "attr.2.value": int64(135), + "attr.2.when_failed": "", + "attr.2.worst": int64(135), + + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50), + }, fields) +} + +func TestSmart_Flatten_SCSI(t *testing.T) { + //setup + timeNow := time.Now() + smart := measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: pkg.DeviceProtocolScsi, + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Status: 0, + Attributes: map[string]measurements.SmartAttribute{ + "read_errors_corrected_by_eccfast": &measurements.SmartScsiAttribute{ + AttributeId: "read_errors_corrected_by_eccfast", + Value: int64(300357663), + }, + }, + } + + //test + tags, fields := smart.Flatten() + + //assert + require.Equal(t, map[string]string{"device_protocol": "SCSI", "device_wwn": "test-wwn"}, tags) + require.Equal(t, map[string]interface{}{ + "attr.read_errors_corrected_by_eccfast.attribute_id": "read_errors_corrected_by_eccfast", + "attr.read_errors_corrected_by_eccfast.failure_rate": float64(0), + "attr.read_errors_corrected_by_eccfast.status": int64(0), + "attr.read_errors_corrected_by_eccfast.status_reason": "", + "attr.read_errors_corrected_by_eccfast.thresh": int64(0), + "attr.read_errors_corrected_by_eccfast.transformed_value": int64(0), + "attr.read_errors_corrected_by_eccfast.value": int64(300357663), + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50)}, + fields) +} + +func TestSmart_Flatten_NVMe(t *testing.T) { + //setup + timeNow := time.Now() + smart := measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: pkg.DeviceProtocolNvme, + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Status: 0, + Attributes: map[string]measurements.SmartAttribute{ + "available_spare": &measurements.SmartNvmeAttribute{ + AttributeId: "available_spare", + Value: int64(100), + }, + }, + } + + //test + tags, fields := smart.Flatten() + + //assert + require.Equal(t, map[string]string{"device_protocol": "NVMe", "device_wwn": "test-wwn"}, tags) + require.Equal(t, map[string]interface{}{ + "attr.available_spare.attribute_id": "available_spare", + "attr.available_spare.failure_rate": float64(0), + "attr.available_spare.status": int64(0), + "attr.available_spare.status_reason": "", + "attr.available_spare.thresh": int64(0), + "attr.available_spare.transformed_value": int64(0), + "attr.available_spare.value": int64(100), + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50)}, fields) +} + +func TestNewSmartFromInfluxDB_ATA(t *testing.T) { + //setup + timeNow := time.Now() + attrs := map[string]interface{}{ + "_time": timeNow, + "device_wwn": "test-wwn", + "device_protocol": pkg.DeviceProtocolAta, + "attr.1.attribute_id": "1", + "attr.1.failure_rate": float64(0), + "attr.1.raw_string": "108", + "attr.1.raw_value": int64(108), + "attr.1.status": int64(0), + "attr.1.status_reason": "", + "attr.1.thresh": int64(54), + "attr.1.transformed_value": int64(0), + "attr.1.value": int64(135), + "attr.1.when_failed": "", + "attr.1.worst": int64(135), + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50), + } + + //test + smart, err := measurements.NewSmartFromInfluxDB(attrs) + + //assert + require.NoError(t, err) + require.Equal(t, &measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: "ATA", + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Attributes: map[string]measurements.SmartAttribute{ + "1": &measurements.SmartAtaAttribute{ + AttributeId: 1, + Value: 135, + Threshold: 54, + Worst: 135, + RawValue: 108, + RawString: "108", + WhenFailed: "", + }, + }, Status: 0}, smart) +} + +func TestNewSmartFromInfluxDB_NVMe(t *testing.T) { + //setup + timeNow := time.Now() + attrs := map[string]interface{}{ + "_time": timeNow, + "device_wwn": "test-wwn", + "device_protocol": pkg.DeviceProtocolNvme, + "attr.available_spare.attribute_id": "available_spare", + "attr.available_spare.failure_rate": float64(0), + "attr.available_spare.status": int64(0), + "attr.available_spare.status_reason": "", + "attr.available_spare.thresh": int64(0), + "attr.available_spare.transformed_value": int64(0), + "attr.available_spare.value": int64(100), + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50), + } + + //test + smart, err := measurements.NewSmartFromInfluxDB(attrs) + + //assert + require.NoError(t, err) + require.Equal(t, &measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: "NVMe", + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Attributes: map[string]measurements.SmartAttribute{ + "available_spare": &measurements.SmartNvmeAttribute{ + AttributeId: "available_spare", + Value: int64(100), + }, + }, Status: 0}, smart) +} + +func TestNewSmartFromInfluxDB_SCSI(t *testing.T) { + //setup + timeNow := time.Now() + attrs := map[string]interface{}{ + "_time": timeNow, + "device_wwn": "test-wwn", + "device_protocol": pkg.DeviceProtocolScsi, + "attr.read_errors_corrected_by_eccfast.attribute_id": "read_errors_corrected_by_eccfast", + "attr.read_errors_corrected_by_eccfast.failure_rate": float64(0), + "attr.read_errors_corrected_by_eccfast.status": int64(0), + "attr.read_errors_corrected_by_eccfast.status_reason": "", + "attr.read_errors_corrected_by_eccfast.thresh": int64(0), + "attr.read_errors_corrected_by_eccfast.transformed_value": int64(0), + "attr.read_errors_corrected_by_eccfast.value": int64(300357663), + "power_cycle_count": int64(10), + "power_on_hours": int64(10), + "temp": int64(50), + } + + //test + smart, err := measurements.NewSmartFromInfluxDB(attrs) + + //assert + require.NoError(t, err) + require.Equal(t, &measurements.Smart{ + Date: timeNow, + DeviceWWN: "test-wwn", + DeviceProtocol: "SCSI", + Temp: 50, + PowerOnHours: 10, + PowerCycleCount: 10, + Attributes: map[string]measurements.SmartAttribute{ + "read_errors_corrected_by_eccfast": &measurements.SmartScsiAttribute{ + AttributeId: "read_errors_corrected_by_eccfast", + Value: int64(300357663), + }, + }, Status: 0}, smart) +} + +func TestFromCollectorSmartInfo(t *testing.T) { + //setup + smartDataFile, err := os.Open("../testdata/smart-ata.json") + require.NoError(t, err) + defer smartDataFile.Close() + + var smartJson collector.SmartInfo + + smartDataBytes, err := ioutil.ReadAll(smartDataFile) + require.NoError(t, err) + err = json.Unmarshal(smartDataBytes, &smartJson) + require.NoError(t, err) + + //test + smartMdl := measurements.Smart{} + err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) + + //assert + require.NoError(t, err) + require.Equal(t, "WWN-test", smartMdl.DeviceWWN) + require.Equal(t, pkg.DeviceStatusPassed, smartMdl.Status) + require.Equal(t, 18, len(smartMdl.Attributes)) + + //check that temperature was correctly parsed + + require.Equal(t, int64(163210330144), smartMdl.Attributes["194"].(*measurements.SmartAtaAttribute).RawValue) + require.Equal(t, int64(32), smartMdl.Attributes["194"].(*measurements.SmartAtaAttribute).TransformedValue) +} + +func TestFromCollectorSmartInfo_Fail_Smart(t *testing.T) { + //setup + smartDataFile, err := os.Open("../testdata/smart-fail.json") + require.NoError(t, err) + defer smartDataFile.Close() + + var smartJson collector.SmartInfo + + smartDataBytes, err := ioutil.ReadAll(smartDataFile) + require.NoError(t, err) + err = json.Unmarshal(smartDataBytes, &smartJson) + require.NoError(t, err) + + //test + smartMdl := measurements.Smart{} + err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) + + //assert + require.NoError(t, err) + require.Equal(t, "WWN-test", smartMdl.DeviceWWN) + require.Equal(t, pkg.DeviceStatusFailedSmart, smartMdl.Status) + require.Equal(t, 0, len(smartMdl.Attributes)) +} + +func TestFromCollectorSmartInfo_Fail_ScrutinySmart(t *testing.T) { + //setup + smartDataFile, err := os.Open("../testdata/smart-fail2.json") + require.NoError(t, err) + defer smartDataFile.Close() + + var smartJson collector.SmartInfo + + smartDataBytes, err := ioutil.ReadAll(smartDataFile) + require.NoError(t, err) + err = json.Unmarshal(smartDataBytes, &smartJson) + require.NoError(t, err) + + //test + smartMdl := measurements.Smart{} + err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) + + //assert + require.NoError(t, err) + require.Equal(t, "WWN-test", smartMdl.DeviceWWN) + require.Equal(t, pkg.DeviceStatusFailedScrutiny|pkg.DeviceStatusFailedSmart, smartMdl.Status) + require.Equal(t, 17, len(smartMdl.Attributes)) +} + +func TestFromCollectorSmartInfo_Nvme(t *testing.T) { + //setup + smartDataFile, err := os.Open("../testdata/smart-nvme.json") + require.NoError(t, err) + defer smartDataFile.Close() + + var smartJson collector.SmartInfo + + smartDataBytes, err := ioutil.ReadAll(smartDataFile) + require.NoError(t, err) + err = json.Unmarshal(smartDataBytes, &smartJson) + require.NoError(t, err) + + //test + smartMdl := measurements.Smart{} + err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) + + //assert + require.NoError(t, err) + require.Equal(t, "WWN-test", smartMdl.DeviceWWN) + require.Equal(t, pkg.DeviceStatusPassed, smartMdl.Status) + require.Equal(t, 16, len(smartMdl.Attributes)) + + require.Equal(t, int64(111303174), smartMdl.Attributes["host_reads"].(*measurements.SmartNvmeAttribute).Value) + require.Equal(t, int64(83170961), smartMdl.Attributes["host_writes"].(*measurements.SmartNvmeAttribute).Value) +} + +func TestFromCollectorSmartInfo_Scsi(t *testing.T) { + //setup + smartDataFile, err := os.Open("../testdata/smart-scsi.json") + require.NoError(t, err) + defer smartDataFile.Close() + + var smartJson collector.SmartInfo + + smartDataBytes, err := ioutil.ReadAll(smartDataFile) + require.NoError(t, err) + err = json.Unmarshal(smartDataBytes, &smartJson) + require.NoError(t, err) + + //test + smartMdl := measurements.Smart{} + err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) + + //assert + require.NoError(t, err) + require.Equal(t, "WWN-test", smartMdl.DeviceWWN) + require.Equal(t, pkg.DeviceStatusPassed, smartMdl.Status) + require.Equal(t, 13, len(smartMdl.Attributes)) + + require.Equal(t, int64(56), smartMdl.Attributes["scsi_grown_defect_list"].(*measurements.SmartScsiAttribute).Value) + require.Equal(t, int64(300357663), smartMdl.Attributes["read_errors_corrected_by_eccfast"].(*measurements.SmartScsiAttribute).Value) //total_errors_corrected +} diff --git a/webapp/backend/pkg/models/setting.go b/webapp/backend/pkg/models/setting.go new file mode 100644 index 0000000..d9a1d6b --- /dev/null +++ b/webapp/backend/pkg/models/setting.go @@ -0,0 +1,5 @@ +package models + +// Temperature Format +// Date Format +// Device History window diff --git a/webapp/backend/pkg/models/testdata/helper.go b/webapp/backend/pkg/models/testdata/helper.go new file mode 100644 index 0000000..771557c --- /dev/null +++ b/webapp/backend/pkg/models/testdata/helper.go @@ -0,0 +1,97 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "time" +) + +func main() { + + //webapp/backend/pkg/web/testdata/register-devices-req.json + devices := "webapp/backend/pkg/web/testdata/register-devices-req.json" + + smartData := map[string][]string{ + "0x5000cca264eb01d7": {"webapp/backend/pkg/models/testdata/smart-ata.json", "webapp/backend/pkg/models/testdata/smart-ata-date.json", "webapp/backend/pkg/models/testdata/smart-ata-date2.json"}, + "0x5000cca264ec3183": {"webapp/backend/pkg/models/testdata/smart-fail2.json"}, + "0x5002538e40a22954": {"webapp/backend/pkg/models/testdata/smart-nvme.json"}, + "0x5000cca252c859cc": {"webapp/backend/pkg/models/testdata/smart-scsi.json"}, + "0x5000cca264ebc248": {"webapp/backend/pkg/models/testdata/smart-scsi2.json"}, + } + + // send a post request to register devices + file, err := os.Open(devices) + if err != nil { + log.Fatalf("ERROR %v", err) + } + defer file.Close() + _, err = SendPostRequest("http://localhost:9090/api/devices/register", file) + if err != nil { + log.Fatalf("ERROR %v", err) + } + // + + for diskId, smartDataFileNames := range smartData { + for _, smartDataFileName := range smartDataFileNames { + for daysToSubtract := 0; daysToSubtract <= 30; daysToSubtract++ { //add 4 weeks worth of data + smartDataReader, err := readSmartDataFileFixTimestamp(daysToSubtract, smartDataFileName) + if err != nil { + log.Fatalf("ERROR %v", err) + } + + _, err = SendPostRequest(fmt.Sprintf("http://localhost:9090/api/device/%s/smart", diskId), smartDataReader) + if err != nil { + log.Fatalf("ERROR %v", err) + } + } + + } + + } + +} + +func SendPostRequest(url string, file io.Reader) ([]byte, error) { + response, err := http.Post(url, "application/json", file) + if err != nil { + return nil, err + } + defer response.Body.Close() + + log.Printf("%v\n", response.Status) + + return ioutil.ReadAll(response.Body) +} + +// InfluxDB will throw an error/ignore any submitted data with a timestamp older than the +// retention period. Lets fix this by opening test files, modifying the timestamp and returning an io.Reader +func readSmartDataFileFixTimestamp(daysToSubtract int, smartDataFilepath string) (io.Reader, error) { + metricsfile, err := os.Open(smartDataFilepath) + if err != nil { + return nil, err + } + + metricsFileData, err := ioutil.ReadAll(metricsfile) + if err != nil { + return nil, err + } + //unmarshal because we need to change the timestamp + var smartData collector.SmartInfo + err = json.Unmarshal(metricsFileData, &smartData) + if err != nil { + return nil, err + } + + daysToSubtractInHours := time.Duration(-1 * 24 * daysToSubtract) + smartData.LocalTime.TimeT = time.Now().Add(daysToSubtractInHours * time.Hour).Unix() + updatedSmartDataBytes, err := json.Marshal(smartData) + + return bytes.NewReader(updatedSmartDataBytes), nil +} diff --git a/webapp/backend/pkg/models/testdata/smart-ata-date.json b/webapp/backend/pkg/models/testdata/smart-ata-date.json new file mode 100644 index 0000000..4e9cf35 --- /dev/null +++ b/webapp/backend/pkg/models/testdata/smart-ata-date.json @@ -0,0 +1,846 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-4.19.128-flatcar", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-j", + "-a", + "/dev/sdb" + ], + "exit_status": 0 + }, + "device": { + "name": "/dev/sdb", + "info_name": "/dev/sdb [SAT]", + "type": "sat", + "protocol": "ATA" + }, + "model_name": "WDC WD140EDFZ-11A0VA0", + "serial_number": "9RK1XXXX", + "wwn": { + "naa": 5, + "oui": 3274, + "id": 10283057623 + }, + "firmware_version": "81.00A81", + "user_capacity": { + "blocks": 27344764928, + "bytes": 14000519643136 + }, + "logical_block_size": 512, + "physical_block_size": 4096, + "rotation_rate": 5400, + "form_factor": { + "ata_value": 2, + "name": "3.5 inches" + }, + "in_smartctl_database": false, + "ata_version": { + "string": "ACS-2, ATA8-ACS T13/1699-D revision 4", + "major_value": 1020, + "minor_value": 41 + }, + "sata_version": { + "string": "SATA 3.2", + "value": 255 + }, + "interface_speed": { + "max": { + "sata_value": 14, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + }, + "current": { + "sata_value": 3, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + } + }, + "local_time": { + "time_t": 1637039918, + "asctime": "Sun Jun 30 00:03:30 2021 UTC" + }, + "smart_status": { + "passed": true + }, + "ata_smart_data": { + "offline_data_collection": { + "status": { + "value": 130, + "string": "was completed without error", + "passed": true + }, + "completion_seconds": 101 + }, + "self_test": { + "status": { + "value": 241, + "string": "in progress, 10% remaining", + "remaining_percent": 10 + }, + "polling_minutes": { + "short": 2, + "extended": 1479 + } + }, + "capabilities": { + "values": [ + 91, + 3 + ], + "exec_offline_immediate_supported": true, + "offline_is_aborted_upon_new_cmd": false, + "offline_surface_scan_supported": true, + "self_tests_supported": true, + "conveyance_self_test_supported": false, + "selective_self_test_supported": true, + "attribute_autosave_enabled": true, + "error_logging_supported": true, + "gp_logging_supported": true + } + }, + "ata_sct_capabilities": { + "value": 61, + "error_recovery_control_supported": true, + "feature_control_supported": true, + "data_table_supported": true + }, + "ata_smart_attributes": { + "revision": 16, + "table": [ + { + "id": 1, + "name": "Raw_Read_Error_Rate", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 11, + "string": "PO-R-- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 2, + "name": "Throughput_Performance", + "value": 135, + "worst": 135, + "thresh": 54, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 108, + "string": "108" + } + }, + { + "id": 3, + "name": "Spin_Up_Time", + "value": 81, + "worst": 81, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 7, + "string": "POS--- ", + "prefailure": true, + "updated_online": true, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 30089675132, + "string": "380 (Average 380)" + } + }, + { + "id": 4, + "name": "Start_Stop_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 9, + "string": "9" + } + }, + { + "id": 5, + "name": "Reallocated_Sector_Ct", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 51, + "string": "PO--CK ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 7, + "name": "Seek_Error_Rate", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 8, + "name": "Seek_Time_Performance", + "value": 133, + "worst": 133, + "thresh": 20, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 18, + "string": "18" + } + }, + { + "id": 9, + "name": "Power_On_Hours", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 1730, + "string": "1730" + } + }, + { + "id": 10, + "name": "Spin_Retry_Count", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 12, + "name": "Power_Cycle_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 9, + "string": "9" + } + }, + { + "id": 22, + "name": "Unknown_Attribute", + "value": 100, + "worst": 100, + "thresh": 25, + "when_failed": "", + "flags": { + "value": 35, + "string": "PO---K ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 100, + "string": "100" + } + }, + { + "id": 192, + "name": "Power-Off_Retract_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 329, + "string": "329" + } + }, + { + "id": 193, + "name": "Load_Cycle_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 329, + "string": "329" + } + }, + { + "id": 194, + "name": "Temperature_Celsius", + "value": 51, + "worst": 51, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 2, + "string": "-O---- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 163210330144, + "string": "32 (Min/Max 24/38)" + } + }, + { + "id": 196, + "name": "Reallocated_Event_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 197, + "name": "Current_Pending_Sector", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 34, + "string": "-O---K ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 198, + "name": "Offline_Uncorrectable", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 8, + "string": "---R-- ", + "prefailure": false, + "updated_online": false, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 199, + "name": "UDMA_CRC_Error_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + } + ] + }, + "power_on_time": { + "hours": 1730 + }, + "power_cycle_count": 9, + "temperature": { + "current": 32 + }, + "ata_smart_error_log": { + "summary": { + "revision": 1, + "count": 0 + } + }, + "ata_smart_self_test_log": { + "standard": { + "revision": 1, + "table": [ + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1708 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1684 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1661 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1636 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1624 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1541 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1517 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1493 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1469 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1445 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1439 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1373 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1349 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1325 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1301 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1277 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1253 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1252 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1205 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1181 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1157 + } + ], + "count": 21, + "error_count_total": 0, + "error_count_outdated": 0 + } + }, + "ata_smart_selective_self_test_log": { + "revision": 1, + "table": [ + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + } + ], + "flags": { + "value": 0, + "remainder_scan_enabled": false + }, + "power_up_scan_resume_minutes": 0 + } +} diff --git a/webapp/backend/pkg/models/testdata/smart-ata-date2.json b/webapp/backend/pkg/models/testdata/smart-ata-date2.json new file mode 100644 index 0000000..5c64623 --- /dev/null +++ b/webapp/backend/pkg/models/testdata/smart-ata-date2.json @@ -0,0 +1,846 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-4.19.128-flatcar", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-j", + "-a", + "/dev/sdb" + ], + "exit_status": 0 + }, + "device": { + "name": "/dev/sdb", + "info_name": "/dev/sdb [SAT]", + "type": "sat", + "protocol": "ATA" + }, + "model_name": "WDC WD140EDFZ-11A0VA0", + "serial_number": "9RK1XXXX", + "wwn": { + "naa": 5, + "oui": 3274, + "id": 10283057623 + }, + "firmware_version": "81.00A81", + "user_capacity": { + "blocks": 27344764928, + "bytes": 14000519643136 + }, + "logical_block_size": 512, + "physical_block_size": 4096, + "rotation_rate": 5400, + "form_factor": { + "ata_value": 2, + "name": "3.5 inches" + }, + "in_smartctl_database": false, + "ata_version": { + "string": "ACS-2, ATA8-ACS T13/1699-D revision 4", + "major_value": 1020, + "minor_value": 41 + }, + "sata_version": { + "string": "SATA 3.2", + "value": 255 + }, + "interface_speed": { + "max": { + "sata_value": 14, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + }, + "current": { + "sata_value": 3, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + } + }, + "local_time": { + "time_t": 1637039918, + "asctime": "Tue Feb 23 00:03:30 2021 UTC" + }, + "smart_status": { + "passed": true + }, + "ata_smart_data": { + "offline_data_collection": { + "status": { + "value": 130, + "string": "was completed without error", + "passed": true + }, + "completion_seconds": 101 + }, + "self_test": { + "status": { + "value": 241, + "string": "in progress, 10% remaining", + "remaining_percent": 10 + }, + "polling_minutes": { + "short": 2, + "extended": 1479 + } + }, + "capabilities": { + "values": [ + 91, + 3 + ], + "exec_offline_immediate_supported": true, + "offline_is_aborted_upon_new_cmd": false, + "offline_surface_scan_supported": true, + "self_tests_supported": true, + "conveyance_self_test_supported": false, + "selective_self_test_supported": true, + "attribute_autosave_enabled": true, + "error_logging_supported": true, + "gp_logging_supported": true + } + }, + "ata_sct_capabilities": { + "value": 61, + "error_recovery_control_supported": true, + "feature_control_supported": true, + "data_table_supported": true + }, + "ata_smart_attributes": { + "revision": 16, + "table": [ + { + "id": 1, + "name": "Raw_Read_Error_Rate", + "value": 90, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 11, + "string": "PO-R-- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 2, + "name": "Throughput_Performance", + "value": 125, + "worst": 135, + "thresh": 54, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 118, + "string": "108" + } + }, + { + "id": 3, + "name": "Spin_Up_Time", + "value": 71, + "worst": 81, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 7, + "string": "POS--- ", + "prefailure": true, + "updated_online": true, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 30089675142, + "string": "380 (Average 380)" + } + }, + { + "id": 4, + "name": "Start_Stop_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 19, + "string": "9" + } + }, + { + "id": 5, + "name": "Reallocated_Sector_Ct", + "value": 90, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 51, + "string": "PO--CK ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 7, + "name": "Seek_Error_Rate", + "value": 90, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 8, + "name": "Seek_Time_Performance", + "value": 123, + "worst": 133, + "thresh": 20, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 28, + "string": "18" + } + }, + { + "id": 9, + "name": "Power_On_Hours", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 1740, + "string": "1730" + } + }, + { + "id": 10, + "name": "Spin_Retry_Count", + "value": 90, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 12, + "name": "Power_Cycle_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 19, + "string": "9" + } + }, + { + "id": 22, + "name": "Unknown_Attribute", + "value": 90, + "worst": 100, + "thresh": 25, + "when_failed": "", + "flags": { + "value": 35, + "string": "PO---K ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 110, + "string": "100" + } + }, + { + "id": 192, + "name": "Power-Off_Retract_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 339, + "string": "329" + } + }, + { + "id": 193, + "name": "Load_Cycle_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 339, + "string": "329" + } + }, + { + "id": 194, + "name": "Temperature_Celsius", + "value": 41, + "worst": 51, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 2, + "string": "-O---- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 163210330154, + "string": "32 (Min/Max 24/38)" + } + }, + { + "id": 196, + "name": "Reallocated_Event_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 197, + "name": "Current_Pending_Sector", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 34, + "string": "-O---K ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 198, + "name": "Offline_Uncorrectable", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 8, + "string": "---R-- ", + "prefailure": false, + "updated_online": false, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 10, + "string": "0" + } + }, + { + "id": 199, + "name": "UDMA_CRC_Error_Count", + "value": 90, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 10, + "string": "0" + } + } + ] + }, + "power_on_time": { + "hours": 3030 + }, + "power_cycle_count": 9, + "temperature": { + "current": 62 + }, + "ata_smart_error_log": { + "summary": { + "revision": 1, + "count": 0 + } + }, + "ata_smart_self_test_log": { + "standard": { + "revision": 1, + "table": [ + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1708 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1684 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1661 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1636 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1624 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1541 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1517 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1493 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1469 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1445 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1439 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1373 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1349 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1325 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1301 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1277 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1253 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1252 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1205 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1181 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1157 + } + ], + "count": 21, + "error_count_total": 0, + "error_count_outdated": 0 + } + }, + "ata_smart_selective_self_test_log": { + "revision": 1, + "table": [ + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + } + ], + "flags": { + "value": 0, + "remainder_scan_enabled": false + }, + "power_up_scan_resume_minutes": 0 + } +} diff --git a/webapp/backend/pkg/models/testdata/smart-ata-full.json b/webapp/backend/pkg/models/testdata/smart-ata-full.json index 82b5250..ad2c195 100644 --- a/webapp/backend/pkg/models/testdata/smart-ata-full.json +++ b/webapp/backend/pkg/models/testdata/smart-ata-full.json @@ -70,7 +70,7 @@ } }, "local_time": { - "time_t": 1600014563, + "time_t": 1637039918, "asctime": "Sun Sep 13 16:29:23 2020 UTC" }, "read_lookahead": { diff --git a/webapp/backend/pkg/models/testdata/smart-ata.json b/webapp/backend/pkg/models/testdata/smart-ata.json index 36ac36b..eebe241 100644 --- a/webapp/backend/pkg/models/testdata/smart-ata.json +++ b/webapp/backend/pkg/models/testdata/smart-ata.json @@ -69,7 +69,7 @@ } }, "local_time": { - "time_t": 1592697810, + "time_t": 1637039918, "asctime": "Sun Jun 21 00:03:30 2020 UTC" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-ata2.json b/webapp/backend/pkg/models/testdata/smart-ata2.json index b981b10..9b03cfd 100644 --- a/webapp/backend/pkg/models/testdata/smart-ata2.json +++ b/webapp/backend/pkg/models/testdata/smart-ata2.json @@ -66,7 +66,7 @@ } }, "local_time": { - "time_t": 1564664713, + "time_t": 1637039918, "asctime": "Thu Aug 01 15:05:13 2019 WEDT" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-fail2.json b/webapp/backend/pkg/models/testdata/smart-fail2.json index 4fbfb88..fe10e17 100644 --- a/webapp/backend/pkg/models/testdata/smart-fail2.json +++ b/webapp/backend/pkg/models/testdata/smart-fail2.json @@ -70,7 +70,7 @@ } }, "local_time": { - "time_t": 1594216103, + "time_t": 1637039918, "asctime": "Wed Jul 8 15:48:23 2020 CEST" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-megaraid0.json b/webapp/backend/pkg/models/testdata/smart-megaraid0.json index 5767206..a848330 100644 --- a/webapp/backend/pkg/models/testdata/smart-megaraid0.json +++ b/webapp/backend/pkg/models/testdata/smart-megaraid0.json @@ -79,7 +79,7 @@ } }, "local_time": { - "time_t": 1598297918, + "time_t": 1637039918, "asctime": "Mon Aug 24 21:38:38 2020 CEST" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-megaraid1.json b/webapp/backend/pkg/models/testdata/smart-megaraid1.json index 04a2af2..958a86a 100644 --- a/webapp/backend/pkg/models/testdata/smart-megaraid1.json +++ b/webapp/backend/pkg/models/testdata/smart-megaraid1.json @@ -79,7 +79,7 @@ } }, "local_time": { - "time_t": 1598297922, + "time_t": 1637039918, "asctime": "Mon Aug 24 21:38:42 2020 CEST" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-nvme.json b/webapp/backend/pkg/models/testdata/smart-nvme.json index c6b6ec8..07937e8 100644 --- a/webapp/backend/pkg/models/testdata/smart-nvme.json +++ b/webapp/backend/pkg/models/testdata/smart-nvme.json @@ -59,7 +59,7 @@ }, "logical_block_size": 512, "local_time": { - "time_t": 1591790462, + "time_t": 1637039918, "asctime": "Wed Jun 10 14:01:02 2020 CEST" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-nvme2.json b/webapp/backend/pkg/models/testdata/smart-nvme2.json index 4f47c1a..8b96836 100644 --- a/webapp/backend/pkg/models/testdata/smart-nvme2.json +++ b/webapp/backend/pkg/models/testdata/smart-nvme2.json @@ -67,7 +67,7 @@ }, "logical_block_size": 512, "local_time": { - "time_t": 1600619090, + "time_t": 1637039918, "asctime": "Sun Sep 20 16:24:50 2020 Europe" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-raid.json b/webapp/backend/pkg/models/testdata/smart-raid.json index 951548d..9fb882f 100644 --- a/webapp/backend/pkg/models/testdata/smart-raid.json +++ b/webapp/backend/pkg/models/testdata/smart-raid.json @@ -43,7 +43,7 @@ "name": "disk" }, "local_time": { - "time_t": 1570609867, + "time_t": 1637039918, "asctime": "Wed Oct 09 10:31:07 2019 RDT" }, "temperature": { diff --git a/webapp/backend/pkg/models/testdata/smart-scsi.json b/webapp/backend/pkg/models/testdata/smart-scsi.json index fe0cfb7..59cd479 100644 --- a/webapp/backend/pkg/models/testdata/smart-scsi.json +++ b/webapp/backend/pkg/models/testdata/smart-scsi.json @@ -26,7 +26,7 @@ "name": "disk" }, "local_time": { - "time_t": 1598048822, + "time_t": 1637039918, "asctime": "Fri Aug 21 22:27:02 2020 UTC" }, "smart_status": { diff --git a/webapp/backend/pkg/models/testdata/smart-scsi2.json b/webapp/backend/pkg/models/testdata/smart-scsi2.json index 26f9470..2cd7601 100644 --- a/webapp/backend/pkg/models/testdata/smart-scsi2.json +++ b/webapp/backend/pkg/models/testdata/smart-scsi2.json @@ -44,7 +44,7 @@ "name": "disk" }, "local_time": { - "time_t": 1545001755, + "time_t": 1637039918, "asctime": "Sun Dec 16 17:09:15 2018 CST" }, "smart_status": { diff --git a/webapp/backend/pkg/notify/notify.go b/webapp/backend/pkg/notify/notify.go index da771a5..5b81464 100644 --- a/webapp/backend/pkg/notify/notify.go +++ b/webapp/backend/pkg/notify/notify.go @@ -258,7 +258,6 @@ func (n *Notify) GenShoutrrrNotificationParams(shoutrrrUrl string) (string, *sho (*params)["title"] = subject case "slack": (*params)["title"] = subject - (*params)["thumb_url"] = logoUrl case "smtp": (*params)["subject"] = subject case "standard": diff --git a/webapp/backend/pkg/metadata/ata_attribute_metadata.go b/webapp/backend/pkg/thresholds/ata_attribute_metadata.go similarity index 98% rename from webapp/backend/pkg/metadata/ata_attribute_metadata.go rename to webapp/backend/pkg/thresholds/ata_attribute_metadata.go index 63dc293..3bd98eb 100644 --- a/webapp/backend/pkg/metadata/ata_attribute_metadata.go +++ b/webapp/backend/pkg/thresholds/ata_attribute_metadata.go @@ -1,4 +1,4 @@ -package metadata +package thresholds const AtaSmartAttributeDisplayTypeRaw = "raw" const AtaSmartAttributeDisplayTypeNormalized = "normalized" @@ -6,15 +6,15 @@ const AtaSmartAttributeDisplayTypeTransformed = "transformed" type AtaAttributeMetadata struct { ID int64 `json:"-"` - DisplayName string `json:"-"` + DisplayName string `json:"display_name"` Ideal string `json:"ideal"` Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - ObservedThresholds []ObservedThreshold `json:"observed_thresholds,omitempty"` //these thresholds must match the DisplayType - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + ObservedThresholds []ObservedThreshold `json:"observed_thresholds,omitempty"` //these thresholds must match the DisplayType + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } const ObservedThresholdIdealLow = "low" @@ -1014,7 +1014,7 @@ var AtaMetadata = map[int]AtaAttributeMetadata{ Ideal: ObservedThresholdIdealLow, Critical: false, Description: "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", - Transform: func(normValue int, rawValue int64, rawString string) int64 { + Transform: func(normValue int64, rawValue int64, rawString string) int64 { return rawValue & 0b11111111 }, TransformValueUnit: "°C", diff --git a/webapp/backend/pkg/metadata/nvme_attribute_metadata.go b/webapp/backend/pkg/thresholds/nvme_attribute_metadata.go similarity index 93% rename from webapp/backend/pkg/metadata/nvme_attribute_metadata.go rename to webapp/backend/pkg/thresholds/nvme_attribute_metadata.go index 2f9f550..ad79988 100644 --- a/webapp/backend/pkg/metadata/nvme_attribute_metadata.go +++ b/webapp/backend/pkg/thresholds/nvme_attribute_metadata.go @@ -1,4 +1,4 @@ -package metadata +package thresholds // https://media.kingston.com/support/downloads/MKP_521.6_SMART-DCP1000_attribute.pdf // https://www.percona.com/blog/2017/02/09/using-nvme-command-line-tools-to-check-nvme-flash-health/ @@ -6,14 +6,14 @@ package metadata // https://www.micromat.com/product_manuals/drive_scope_manual_01.pdf type NvmeAttributeMetadata struct { ID string `json:"-"` - DisplayName string `json:"-"` + DisplayName string `json:"display_name"` Ideal string `json:"ideal"` Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } var NmveMetadata = map[string]NvmeAttributeMetadata{ diff --git a/webapp/backend/pkg/metadata/scsi_attribute_metadata.go b/webapp/backend/pkg/thresholds/scsi_attribute_metadata.go similarity index 57% rename from webapp/backend/pkg/metadata/scsi_attribute_metadata.go rename to webapp/backend/pkg/thresholds/scsi_attribute_metadata.go index 5e83f2a..83437fc 100644 --- a/webapp/backend/pkg/metadata/scsi_attribute_metadata.go +++ b/webapp/backend/pkg/thresholds/scsi_attribute_metadata.go @@ -1,15 +1,15 @@ -package metadata +package thresholds type ScsiAttributeMetadata struct { ID string `json:"-"` - DisplayName string `json:"-"` + DisplayName string `json:"display_name"` Ideal string `json:"ideal"` Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } var ScsiMetadata = map[string]ScsiAttributeMetadata{ @@ -21,96 +21,96 @@ var ScsiMetadata = map[string]ScsiAttributeMetadata{ Critical: true, Description: "", }, - "read.errors_corrected_by_eccfast": { - ID: "read.errors_corrected_by_eccfast", + "read_errors_corrected_by_eccfast": { + ID: "read_errors_corrected_by_eccfast", DisplayName: "Read Errors Corrected by ECC Fast", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.errors_corrected_by_eccdelayed": { - ID: "read.errors_corrected_by_eccdelayed", + "read_errors_corrected_by_eccdelayed": { + ID: "read_errors_corrected_by_eccdelayed", DisplayName: "Read Errors Corrected by ECC Delayed", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.errors_corrected_by_rereads_rewrites": { - ID: "read.errors_corrected_by_rereads_rewrites", + "read_errors_corrected_by_rereads_rewrites": { + ID: "read_errors_corrected_by_rereads_rewrites", DisplayName: "Read Errors Corrected by ReReads/ReWrites", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "read.total_errors_corrected": { - ID: "read.total_errors_corrected", + "read_total_errors_corrected": { + ID: "read_total_errors_corrected", DisplayName: "Read Total Errors Corrected", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.correction_algorithm_invocations": { - ID: "read.correction_algorithm_invocations", + "read_correction_algorithm_invocations": { + ID: "read_correction_algorithm_invocations", DisplayName: "Read Correction Algorithm Invocations", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.total_uncorrected_errors": { - ID: "read.total_uncorrected_errors", + "read_total_uncorrected_errors": { + ID: "read_total_uncorrected_errors", DisplayName: "Read Total Uncorrected Errors", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "write.errors_corrected_by_eccfast": { - ID: "write.errors_corrected_by_eccfast", + "write_errors_corrected_by_eccfast": { + ID: "write_errors_corrected_by_eccfast", DisplayName: "Write Errors Corrected by ECC Fast", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.errors_corrected_by_eccdelayed": { - ID: "write.errors_corrected_by_eccdelayed", + "write_errors_corrected_by_eccdelayed": { + ID: "write_errors_corrected_by_eccdelayed", DisplayName: "Write Errors Corrected by ECC Delayed", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.errors_corrected_by_rereads_rewrites": { - ID: "write.errors_corrected_by_rereads_rewrites", + "write_errors_corrected_by_rereads_rewrites": { + ID: "write_errors_corrected_by_rereads_rewrites", DisplayName: "Write Errors Corrected by ReReads/ReWrites", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "write.total_errors_corrected": { - ID: "write.total_errors_corrected", + "write_total_errors_corrected": { + ID: "write_total_errors_corrected", DisplayName: "Write Total Errors Corrected", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.correction_algorithm_invocations": { - ID: "write.correction_algorithm_invocations", + "write_correction_algorithm_invocations": { + ID: "write_correction_algorithm_invocations", DisplayName: "Write Correction Algorithm Invocations", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.total_uncorrected_errors": { - ID: "write.total_uncorrected_errors", + "write_total_uncorrected_errors": { + ID: "write_total_uncorrected_errors", DisplayName: "Write Total Uncorrected Errors", DisplayType: "", Ideal: "low", diff --git a/webapp/backend/pkg/version/version.go b/webapp/backend/pkg/version/version.go index d2ba094..e68c616 100644 --- a/webapp/backend/pkg/version/version.go +++ b/webapp/backend/pkg/version/version.go @@ -2,4 +2,4 @@ package version // VERSION is the app-global version string, which will be replaced with a // new value during packaging -const VERSION = "0.3.12" +const VERSION = "0.4.0" diff --git a/webapp/backend/pkg/web/handler/get_device_details.go b/webapp/backend/pkg/web/handler/get_device_details.go index 4bee8fc..864b842 100644 --- a/webapp/backend/pkg/web/handler/get_device_details.go +++ b/webapp/backend/pkg/web/handler/get_device_details.go @@ -1,53 +1,44 @@ package handler import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func GetDeviceDetails(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - device := dbModels.Device{} - - if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB { - return db.Order("smarts.created_at DESC").Limit(40) - }). - Preload("SmartResults.AtaAttributes"). - Preload("SmartResults.NvmeAttributes"). - Preload("SmartResults.ScsiAttributes"). - Where("wwn = ?", c.Param("wwn")). - First(&device).Error; err != nil { + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + device, err := deviceRepo.GetDeviceDetails(c, c.Param("wwn")) + if err != nil { logger.Errorln("An error occurred while retrieving device details", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } - if err := device.SquashHistory(); err != nil { - logger.Errorln("An error occurred while squashing device history", err) - c.JSON(http.StatusInternalServerError, gin.H{"success": false}) - return + durationKey, exists := c.GetQuery("duration_key") + if !exists { + durationKey = "forever" } - if err := device.ApplyMetadataRules(); err != nil { - logger.Errorln("An error occurred while applying scrutiny thresholds & rules", err) + smartResults, err := deviceRepo.GetSmartAttributeHistory(c, c.Param("wwn"), durationKey, nil) + if err != nil { + logger.Errorln("An error occurred while retrieving device smart results", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } var deviceMetadata interface{} if device.IsAta() { - deviceMetadata = metadata.AtaMetadata + deviceMetadata = thresholds.AtaMetadata } else if device.IsNvme() { - deviceMetadata = metadata.NmveMetadata + deviceMetadata = thresholds.NmveMetadata } else if device.IsScsi() { - deviceMetadata = metadata.ScsiMetadata + deviceMetadata = thresholds.ScsiMetadata } - c.JSON(http.StatusOK, gin.H{"success": true, "data": device, "metadata": deviceMetadata}) + c.JSON(http.StatusOK, gin.H{"success": true, "data": map[string]interface{}{"device": device, "smart_results": smartResults}, "metadata": deviceMetadata}) } diff --git a/webapp/backend/pkg/web/handler/get_devices_summary.go b/webapp/backend/pkg/web/handler/get_devices_summary.go index b0c9c1c..8eb392f 100644 --- a/webapp/backend/pkg/web/handler/get_devices_summary.go +++ b/webapp/backend/pkg/web/handler/get_devices_summary.go @@ -1,31 +1,28 @@ package handler import ( - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func GetDevicesSummary(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - devices := []dbModels.Device{} + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) - //We need the last x (for now all) Smart objects for each Device, so that we can graph Temperature - //We also need the last - if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB { - return db.Order("smarts.created_at DESC") //OLD: .Limit(devicesCount) - }). - Find(&devices).Error; err != nil { - logger.Errorln("Could not get device summary from DB", err) + summary, err := deviceRepo.GetSummary(c) + if err != nil { + logger.Errorln("An error occurred while retrieving device summary", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } c.JSON(http.StatusOK, gin.H{ "success": true, - "data": devices, + "data": map[string]interface{}{ + "summary": summary, + //"temperature": tem + }, }) } diff --git a/webapp/backend/pkg/web/handler/get_devices_summary_temp_history.go b/webapp/backend/pkg/web/handler/get_devices_summary_temp_history.go new file mode 100644 index 0000000..631b9ec --- /dev/null +++ b/webapp/backend/pkg/web/handler/get_devices_summary_temp_history.go @@ -0,0 +1,32 @@ +package handler + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "net/http" +) + +func GetDevicesSummaryTempHistory(c *gin.Context) { + logger := c.MustGet("LOGGER").(logrus.FieldLogger) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + + durationKey, exists := c.GetQuery("duration_key") + if !exists { + durationKey = "week" + } + + tempHistory, err := deviceRepo.GetSmartTemperatureHistory(c, durationKey) + if err != nil { + logger.Errorln("An error occurred while retrieving summary/temp history", err) + c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "success": true, + "data": map[string]interface{}{ + "temp_history": tempHistory, + }, + }) +} diff --git a/webapp/backend/pkg/web/handler/register_devices.go b/webapp/backend/pkg/web/handler/register_devices.go index 746278a..e1ddf95 100644 --- a/webapp/backend/pkg/web/handler/register_devices.go +++ b/webapp/backend/pkg/web/handler/register_devices.go @@ -1,22 +1,20 @@ package handler import ( - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" "github.com/gin-gonic/gin" - "gorm.io/gorm" - "gorm.io/gorm/clause" - "github.com/sirupsen/logrus" "net/http" ) // register devices that are detected by various collectors. -// This function is run everytime a collector is about to start a run. It can be used to update device data. +// This function is run everytime a collector is about to start a run. It can be used to update device metadata. func RegisterDevices(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - var collectorDeviceWrapper dbModels.DeviceWrapper + var collectorDeviceWrapper models.DeviceWrapper err := c.BindJSON(&collectorDeviceWrapper) if err != nil { logger.Errorln("Cannot parse detected devices", err) @@ -28,11 +26,7 @@ func RegisterDevices(c *gin.Context) { for _, dev := range collectorDeviceWrapper.Data { //insert devices into DB (and update specified columns if device is already registered) // update device fields that may change: (DeviceType, HostID) - if err := db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "wwn"}}, - DoUpdates: clause.AssignmentColumns([]string{"host_id", "device_name", "device_type"}), - }).Create(&dev).Error; err != nil { - + if err := deviceRepo.RegisterDevice(c, dev); err != nil { errs = append(errs, err) } } @@ -44,7 +38,7 @@ func RegisterDevices(c *gin.Context) { }) return } else { - c.JSON(http.StatusOK, dbModels.DeviceWrapper{ + c.JSON(http.StatusOK, models.DeviceWrapper{ Success: true, Data: collectorDeviceWrapper.Data, }) diff --git a/webapp/backend/pkg/web/handler/send_test_notification.go b/webapp/backend/pkg/web/handler/send_test_notification.go index 52ba8f5..07a1d6c 100644 --- a/webapp/backend/pkg/web/handler/send_test_notification.go +++ b/webapp/backend/pkg/web/handler/send_test_notification.go @@ -1,8 +1,9 @@ package handler import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/config" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" "github.com/analogj/scrutiny/webapp/backend/pkg/notify" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" @@ -20,7 +21,7 @@ func SendTestNotification(c *gin.Context) { Payload: notify.Payload{ FailureType: "EmailTest", DeviceSerial: "FAKEWDDJ324KSO", - DeviceType: dbModels.DeviceProtocolAta, + DeviceType: pkg.DeviceProtocolAta, DeviceName: "/dev/sda", Test: true, }, @@ -33,7 +34,7 @@ func SendTestNotification(c *gin.Context) { "errors": []string{err.Error()}, }) } else { - c.JSON(http.StatusOK, dbModels.DeviceWrapper{ + c.JSON(http.StatusOK, models.DeviceWrapper{ Success: true, }) } diff --git a/webapp/backend/pkg/web/handler/upload_device_metrics.go b/webapp/backend/pkg/web/handler/upload_device_metrics.go index 949116a..7a971bd 100644 --- a/webapp/backend/pkg/web/handler/upload_device_metrics.go +++ b/webapp/backend/pkg/web/handler/upload_device_metrics.go @@ -1,20 +1,24 @@ package handler import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" "github.com/analogj/scrutiny/webapp/backend/pkg/notify" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func UploadDeviceMetrics(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) + //db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) appConfig := c.MustGet("CONFIG").(config.Interface) + //influxWriteDb := c.MustGet("INFLUXDB_WRITE").(*api.WriteAPIBlocking) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + + //appConfig := c.MustGet("CONFIG").(config.Interface) var collectorSmartData collector.SmartInfo err := c.BindJSON(&collectorSmartData) @@ -25,39 +29,49 @@ func UploadDeviceMetrics(c *gin.Context) { } //update the device information if necessary - var device dbModels.Device - db.Where("wwn = ?", c.Param("wwn")).First(&device) - device.UpdateFromCollectorSmartInfo(collectorSmartData) - if err := db.Model(&device).Updates(device).Error; err != nil { - logger.Errorln("An error occurred while updating device data from smartctl metrics", err) + updatedDevice, err := deviceRepo.UpdateDevice(c, c.Param("wwn"), collectorSmartData) + if err != nil { + logger.Errorln("An error occurred while updating device data from smartctl metrics:", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } // insert smart info - deviceSmartData := dbModels.Smart{} - err = deviceSmartData.FromCollectorSmartInfo(c.Param("wwn"), collectorSmartData) + smartData, err := deviceRepo.SaveSmartAttributes(c, c.Param("wwn"), collectorSmartData) if err != nil { - logger.Errorln("Could not process SMART metrics", err) + logger.Errorln("An error occurred while saving smartctl metrics", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } - if err := db.Create(&deviceSmartData).Error; err != nil { - logger.Errorln("An error occurred while saving smartctl metrics", err) + + if smartData.Status != pkg.DeviceStatusPassed { + //there is a failure detected by Scrutiny, update the device status on the homepage. + updatedDevice, err = deviceRepo.UpdateDeviceStatus(c, c.Param("wwn"), smartData.Status) + if err != nil { + logger.Errorln("An error occurred while updating device status", err) + c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + return + } + } + + // save smart temperature data (ignore failures) + err = deviceRepo.SaveSmartTemperature(c, c.Param("wwn"), updatedDevice.DeviceProtocol, collectorSmartData) + if err != nil { + logger.Errorln("An error occurred while saving smartctl temp data", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } //check for error - if deviceSmartData.SmartStatus == dbModels.SmartStatusFailed { + if updatedDevice.DeviceStatus != pkg.DeviceStatusPassed { //send notifications testNotify := notify.Notify{ Config: appConfig, Payload: notify.Payload{ FailureType: notify.NotifyFailureTypeSmartFailure, - DeviceName: device.DeviceName, - DeviceType: device.DeviceProtocol, - DeviceSerial: device.SerialNumber, + DeviceName: updatedDevice.DeviceName, + DeviceType: updatedDevice.DeviceProtocol, + DeviceSerial: updatedDevice.SerialNumber, Test: false, }, Logger: logger, diff --git a/webapp/backend/pkg/web/middleware/repository.go b/webapp/backend/pkg/web/middleware/repository.go new file mode 100644 index 0000000..3fe58d2 --- /dev/null +++ b/webapp/backend/pkg/web/middleware/repository.go @@ -0,0 +1,22 @@ +package middleware + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" +) + +func RepositoryMiddleware(appConfig config.Interface, globalLogger logrus.FieldLogger) gin.HandlerFunc { + + deviceRepo, err := database.NewScrutinyRepository(appConfig, globalLogger) + if err != nil { + panic(err) + } + + //TODO: determine where we can call defer deviceRepo.Close() + return func(c *gin.Context) { + c.Set("DEVICE_REPOSITORY", deviceRepo) + c.Next() + } +} diff --git a/webapp/backend/pkg/web/middleware/sqlite3.go b/webapp/backend/pkg/web/middleware/sqlite3.go deleted file mode 100644 index 3eeee13..0000000 --- a/webapp/backend/pkg/web/middleware/sqlite3.go +++ /dev/null @@ -1,59 +0,0 @@ -package middleware - -import ( - "fmt" - "github.com/analogj/scrutiny/webapp/backend/pkg/config" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -func DatabaseMiddleware(appConfig config.Interface, globalLogger logrus.FieldLogger) gin.HandlerFunc { - - //var database *gorm.DB - fmt.Printf("Trying to connect to database stored: %s\n", appConfig.GetString("web.database.location")) - database, err := gorm.Open(sqlite.Open(appConfig.GetString("web.database.location")), &gorm.Config{ - //TODO: figure out how to log database queries again. - //Logger: logger - }) - if err != nil { - panic("Failed to connect to database!") - } - - //database.SetLogger() - database.AutoMigrate(&db.Device{}) - database.AutoMigrate(&db.SelfTest{}) - database.AutoMigrate(&db.Smart{}) - database.AutoMigrate(&db.SmartAtaAttribute{}) - database.AutoMigrate(&db.SmartNvmeAttribute{}) - database.AutoMigrate(&db.SmartScsiAttribute{}) - - //TODO: detrmine where we can call defer database.Close() - return func(c *gin.Context) { - c.Set("DB", database) - c.Next() - } -} - -// GormLogger is a custom logger for Gorm, making it use logrus. -type GormLogger struct{ Logger logrus.FieldLogger } - -// Print handles log events from Gorm for the custom logger. -func (gl *GormLogger) Print(v ...interface{}) { - switch v[0] { - case "sql": - gl.Logger.WithFields( - logrus.Fields{ - "module": "gorm", - "type": "sql", - "rows": v[5], - "src_ref": v[1], - "values": v[4], - }, - ).Debug(v[3]) - case "log": - gl.Logger.WithFields(logrus.Fields{"module": "gorm", "type": "log"}).Print(v[2]) - } -} diff --git a/webapp/backend/pkg/web/server.go b/webapp/backend/pkg/web/server.go index 6bfd99a..cc73d39 100644 --- a/webapp/backend/pkg/web/server.go +++ b/webapp/backend/pkg/web/server.go @@ -23,7 +23,7 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine { r := gin.New() r.Use(middleware.LoggerMiddleware(logger)) - r.Use(middleware.DatabaseMiddleware(ae.Config, logger)) + r.Use(middleware.RepositoryMiddleware(ae.Config, logger)) r.Use(middleware.ConfigMiddleware(ae.Config)) r.Use(gin.Recovery()) @@ -40,11 +40,12 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine { }) api.POST("/health/notify", handler.SendTestNotification) //check if notifications are configured correctly - api.POST("/devices/register", handler.RegisterDevices) //used by Collector to register new devices and retrieve filtered list - api.GET("/summary", handler.GetDevicesSummary) //used by Dashboard - api.POST("/device/:wwn/smart", handler.UploadDeviceMetrics) //used by Collector to upload data - api.POST("/device/:wwn/selftest", handler.UploadDeviceSelfTests) - api.GET("/device/:wwn/details", handler.GetDeviceDetails) //used by Details + api.POST("/devices/register", handler.RegisterDevices) //used by Collector to register new devices and retrieve filtered list + api.GET("/summary", handler.GetDevicesSummary) //used by Dashboard + api.GET("/summary/temp", handler.GetDevicesSummaryTempHistory) //used by Dashboard (Temperature history dropdown) + api.POST("/device/:wwn/smart", handler.UploadDeviceMetrics) //used by Collector to upload data + api.POST("/device/:wwn/selftest", handler.UploadDeviceSelfTests) + api.GET("/device/:wwn/details", handler.GetDeviceDetails) //used by Details } } diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index d7b9086..4daee5e 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -1,14 +1,17 @@ package web_test import ( + "bytes" "encoding/json" - "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" mock_config "github.com/analogj/scrutiny/webapp/backend/pkg/config/mock" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" "github.com/analogj/scrutiny/webapp/backend/pkg/web" "github.com/golang/mock/gomock" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "io" "io/ioutil" "net/http" "net/http/httptest" @@ -16,12 +19,76 @@ import ( "path" "strings" "testing" + "time" ) -const ( - emptyBasePath = "" - notEmptyBasePath = "/basepath" -) +/* +All tests in this file require the existance of a influxDB listening on port 8086 + +docker run --rm -it -p 8086:8086 \ +-e DOCKER_INFLUXDB_INIT_MODE=setup \ +-e DOCKER_INFLUXDB_INIT_USERNAME=admin \ +-e DOCKER_INFLUXDB_INIT_PASSWORD=password12345 \ +-e DOCKER_INFLUXDB_INIT_ORG=scrutiny \ +-e DOCKER_INFLUXDB_INIT_BUCKET=metrics \ +-e DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-auth-token \ +influxdb:2.0 +*/ + +//func TestMain(m *testing.M) { +// setup() +// code := m.Run() +// shutdown() +// os.Exit(code) +//} + +// InfluxDB will throw an error/ignore any submitted data with a timestamp older than the +// retention period. Lets fix this by opening test files, modifying the timestamp and returning an io.Reader +func helperReadSmartDataFileFixTimestamp(t *testing.T, smartDataFilepath string) io.Reader { + metricsfile, err := os.Open(smartDataFilepath) + require.NoError(t, err) + + metricsFileData, err := ioutil.ReadAll(metricsfile) + require.NoError(t, err) + + //unmarshal because we need to change the timestamp + var smartData collector.SmartInfo + err = json.Unmarshal(metricsFileData, &smartData) + require.NoError(t, err) + smartData.LocalTime.TimeT = time.Now().Unix() + updatedSmartDataBytes, err := json.Marshal(smartData) + + return bytes.NewReader(updatedSmartDataBytes) +} + +func TestHealthRoute(t *testing.T) { + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes() + fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes() + + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } + + ae := web.AppEngine{ + Config: fakeConfig, + } + + router := ae.Setup(logrus.New()) var basePathTestCases = []string{ emptyBasePath, @@ -62,145 +129,146 @@ func TestHealthRoute(t *testing.T) { } func TestRegisterDevicesRoute(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func (tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes() - fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes() - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - file, err := os.Open("testdata/register-devices-req.json") - require.NoError(tt, err) - - //test - w := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/devices/register", file) - router.ServeHTTP(w, req) - - //assert - require.Equal(tt, 200, w.Code) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes() + fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + ae := web.AppEngine{ + Config: fakeConfig, } } func TestUploadDeviceMetricsRoute(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - devicesfile, err := os.Open("testdata/register-devices-single-req.json") - require.NoError(tt, err) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - metricsfile, err := os.Open("testdata/upload-device-metrics-req.json") - require.NoError(tt, err) + ae := web.AppEngine{ + Config: fakeConfig, + } + router := ae.Setup(logrus.New()) + devicesfile, err := os.Open("testdata/register-devices-single-req.json") + require.NoError(t, err) - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/devices/register", devicesfile) - router.ServeHTTP(wr, req) - require.Equal(tt, 200, wr.Code) + metricsfile := helperReadSmartDataFileFixTimestamp(t, "testdata/upload-device-metrics-req.json") - mr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5000cca264eb01d7/smart", metricsfile) - router.ServeHTTP(mr, req) - require.Equal(tt, 200, mr.Code) + //test + wr := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) + router.ServeHTTP(wr, req) + require.Equal(t, 200, wr.Code) - //assert + mr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5000cca264eb01d7/smart", metricsfile) + router.ServeHTTP(mr, req) + require.Equal(t, 200, mr.Code) - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) - } + //assert } func TestPopulateMultiple(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - //fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return("testdata/scrutiny_test.db") - fakeConfig.EXPECT().GetStringSlice("notify.urls").Return([]string{}).AnyTimes() - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - devicesfile, err := os.Open("testdata/register-devices-req.json") - require.NoError(tt, err) - - metricsfile, err := os.Open("../models/testdata/smart-ata.json") - require.NoError(tt, err) - failfile, err := os.Open("../models/testdata/smart-fail2.json") - require.NoError(tt, err) - nvmefile, err := os.Open("../models/testdata/smart-nvme.json") - require.NoError(tt, err) - scsifile, err := os.Open("../models/testdata/smart-scsi.json") - require.NoError(tt, err) - scsi2file, err := os.Open("../models/testdata/smart-scsi2.json") - require.NoError(tt, err) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/devices/register", devicesfile) - router.ServeHTTP(wr, req) - require.Equal(tt, 200, wr.Code) - - mr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5000cca264eb01d7/smart", metricsfile) - router.ServeHTTP(mr, req) - require.Equal(tt, 200, mr.Code) - - fr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5000cca264ec3183/smart", failfile) - router.ServeHTTP(fr, req) - require.Equal(tt, 200, fr.Code) - - nr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5002538e40a22954/smart", nvmefile) - router.ServeHTTP(nr, req) - require.Equal(tt, 200, nr.Code) - - sr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5000cca252c859cc/smart", scsifile) - router.ServeHTTP(sr, req) - require.Equal(tt, 200, sr.Code) - - s2r := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/0x5000cca264ebc248/smart", scsi2file) - router.ServeHTTP(s2r, req) - require.Equal(tt, 200, s2r.Code) - - //assert + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + //fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return("testdata/scrutiny_test.db") + fakeConfig.EXPECT().GetStringSlice("notify.urls").Return([]string{}).AnyTimes() + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + ae := web.AppEngine{ + Config: fakeConfig, } + router := ae.Setup(logrus.New()) + devicesfile, err := os.Open("testdata/register-devices-req.json") + require.NoError(t, err) + + metricsfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-ata.json") + failfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-fail2.json") + nvmefile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-nvme.json") + scsifile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-scsi.json") + scsi2file := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-scsi2.json") + + //test + wr := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) + router.ServeHTTP(wr, req) + require.Equal(t, 200, wr.Code) + + mr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5000cca264eb01d7/smart", metricsfile) + router.ServeHTTP(mr, req) + require.Equal(t, 200, mr.Code) + + fr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5000cca264ec3183/smart", failfile) + router.ServeHTTP(fr, req) + require.Equal(t, 200, fr.Code) + + nr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5002538e40a22954/smart", nvmefile) + router.ServeHTTP(nr, req) + require.Equal(t, 200, nr.Code) + + sr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5000cca252c859cc/smart", scsifile) + router.ServeHTTP(sr, req) + require.Equal(t, 200, sr.Code) + + s2r := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/0x5000cca264ebc248/smart", scsi2file) + router.ServeHTTP(s2r, req) + require.Equal(t, 200, s2r.Code) + + //assert } //TODO: this test should use a recorded request/response playback. @@ -229,173 +297,168 @@ func TestPopulateMultiple(t *testing.T) { //} func TestSendTestNotificationRoute_WebhookFailure(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"https://unroutable.domain.example.asdfghj"}) - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/health/notify", strings.NewReader("{}")) - router.ServeHTTP(wr, req) - - //assert - require.Equal(tt, 500, wr.Code) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"https://unroutable.domain.example.asdfghj"}) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + ae := web.AppEngine{ + Config: fakeConfig, } } func TestSendTestNotificationRoute_ScriptFailure(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///missing/path/on/disk"}) - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/health/notify", strings.NewReader("{}")) - router.ServeHTTP(wr, req) - - //assert - require.Equal(tt, 500, wr.Code) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///missing/path/on/disk"}) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + ae := web.AppEngine{ + Config: fakeConfig, } } func TestSendTestNotificationRoute_ScriptSuccess(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - //setup - parentPath, _ := ioutil.TempDir("", "") - defer os.RemoveAll(parentPath) - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///usr/bin/env"}) - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/health/notify", strings.NewReader("{}")) - router.ServeHTTP(wr, req) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///usr/bin/env"}) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - //assert - require.Equal(t, 200, wr.Code) - }) + ae := web.AppEngine{ + Config: fakeConfig, } } func TestSendTestNotificationRoute_ShoutrrrFailure(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"discord://invalidtoken@channel"}) - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/health/notify", strings.NewReader("{}")) - router.ServeHTTP(wr, req) - - //assert - require.Equal(tt, 500, wr.Code) - - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"discord://invalidtoken@channel"}) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } + ae := web.AppEngine{ + Config: fakeConfig, } } func TestGetDevicesSummaryRoute_Nvme(t *testing.T) { - for _, basePath := range basePathTestCases { - t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func(tt *testing.T) { - //setup - parentPath, _ := ioutil.TempDir("", "") - mockCtrl := gomock.NewController(tt) - fakeConfig := mock_config.NewMockInterface(mockCtrl) - fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) - fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) - fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes() - ae := web.AppEngine{ - Config: fakeConfig, - } - router := ae.Setup(logrus.New()) - devicesfile, err := os.Open("testdata/register-devices-req-2.json") - require.NoError(tt, err) - - metricsfile, err := os.Open("../models/testdata/smart-nvme2.json") - require.NoError(tt, err) - - //test - wr := httptest.NewRecorder() - req, _ := http.NewRequest("POST", basePath + "/api/devices/register", devicesfile) - router.ServeHTTP(wr, req) - require.Equal(tt, 200, wr.Code) - - mr := httptest.NewRecorder() - req, _ = http.NewRequest("POST", basePath + "/api/device/a4c8e8ed-11a0-4c97-9bba-306440f1b944/smart", metricsfile) - router.ServeHTTP(mr, req) - require.Equal(tt, 200, mr.Code) - - sr := httptest.NewRecorder() - req, _ = http.NewRequest("GET", basePath + "/api/summary", nil) - router.ServeHTTP(sr, req) - require.Equal(t, 200, sr.Code) - var device dbModels.DeviceWrapper - json.Unmarshal(sr.Body.Bytes(), &device) - - //assert - require.Equal(tt, "a4c8e8ed-11a0-4c97-9bba-306440f1b944", device.Data[0].WWN) - require.Equal(tt, "passed", device.Data[0].SmartResults[0].SmartStatus) + //setup + parentPath, _ := ioutil.TempDir("", "") + defer os.RemoveAll(parentPath) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) + fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) + fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() + fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes() + fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() + fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() + fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{}) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { + // when running test suite in github actions, we run an influxdb service as a sidecar. + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() + } else { + fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() + } - // tear down - mockCtrl.Finish() - os.RemoveAll(parentPath) - }) + ae := web.AppEngine{ + Config: fakeConfig, } + router := ae.Setup(logrus.New()) + devicesfile, err := os.Open("testdata/register-devices-req-2.json") + require.NoError(t, err) + + metricsfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-nvme2.json") + + //test + wr := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) + router.ServeHTTP(wr, req) + require.Equal(t, 200, wr.Code) + + mr := httptest.NewRecorder() + req, _ = http.NewRequest("POST", "/api/device/a4c8e8ed-11a0-4c97-9bba-306440f1b944/smart", metricsfile) + router.ServeHTTP(mr, req) + require.Equal(t, 200, mr.Code) + + sr := httptest.NewRecorder() + req, _ = http.NewRequest("GET", "/api/summary", nil) + router.ServeHTTP(sr, req) + require.Equal(t, 200, sr.Code) + var deviceSummary models.DeviceSummaryWrapper + err = json.Unmarshal(sr.Body.Bytes(), &deviceSummary) + require.NoError(t, err) + + //assert + require.Equal(t, "a4c8e8ed-11a0-4c97-9bba-306440f1b944", deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.WWN) + require.Equal(t, pkg.DeviceStatusFailedScrutiny, deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.DeviceStatus) } diff --git a/webapp/frontend/package-lock.json b/webapp/frontend/package-lock.json index f2ac183..cae08a9 100644 --- a/webapp/frontend/package-lock.json +++ b/webapp/frontend/package-lock.json @@ -1,8 +1,18345 @@ { "name": "@treo/starter", "version": "1.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@treo/starter", + "version": "1.0.1", + "license": "https://themeforest.net/licenses/standard", + "dependencies": { + "@angular/animations": "9.1.4", + "@angular/cdk": "9.2.2", + "@angular/common": "9.1.4", + "@angular/compiler": "9.1.4", + "@angular/core": "9.1.4", + "@angular/forms": "9.1.4", + "@angular/material": "9.2.2", + "@angular/material-moment-adapter": "9.2.2", + "@angular/platform-browser": "9.1.4", + "@angular/platform-browser-dynamic": "9.1.4", + "@angular/router": "9.1.4", + "@fullcalendar/angular": "4.4.5-beta", + "@fullcalendar/core": "4.4.0", + "@fullcalendar/daygrid": "4.4.0", + "@fullcalendar/interaction": "4.4.0", + "@fullcalendar/list": "4.4.0", + "@fullcalendar/moment": "4.4.0", + "@fullcalendar/rrule": "4.4.0", + "@fullcalendar/timegrid": "4.4.0", + "@types/humanize-duration": "^3.18.1", + "apexcharts": "3.19.0", + "crypto-js": "3.3.0", + "highlight.js": "10.0.1", + "humanize-duration": "^3.24.0", + "lodash": "4.17.15", + "moment": "2.24.0", + "ng-apexcharts": "1.2.3", + "ngx-markdown": "9.0.0", + "ngx-quill": "9.1.0", + "perfect-scrollbar": "1.5.0", + "quill": "1.3.7", + "rrule": "2.6.4", + "rxjs": "6.5.5", + "tslib": "1.11.1", + "web-animations-js": "2.3.2", + "zone.js": "0.10.3" + }, + "devDependencies": { + "@angular-devkit/build-angular": "0.901.4", + "@angular/cli": "9.1.4", + "@angular/compiler-cli": "9.1.4", + "@angular/language-service": "9.1.4", + "@types/crypto-js": "3.1.45", + "@types/highlight.js": "9.12.3", + "@types/jasmine": "3.5.10", + "@types/jasminewd2": "2.0.8", + "@types/lodash": "4.14.150", + "@types/node": "12.12.37", + "codelyzer": "5.2.2", + "jasmine-core": "3.5.0", + "jasmine-spec-reporter": "4.2.1", + "karma": "5.0.4", + "karma-chrome-launcher": "3.1.0", + "karma-coverage-istanbul-reporter": "2.1.1", + "karma-jasmine": "3.0.3", + "karma-jasmine-html-reporter": "1.5.3", + "protractor": "5.4.4", + "tailwindcss": "1.4.4", + "ts-node": "8.3.0", + "tslint": "6.1.2", + "typescript": "3.8.3" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.901.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.4.tgz", + "integrity": "sha512-w4RMj7eLhUSh70HUy5tW4EXjLQFXk0Lfr9WiSy5gvPGp+zzYxknI+Wn4Xid1wU/WS+4tuMv5nJIaNaH2sABESQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "9.1.4", + "rxjs": "6.5.4" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "0.901.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.4.tgz", + "integrity": "sha512-Vod4bc6d38fuvqauIDQxKMe9hKW9m4QNzPKxEc+Dv5Xkv95WaGzkbUVu8M8t4E//sDDMpmcPdYOXSdR27WBi2Q==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.901.4", + "@angular-devkit/build-optimizer": "0.901.4", + "@angular-devkit/build-webpack": "0.901.4", + "@angular-devkit/core": "9.1.4", + "@babel/core": "7.9.0", + "@babel/generator": "7.9.3", + "@babel/preset-env": "7.9.0", + "@babel/template": "7.8.6", + "@jsdevtools/coverage-istanbul-loader": "3.0.3", + "@ngtools/webpack": "9.1.4", + "ajv": "6.12.0", + "autoprefixer": "9.7.4", + "babel-loader": "8.0.6", + "browserslist": "^4.9.1", + "cacache": "15.0.0", + "caniuse-lite": "^1.0.30001032", + "circular-dependency-plugin": "5.2.0", + "copy-webpack-plugin": "5.1.1", + "core-js": "3.6.4", + "css-loader": "3.5.1", + "cssnano": "4.1.10", + "file-loader": "6.0.0", + "find-cache-dir": "3.3.1", + "glob": "7.1.6", + "jest-worker": "25.1.0", + "karma-source-map-support": "1.4.0", + "less": "3.11.1", + "less-loader": "5.0.0", + "license-webpack-plugin": "2.1.4", + "loader-utils": "2.0.0", + "mini-css-extract-plugin": "0.9.0", + "minimatch": "3.0.4", + "open": "7.0.3", + "parse5": "4.0.0", + "postcss": "7.0.27", + "postcss-import": "12.0.1", + "postcss-loader": "3.0.0", + "raw-loader": "4.0.0", + "regenerator-runtime": "0.13.5", + "rimraf": "3.0.2", + "rollup": "2.1.0", + "rxjs": "6.5.4", + "sass": "1.26.3", + "sass-loader": "8.0.2", + "semver": "7.1.3", + "source-map": "0.7.3", + "source-map-loader": "0.2.4", + "speed-measure-webpack-plugin": "1.3.1", + "style-loader": "1.1.3", + "stylus": "0.54.7", + "stylus-loader": "3.0.2", + "terser": "4.6.10", + "terser-webpack-plugin": "2.3.5", + "tree-kill": "1.2.2", + "webpack": "4.42.0", + "webpack-dev-middleware": "3.7.2", + "webpack-dev-server": "3.10.3", + "webpack-merge": "4.2.2", + "webpack-sources": "1.4.3", + "webpack-subresource-integrity": "1.4.0", + "worker-plugin": "4.0.2" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": ">=9.0.0 < 10", + "typescript": ">=3.6 < 3.9" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/generator": { + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", + "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-optimizer": { + "version": "0.901.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.4.tgz", + "integrity": "sha512-iDMlNRwd8ICMBKnycfw55hdnL5kCiqUjQn+aK/4uOMJMz49tiYMNJAaznXX2BFKmYSmbapKjEbzx9yMYRi9Y7w==", + "dev": true, + "dependencies": { + "loader-utils": "2.0.0", + "source-map": "0.7.3", + "tslib": "1.11.1", + "typescript": "3.6.5", + "webpack-sources": "1.4.3" + }, + "bin": { + "build-optimizer": "src/build-optimizer/cli.js" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-optimizer/node_modules/typescript": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.5.tgz", + "integrity": "sha512-BEjlc0Z06ORZKbtcxGrIvvwYs5hAnuo6TKdNFL55frVDlB+na3z5bsLhFaIxmT+dPWgBIjMo6aNnTOgHHmHgiQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.901.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.4.tgz", + "integrity": "sha512-YBOufI4TGAtIDCS6erFygYJX/fkd8xwI58d+7iFIBmtIJC4/fpGjX6qkHMCBgh8HXAkEPSORBCYQn9O44J1ZXQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.901.4", + "@angular-devkit/core": "9.1.4", + "rxjs": "6.5.4" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^4.6.0", + "webpack-dev-server": "^3.1.4" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.4.tgz", + "integrity": "sha512-OPFQDmT4XabLMSRDgmnzedlOrc83DzQIgLcfoh/UhZ7aJKf/2Vq4l09p/DkMNI36vN5BRL0zDZt7TjvKNgyYgA==", + "dev": true, + "dependencies": { + "ajv": "6.12.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.5.4", + "source-map": "0.7.3" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.4.tgz", + "integrity": "sha512-RAbdnUEZ3JTLmWSBiXT5trsVx8Fi72fxN9CiRaluM09Cytg6BUc1wC5XCO0YPvhI400+3Ro1nwjPXezjg7LXzQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "9.1.4", + "ora": "4.0.3", + "rxjs": "6.5.4" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular/animations": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.4.tgz", + "integrity": "sha512-gMo/DbCm5BDArladMAeC7/75T2DvhLr4CSUGJt/P/aimTEG2ywoAALs3pzwSSe4qxrHiR0OIksVW3l4km3iXEw==", + "peerDependencies": { + "@angular/core": "9.1.4", + "tslib": "^1.10.0" + } + }, + "node_modules/@angular/cdk": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.2.tgz", + "integrity": "sha512-VNd+KuMN6cBcy4/8OyMxqYaxdjPP6IyCqIVijB2JREkc5Sg4VWmPgx2L3rHt/DzjsVBVRgx35uqOMymDezG3jQ==", + "optionalDependencies": { + "parse5": "^5.0.0" + }, + "peerDependencies": { + "@angular/common": "^9.0.0 || ^10.0.0-0", + "@angular/core": "^9.0.0 || ^10.0.0-0", + "tslib": "^1.9.0" + } + }, + "node_modules/@angular/cli": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-9.1.4.tgz", + "integrity": "sha512-H9MqoT4zyIv+Yo3cvRVkzafWGHsqt7jUvtvGwMHIDMTfEX+Q8yiYlDLL6WM3Eb6/hDmLcRGC/GI495sKS1z5qA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@angular-devkit/architect": "0.901.4", + "@angular-devkit/core": "9.1.4", + "@angular-devkit/schematics": "9.1.4", + "@schematics/angular": "9.1.4", + "@schematics/update": "0.901.4", + "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "4.1.1", + "debug": "4.1.1", + "ini": "1.3.5", + "inquirer": "7.1.0", + "npm-package-arg": "8.0.1", + "npm-pick-manifest": "6.0.0", + "open": "7.0.3", + "pacote": "9.5.12", + "read-package-tree": "5.3.1", + "rimraf": "3.0.2", + "semver": "7.1.3", + "symbol-observable": "1.2.0", + "universal-analytics": "0.4.20", + "uuid": "7.0.2" + }, + "bin": { + "ng": "bin/ng" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cli/node_modules/uuid": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", + "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@angular/common": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.4.tgz", + "integrity": "sha512-JvCoCWVbx0tF7l/0WTi24ui/mc2SElyVSNchR4VK/FViARnkvnSBdI/Ef5QWXrsPyKU4PYBtnWWgyxRspH+FBA==", + "peerDependencies": { + "@angular/core": "9.1.4", + "rxjs": "^6.5.3", + "tslib": "^1.10.0" + } + }, + "node_modules/@angular/compiler": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.4.tgz", + "integrity": "sha512-B+f3lviFNEJtL9V9exSKYPSz2Ddb6dxgPzQR7GSjGikDo+fKMtC1PjNwgJooS9gavhQx30uwkEEMIPYQbM6nNA==", + "peerDependencies": { + "tslib": "^1.10.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-9.1.4.tgz", + "integrity": "sha512-n3PzqNnPD7s/AF9mv5CnarK0sgfoq4txFncHjJWBSltuTQoz6BDZyjuEdqsSLUvgAZPeLsmohemOzEE38HYHZA==", + "dev": true, + "dependencies": { + "canonical-path": "1.0.0", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "dependency-graph": "^0.7.2", + "fs-extra": "4.0.2", + "magic-string": "^0.25.0", + "minimist": "^1.2.0", + "reflect-metadata": "^0.1.2", + "semver": "^6.3.0", + "source-map": "^0.6.1", + "sourcemap-codec": "^1.4.8", + "yargs": "15.3.0" + }, + "bin": { + "ivy-ngcc": "ngcc/main-ivy-ngcc.js", + "ng-xi18n": "src/extract_i18n.js", + "ngc": "src/main.js", + "ngcc": "ngcc/main-ngcc.js" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "@angular/compiler": "9.1.4", + "tslib": "^1.10.0", + "typescript": ">=3.6 <3.9" + } + }, + "node_modules/@angular/compiler-cli/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/compiler-cli/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/@angular/compiler-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@angular/compiler-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@angular/compiler-cli/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/@angular/compiler-cli/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/compiler-cli/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@angular/compiler-cli/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/@angular/compiler-cli/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/@angular/compiler-cli/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", + "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@angular/core": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.4.tgz", + "integrity": "sha512-ND240vncmVD2KVe/KSQU3d/DxxoRipFg1+jFOFZGt0n0orCBHk/V1fu9iaG1sRyldL0+rCQ+fTI+1N4DTmMnxA==", + "peerDependencies": { + "rxjs": "^6.5.3", + "tslib": "^1.10.0", + "zone.js": "~0.10.3" + } + }, + "node_modules/@angular/forms": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.4.tgz", + "integrity": "sha512-Njt+pMLfPBchL0/ayIjJqXL6ZfM4Ccvf7KO1wS1HMzh3QlmfNa0JSgc4pfrbRJAMN9g7V/FYLyKejs1bJZkenA==", + "peerDependencies": { + "@angular/common": "9.1.4", + "@angular/core": "9.1.4", + "@angular/platform-browser": "9.1.4", + "rxjs": "^6.5.3", + "tslib": "^1.10.0" + } + }, + "node_modules/@angular/language-service": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-9.1.4.tgz", + "integrity": "sha512-eyVxxiegdb4ESdFGfkuDN+YfUbOVHRQLjIl6ACFJQDNHzVXzbmuqpyr5hIJANIVady103/7+dqRxxJo1DdIdTQ==", + "dev": true + }, + "node_modules/@angular/material": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.2.tgz", + "integrity": "sha512-gdQiMJ6PtW/5fd+0mglHFyzxULDCBGjn9RTET3sUq2rkc9+jBXr4OvnsUyBWSnqqv97XqotVDIx5JgE4/YX/Rw==", + "peerDependencies": { + "@angular/animations": "^9.0.0 || ^10.0.0-0", + "@angular/cdk": "9.2.2", + "@angular/common": "^9.0.0 || ^10.0.0-0", + "@angular/core": "^9.0.0 || ^10.0.0-0", + "@angular/forms": "^9.0.0 || ^10.0.0-0", + "tslib": "^1.9.0" + } + }, + "node_modules/@angular/material-moment-adapter": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-9.2.2.tgz", + "integrity": "sha512-hijj2VVC7Oy9XGVYE+FsdI521w/9v453jP2VUH+CCRoeoCopdNS+dh1vacSAGf21UXwH9LJ5E6kI9RsmfwF/Ig==", + "peerDependencies": { + "@angular/core": "^9.0.0 || ^10.0.0-0", + "@angular/material": "9.2.2", + "moment": "^2.18.1", + "tslib": "^1.9.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.4.tgz", + "integrity": "sha512-mBCHfTl+5tQfaUiGlDujP7mFBzovFc54Zi2kcCE8DSdSSVQ2TPBo6hXa6y2cL3hJPFZzQ7mC4ORFrsGADhHn/w==", + "peerDependencies": { + "@angular/animations": "9.1.4", + "@angular/common": "9.1.4", + "@angular/core": "9.1.4", + "tslib": "^1.10.0" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.4.tgz", + "integrity": "sha512-YtVbnxyS6FU7xNpA6A95tmSfrB8+WC7OH3mbP8M9NaGk0OYz8B/JOe1HByP4JRpEGCvBtXdJ2NSW/MpLIT8SiQ==", + "peerDependencies": { + "@angular/common": "9.1.4", + "@angular/compiler": "9.1.4", + "@angular/core": "9.1.4", + "@angular/platform-browser": "9.1.4", + "tslib": "^1.10.0" + } + }, + "node_modules/@angular/router": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.4.tgz", + "integrity": "sha512-yUyjCgG2P2Jh8MvoyC6yirmAtx1Qe7MKLuLvsa9WOB571QNEcNLTYMfAMHUKsQTcE/+o984QyLlneoibgI9wFA==", + "peerDependencies": { + "@angular/common": "9.1.4", + "@angular/core": "9.1.4", + "@angular/platform-browser": "9.1.4", + "rxjs": "^6.5.3", + "tslib": "^1.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.8.3" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz", + "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==", + "dev": true, + "dependencies": { + "browserslist": "^4.11.1", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "node_modules/@babel/compat-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", + "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.7.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz", + "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.9.6", + "browserslist": "^4.11.1", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "node_modules/@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/helpers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz", + "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.9.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.8.8", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", + "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", + "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz", + "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz", + "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz", + "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", + "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", + "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.9.0", + "@babel/helper-compilation-targets": "^7.8.7", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.9.0", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.9.0", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.0", + "@babel/plugin-transform-modules-systemjs": "^7.9.0", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.7", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.0", + "browserslist": "^4.9.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", + "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "node_modules/@babel/traverse": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", + "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/traverse/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/types": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.0", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@fullcalendar/angular": { + "version": "4.4.5-beta", + "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-4.4.5-beta.tgz", + "integrity": "sha512-L144YrgrgFr75/LGNcDDX9xKy465AZR/EqWPxkdNFgBSeeblH+kf8OMy8K6YcuJDlv4nXw4RucBqbMrrQKvbQw==", + "dependencies": { + "@fullcalendar/core": "~4.4.0", + "fast-deep-equal": "^3.1.1" + }, + "engines": { + "node": ">= 6.9.0", + "npm": ">= 3.0.0" + }, + "peerDependencies": { + "@angular/common": "^9.0.0", + "@angular/core": "^9.0.0", + "tslib": "^1.10.0" + } + }, + "node_modules/@fullcalendar/core": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-4.4.0.tgz", + "integrity": "sha512-PC4mmXHJHAlXmUEmZVnePyA8yYCOBdxBNq8yjJqedEtT1X0x36yTFz/Y0Ux6bniICZDqYtk0xoxe6jaxi++e0g==" + }, + "node_modules/@fullcalendar/daygrid": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-4.4.0.tgz", + "integrity": "sha512-pDfvL0XZxKHTZ4VFOmwaYe3LmuABEIZsEopeqQ8y5O6BDen9KCbJqgHeCI8FpASSBd6bNlUx7il7EHdSoHhgIw==", + "peerDependencies": { + "@fullcalendar/core": "~4.4.0" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-4.4.0.tgz", + "integrity": "sha512-nGu0ZzYYlNpIhqfyv3JupteWKFETs3W1MzbRJcEZkuPncn4BooEi4A2blgHfacHAmmpaNkT84tAmhzi734MFBA==", + "peerDependencies": { + "@fullcalendar/core": "~4.4.0" + } + }, + "node_modules/@fullcalendar/list": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-4.4.0.tgz", + "integrity": "sha512-uUDSPS71czNTK5Z3x3HzeE3KIvqkCfvhY+mGFdaAL6+7VpCwEIfB6s3GIJOjzu9TONmczMk4jdq0b1WUFLY5PQ==", + "peerDependencies": { + "@fullcalendar/core": "~4.4.0" + } + }, + "node_modules/@fullcalendar/moment": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/moment/-/moment-4.4.0.tgz", + "integrity": "sha512-sW2F7z0E1+kBvBduGiXVYJtIWj2AWeUQQoiLA+xgprsyljzigwnI+9J2iviaB9uL7LIbCSnPrOZmhpVTufmPvQ==", + "peerDependencies": { + "@fullcalendar/core": "~4.4.0", + "moment": "^2.24.0" + } + }, + "node_modules/@fullcalendar/rrule": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/rrule/-/rrule-4.4.0.tgz", + "integrity": "sha512-pXe3kSShg9CQ5gr0J0IGMYAwVlBv6j9yotRfJUrCY7xUWNkqTLAmburW7Q7KNlDMOLuiFbM/twBYZYiIjjTWpg==", + "peerDependencies": { + "@fullcalendar/core": "~4.4.0", + "rrule": "^2.6.0" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-4.4.0.tgz", + "integrity": "sha512-QwJ9oM87/ZTbXaE8PMIVp20GPtVCFmroaeR1GydJ6BKYtbxG/nsaSv7RhqvDa2jLjHaTWC2NjHo9hRfjQjtCZA==", + "dependencies": { + "@fullcalendar/daygrid": "~4.4.0" + }, + "peerDependencies": { + "@fullcalendar/core": "~4.4.0" + } + }, + "node_modules/@fullhuman/postcss-purgecss": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.1.2.tgz", + "integrity": "sha512-Jf34YVBK9GtXTblpu0svNUJdA7rTQoRMz+yEJe6mwTnXDIGipWLzaX/VgU/x6IPC6WvU5SY/XlawwqhxoyFPTg==", + "dev": true, + "dependencies": { + "postcss": "7.0.27", + "purgecss": "^2.1.2" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jsdevtools/coverage-istanbul-loader": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.3.tgz", + "integrity": "sha512-TAdNkeGB5Fe4Og+ZkAr1Kvn9by2sfL44IAHFtxlh1BA1XJ5cLpO9iSNki5opWESv3l3vSHsZ9BNKuqFKbEbFaA==", + "dev": true, + "dependencies": { + "convert-source-map": "^1.7.0", + "istanbul-lib-instrument": "^4.0.1", + "loader-utils": "^1.4.0", + "merge-source-map": "^1.1.0", + "schema-utils": "^2.6.4" + } + }, + "node_modules/@jsdevtools/coverage-istanbul-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/@jsdevtools/coverage-istanbul-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@ngtools/webpack": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.4.tgz", + "integrity": "sha512-CDlQzMnWraxf/dT3G5L+0N0VniWHWdzjLRP8pWBoyV0xlzWS1yL/lj8Mas2jEIuaUxZ8bi29mE7xa8prqewtBQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "9.1.4", + "enhanced-resolve": "4.1.1", + "rxjs": "6.5.4", + "webpack-sources": "1.4.3" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": ">=9.0.0 < 10", + "typescript": ">=3.6 < 3.9", + "webpack": "^4.0.0" + } + }, + "node_modules/@ngtools/webpack/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@schematics/angular": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-9.1.4.tgz", + "integrity": "sha512-7nbiYBRgXc+f0sa5iXTcF6/VMy/Xq0wyKKnDFiLCb2aFYR7EXRHWF2GuwDIg2bvFugLuCBDoNnXeddLE1TXGWg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "9.1.4", + "@angular-devkit/schematics": "9.1.4" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/update": { + "version": "0.901.4", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.901.4.tgz", + "integrity": "sha512-jCtZY2Fbj502gKN5gdu1brnRy/ssyzTrWm69Ty73V+t8uL7nLr+/hny/VBJ8CiQnKQvxcgVl1xgvI1cXzpysVA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "9.1.4", + "@angular-devkit/schematics": "9.1.4", + "@yarnpkg/lockfile": "1.1.0", + "ini": "1.3.5", + "npm-package-arg": "^8.0.0", + "pacote": "9.5.12", + "rxjs": "6.5.4", + "semver": "7.1.3", + "semver-intersect": "1.4.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 6.11.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/update/node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@schematics/update/node_modules/semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "node_modules/@types/crypto-js": { + "version": "3.1.45", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.45.tgz", + "integrity": "sha512-/4yiILxQnVfpAtrVctuEl0qwqAToqayoPEvutyWhHPslr2D9sx85KRmIq7etC0ZYKCK8ppucoLzJukjJdAtfdA==", + "dev": true + }, + "node_modules/@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "node_modules/@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "dependencies": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/highlight.js": { + "version": "9.12.3", + "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", + "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==", + "dev": true + }, + "node_modules/@types/humanize-duration": { + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.1.tgz", + "integrity": "sha512-MUgbY3CF7hg/a/jogixmAufLjJBQT7WEf8Q+kYJkOc47ytngg1IuZobCngdTjAgY83JWEogippge5O5fplaQlw==" + }, + "node_modules/@types/jasmine": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.5.10.tgz", + "integrity": "sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew==", + "dev": true + }, + "node_modules/@types/jasminewd2": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.8.tgz", + "integrity": "sha512-d9p31r7Nxk0ZH0U39PTH0hiDlJ+qNVGjlt1ucOoTUptxb2v+Y5VMnsxfwN+i3hK4yQnqBi3FMmoMFcd1JHDxdg==", + "dev": true, + "dependencies": { + "@types/jasmine": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.150", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.150.tgz", + "integrity": "sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w==", + "dev": true + }, + "node_modules/@types/marked": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.7.3.tgz", + "integrity": "sha512-WXdEKuT3azHxLTThd5dwnpLt2Q9QiC8iKj09KZRtVqro3pX8hhY+GbD8FZOae6SBBEJ22yKJn3c7ejL0aucAcA==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.12.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz", + "integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg==", + "dev": true + }, + "node_modules/@types/q": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "dev": true + }, + "node_modules/@types/selenium-webdriver": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.17.tgz", + "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", + "dev": true + }, + "node_modules/@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "node_modules/@types/webpack-sources": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", + "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.6.1" + } + }, + "node_modules/@types/webpack-sources/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/@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz", + "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "dev": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "dependencies": { + "type-fest": "^0.11.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apexcharts": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.19.0.tgz", + "integrity": "sha512-fzupCGVDvOoU6kEzguLAfgRgrlHynHM5fnkkyCL85tYf9U8bw1hCijs4A+kWXurC/SNytJrArBc21kA/2wuHYg==", + "dependencies": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + }, + "funding": { + "url": "https://github.com/apexcharts/apexcharts.js?sponsor=1" + } + }, + "node_modules/app-root-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", + "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "dependencies": { + "default-require-extensions": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "dependencies": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", + "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", + "dev": true, + "dependencies": { + "browserslist": "^4.8.3", + "caniuse-lite": "^1.0.30001020", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.26", + "postcss-value-parser": "^4.0.2" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true + }, + "node_modules/axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "dependencies": { + "ast-types-flow": "0.0.7" + } + }, + "node_modules/babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "dev": true, + "dependencies": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" + }, + "engines": { + "node": ">= 6.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/babel-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/babel-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "node_modules/base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "dependencies": { + "callsite": "1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "node_modules/blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "blocking-proxy": "built/lib/bin.js" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + }, + "node_modules/browserstack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.0.tgz", + "integrity": "sha512-HJDJ0TSlmkwnt9RZ+v5gFpa1XZTBYTj0ywvLwJ3241J7vMw2jAsGNVhKHtmCOyg+VxeLZyaibO9UL71AsUeDIw==", + "dev": true, + "dependencies": { + "https-proxy-agent": "^2.2.1" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.0.tgz", + "integrity": "sha512-L0JpXHhplbJSiDGzyJJnJCTL7er7NzbBgxzVqLswEb4bO91Zbv17OUMuUeu/q0ZwKn3V+1HM4wb9tO4eVE/K8g==", + "dev": true, + "dependencies": { + "chownr": "^1.1.2", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^2.7.1", + "ssri": "^8.0.0", + "tar": "^6.0.1", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001048", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz", + "integrity": "sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg==", + "dev": true + }, + "node_modules/canonical-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", + "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", + "dev": true + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circular-dependency-plugin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", + "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "webpack": ">=4.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", + "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/clipboard": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "optional": true, + "dependencies": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "node_modules/cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "dependencies": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/codelyzer": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.2.2.tgz", + "integrity": "sha512-jB4FZ1Sx7kZhvZVdf+N2BaKTdrrNZOL0Bj10RRfrhHrb3zEvXjJvvq298JPMJAiyiCS/v4zs1QlGU0ip7xGqeA==", + "dev": true, + "dependencies": { + "app-root-path": "^2.2.1", + "aria-query": "^3.0.0", + "axobject-query": "2.0.2", + "css-selector-tokenizer": "^0.7.1", + "cssauron": "^1.4.0", + "damerau-levenshtein": "^1.0.4", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.7", + "sprintf-js": "^1.1.2" + }, + "peerDependencies": { + "@angular/compiler": ">=2.3.1 <10.0.0 || >9.0.0-beta <10.0.0 || >9.1.0-beta <10.0.0 || >9.2.0-beta <10.0.0", + "@angular/core": ">=2.3.1 <10.0.0 || >9.0.0-beta <10.0.0 || >9.1.0-beta <10.0.0 || >9.2.0-beta <10.0.0", + "tslint": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/codelyzer/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/codelyzer/node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", + "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", + "dev": true, + "dependencies": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/copy-webpack-plugin/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "dependencies": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-loader": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.1.tgz", + "integrity": "sha512-0G4CbcZzQ9D1Q6ndOfjFuMDo8uLYMu5vc9Abs5ztyHcKvmil6GJrMiNjzzi3tQvUF+mVRuDg7bE6Oc0Prolgig==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.27", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.0.3", + "schema-utils": "^2.6.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/css-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/css-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "dev": true, + "dependencies": { + "css": "^2.0.0" + } + }, + "node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", + "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2", + "regexpu-core": "^4.6.0" + } + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/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/css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, + "node_modules/css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css/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/cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "dev": true, + "dependencies": { + "through": "X.X.X" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/csso": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "dev": true, + "dependencies": { + "css-tree": "1.0.0-alpha.39" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.6", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "dev": true + }, + "node_modules/csso/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/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "dependencies": { + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/dependency-graph": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", + "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "node_modules/detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "dependencies": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.3.427", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz", + "integrity": "sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "dependencies": { + "iconv-lite": "~0.4.13" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + } + }, + "node_modules/engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "dependencies": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/engine.io/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "node_modules/entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + }, + "node_modules/err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, + "node_modules/events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "dependencies": { + "original": "^1.0.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "node_modules/fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz", + "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "dependencies": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", + "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", + "dev": true, + "dependencies": { + "debug": "^3.0.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/follow-redirects/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "dependencies": { + "delegate": "^3.1.2" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-binary2/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "node_modules/highlight.js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.0.1.tgz", + "integrity": "sha512-l1HB5S9nmBuvurFIOPbpeJv4psKh2MyKCTOYRK/E6dwRXkbG96PLH7amP/xpGNyZOK8OWqv45DxLS/ZAIb3n9w==", + "deprecated": "Potential security issue. Upgrade to @latest", + "engines": { + "node": "*" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", + "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "dev": true, + "dependencies": { + "lru-cache": "^5.1.1" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "node_modules/html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "node_modules/html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/http-parser-js": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "dependencies": { + "agent-base": "4", + "debug": "3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/http-proxy/node_modules/eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/humanize-duration": { + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.24.0.tgz", + "integrity": "sha512-B3udnqisaDeRsvUSb+5n2hjxhABI9jotB+i1IEhgHhguTeM5LxIUKoVIu7UpeyaPOygr/Fnv7UhOi45kYYG+tg==" + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "dependencies": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "dependencies": { + "html-comment-regex": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-api": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.6.tgz", + "integrity": "sha512-x0Eicp6KsShG1k1rMgBAi/1GgY7kFGEBwQpw3PXGEmu+rBcBNhqU8g2DgY9mlepAsLPzrzrbqSgCGANnki4POA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "compare-versions": "^3.4.0", + "fileset": "^2.0.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "minimatch": "^3.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-api/node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-api/node_modules/istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "dependencies": { + "append-transform": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", + "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-report/node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/istanbul-lib-source-maps/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/istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "dev": true, + "dependencies": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true + }, + "node_modules/jasmine-spec-reporter": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", + "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", + "dev": true, + "dependencies": { + "colors": "1.1.2" + } + }, + "node_modules/jasmine/node_modules/jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + }, + "node_modules/jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", + "dev": true, + "engines": { + "node": ">= 6.9.x" + } + }, + "node_modules/jest-worker": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jszip": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz", + "integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, + "node_modules/karma": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-5.0.4.tgz", + "integrity": "sha512-UGqTe2LBiGQBXRN+Fygeiq63tbfOX45639SKSbPkLpARwnxROWJZg+froGkpHxr84FXCe8UGCf+1PITM6frT5w==", + "dev": true, + "dependencies": { + "body-parser": "^1.16.1", + "braces": "^3.0.2", + "chokidar": "^3.0.0", + "colors": "^1.1.0", + "connect": "^3.6.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^4.0.2", + "lodash": "^4.17.14", + "log4js": "^4.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "ua-parser-js": "0.7.21", + "yargs": "^15.3.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage-istanbul-reporter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.1.1.tgz", + "integrity": "sha512-CH8lTi8+kKXGvrhy94+EkEMldLCiUA0xMOiL31vvli9qK0T+qcXJAwWBRVJWnVWxYkTmyWar8lPz63dxX6/z1A==", + "dev": true, + "dependencies": { + "istanbul-api": "^2.1.6", + "minimatch": "^3.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/mattlewis92" + } + }, + "node_modules/karma-jasmine": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-3.0.3.tgz", + "integrity": "sha512-80iBR8/hLFY2Uw3S2GG6EndWtMCGMJjrCYNwYROWsJFVTjWrRSsLqcA2ye+U3ygW5sjOQo8f+78L8cGUxjC/+A==", + "dev": true, + "dependencies": { + "jasmine-core": "^3.5.0" + }, + "engines": { + "node": ">= 8" + }, + "peerDependencies": { + "karma": "*" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.3.tgz", + "integrity": "sha512-ci0VrjuCaFj+9d1tYlTE3KIPUCp0rz874zWWU3JgCMqGIyw5ke+BXWFPOAGAqUdCJcrMwneyvp1zFXA74MiPUA==", + "dev": true, + "peerDependencies": { + "jasmine-core": ">=3.5", + "karma": ">=0.9", + "karma-jasmine": ">=1.1" + } + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/karma/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/karma/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/karma/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/mime": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", + "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/karma/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/karma/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/karma/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/karma/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/karma/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/karma/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/katex": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz", + "integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==", + "dependencies": { + "commander": "^2.19.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "dependencies": { + "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/less/-/less-3.11.1.tgz", + "integrity": "sha512-tlWX341RECuTOvoDIvtFqXsKj072hm3+9ymRBe76/mD6O5ZZecnlAOVDlWAleF2+aohFrxNidXhv2773f6kY7g==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "tslib": "^1.10.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.4.1", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz", + "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "loader-utils": "^1.1.0", + "pify": "^4.0.1" + }, + "engines": { + "node": ">= 4.8.0" + }, + "peerDependencies": { + "less": "^2.3.1 || ^3.0.0", + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/less-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/less-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/less/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, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "dependencies": { + "leven": "^3.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/license-webpack-plugin": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.4.tgz", + "integrity": "sha512-1Xq72fmPbTg5KofXs+yI5L4QqPFjQ6mZxoeI6D7gfiEDOtaEIk6PGrdLaej90bpDqKNHNxlQ/MW4tMAL6xMPJQ==", + "dev": true, + "dependencies": { + "@types/webpack-sources": "^0.1.5", + "webpack-sources": "^1.2.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log4js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz", + "integrity": "sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==", + "dev": true, + "dependencies": { + "date-format": "^2.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.0", + "rfdc": "^1.1.4", + "streamroller": "^1.0.6" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/loglevel": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", + "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-loglevel?utm_medium=referral&utm_source=npm_fund" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lru-cache/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/luxon": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.23.0.tgz", + "integrity": "sha512-+6a/bXsCWrrR8vfbL41iM92es12zwV2Rum/KPkT+ubOZnnU3Sqbqok/FmD1xsWlWN2Y9Hu0fU/vNgU24ns7bpA==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-fetch-happen": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", + "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "dev": true, + "dependencies": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/marked": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", + "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">= 8.16.2" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/merge-source-map/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/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", + "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/move-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "node_modules/ng-apexcharts": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/ng-apexcharts/-/ng-apexcharts-1.2.3.tgz", + "integrity": "sha512-4G+JRCWp8uSSBJKvYP9vKHEZIC0w6YuRLasumZS35fCCc7bzLY+L907n8khG9Xeoo4LBt7pVbmjb9P+lSWs/5g==", + "dependencies": { + "tslib": "^1.9.0" + }, + "peerDependencies": { + "@angular/common": "^8.0.0", + "@angular/core": "^8.0.0", + "apexcharts": "^3.11.2", + "rxjs": "^6.4.0" + } + }, + "node_modules/ngx-markdown": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-9.0.0.tgz", + "integrity": "sha512-wcXMxA4Skgk9SzhfDRjihap/Kjq17jmMQiE/Ccp0bNibGaDgS5DbZiPBlMNLkp669UvjY9wVuxE4NuDtmQHS9w==", + "dependencies": { + "@types/marked": "^0.7.2", + "katex": "^0.11.0", + "marked": "^0.8.0", + "prismjs": "^1.16.0" + }, + "peerDependencies": { + "@angular/common": "^8.0.0 || ^9.0.0", + "@angular/core": "^8.0.0 || ^9.0.0", + "@angular/platform-browser": "^8.0.0 || ^9.0.0", + "rxjs": "^6.0.0", + "tslib": "^1.10.0", + "zone.js": "^0.9.0 || ^0.10.0" + } + }, + "node_modules/ngx-quill": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/ngx-quill/-/ngx-quill-9.1.0.tgz", + "integrity": "sha512-3VkacaTNGP3akHpjmxT+mvhfM/YeDsuQCwZWI1kKvB66BKSIaiZJOM8E9MHV++QOHSQ0nJzU6TUgYgxaAaSj0g==", + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "@angular/animations": "^7.0.0 || ^8.0.0 || ^9.0.0", + "@angular/common": "^7.0.0 || ^8.0.0 || ^9.0.0", + "@angular/core": "^7.0.0 || ^8.0.0 || ^9.0.0", + "@angular/forms": "^7.0.0 || ^8.0.0 || ^9.0.0", + "@angular/platform-browser": "^7.0.0 || ^8.0.0 || ^9.0.0", + "quill": "^1.3.7", + "rxjs": "^6.4.0 || ^6.5.0", + "tslib": "^1.10.0" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dev": true, + "dependencies": { + "lodash.toarray": "^4.4.0" + } + }, + "node_modules/node-fetch-npm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", + "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", + "dev": true, + "dependencies": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/node-releases": { + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, + "node_modules/npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-install-checks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-install-checks/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-package-arg": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.0.1.tgz", + "integrity": "sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ==", + "dev": true, + "dependencies": { + "hosted-git-info": "^3.0.2", + "semver": "^7.0.0", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-pick-manifest": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.0.0.tgz", + "integrity": "sha512-PdJpXMvjqt4nftNEDpCgjBUF8yI3Q3MyuAmVB9nemnnCg32F4BPL/JFBfdj8DubgHCYUFQhtLWmBPvdsFtjWMg==", + "dev": true, + "dependencies": { + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.0.0", + "semver": "^7.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.4.tgz", + "integrity": "sha512-6jb34hX/iYNQebqWUHtU8YF6Cjb1H6ouTFPClYsyiW6lpFkljTpdeftm53rRojtja1rKAvKNIIiTS5Sjpw4wsA==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "JSONStream": "^1.3.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/npm-registry-fetch/node_modules/npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, + "node_modules/npm-registry-fetch/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", + "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/open": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/open/-/open-7.0.3.tgz", + "integrity": "sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opn/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.3.tgz", + "integrity": "sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "dependencies": { + "url-parse": "^1.4.3" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pacote": { + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.12.tgz", + "integrity": "sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-normalize-package-bin": "^1.0.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + } + }, + "node_modules/pacote/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/pacote/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/pacote/node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/pacote/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/pacote/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/pacote/node_modules/npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "node_modules/pacote/node_modules/npm-pick-manifest": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "node_modules/pacote/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/pacote/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/pacote/node_modules/ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/pacote/node_modules/tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/pacote/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, + "node_modules/parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "dependencies": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + }, + "node_modules/parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/perfect-scrollbar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz", + "integrity": "sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/portfinder": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", + "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "dev": true, + "dependencies": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-functions/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-functions/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/postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-import/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.3.tgz", + "integrity": "sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1", + "postcss": "^7.0.18" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/postcss-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "dev": true, + "dependencies": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "dependencies": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-nested": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.1.tgz", + "integrity": "sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.21", + "postcss-selector-parser": "^6.0.2" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "dev": true, + "dependencies": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "node_modules/postcss/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/postcss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/prismjs": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", + "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", + "optionalDependencies": { + "clipboard": "^2.0.0" + } + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "dev": true, + "dependencies": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/protoduck": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "dev": true, + "dependencies": { + "genfun": "^5.0.0" + } + }, + "node_modules/protractor": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.4.tgz", + "integrity": "sha512-BaL4vePgu3Vfa/whvTUAlgaCAId4uNSGxIFSCXMgj7LMYENPWLp85h5RBi9pdpX/bWQ8SF6flP7afmi2TC4eHw==", + "dev": true, + "dependencies": { + "@types/q": "^0.0.32", + "@types/selenium-webdriver": "^3.0.0", + "blocking-proxy": "^1.0.0", + "browserstack": "^1.5.1", + "chalk": "^1.1.3", + "glob": "^7.0.3", + "jasmine": "2.8.0", + "jasminewd2": "^2.1.0", + "q": "1.4.1", + "saucelabs": "^1.5.0", + "selenium-webdriver": "3.6.0", + "source-map-support": "~0.4.0", + "webdriver-js-extender": "2.1.0", + "webdriver-manager": "^12.0.6", + "yargs": "^12.0.5" + }, + "bin": { + "protractor": "bin/protractor", + "webdriver-manager": "bin/webdriver-manager" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/protractor/node_modules/@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true + }, + "node_modules/protractor/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "dependencies": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/protractor/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/protractor/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/protractor/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/protractor/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/protractor/node_modules/webdriver-manager": { + "version": "12.1.7", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.7.tgz", + "integrity": "sha512-XINj6b8CYuUYC93SG3xPkxlyUc3IJbD6Vvo75CVGuG9uzsefDzWQrhz0Lq8vbPxtb4d63CZdYophF8k8Or/YiA==", + "dev": true, + "dependencies": { + "adm-zip": "^0.4.9", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + }, + "bin": { + "webdriver-manager": "bin/webdriver-manager" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/purgecss": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-2.1.2.tgz", + "integrity": "sha512-5oDBxiT9VonwKmEMohPFRFZrj8fdSVKxHPwq7G5Rx/2pXicZFJu+D4m5bb3NuV0sSK3ooNxq5jFIwwHzifP5FA==", + "dev": true, + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.0.0", + "postcss": "7.0.27", + "postcss-selector-parser": "^6.0.2" + }, + "bin": { + "purgecss": "bin/purgecss" + } + }, + "node_modules/purgecss/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "node_modules/quill": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "dependencies": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "node_modules/quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "dependencies": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.0.tgz", + "integrity": "sha512-iINUOYvl1cGEmfoaLjnZXt4bKfT2LJnZZib5N/LLyAphC+Dd11vNP9CNVb38j+SAJpFI1uo8j9frmih53ASy7Q==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/raw-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/raw-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-package-json": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.1.tgz", + "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "dev": true, + "dependencies": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.7.tgz", + "integrity": "sha512-fDnlZ+AybAS3C7Q9xDq5y8A2z+lT63zLbynew/lur/IR24OQF5x98tfNwf79mzEdfywZ0a2wpM860FhFfMxZlA==", + "dev": true, + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/reduce-css-calc/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rollup": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.1.0.tgz", + "integrity": "sha512-gfE1455AEazVVTJoeQtcOq/U6GSxwoj4XPSWVsuWmgIxj7sBQNLDOSA82PbdMe+cP8ql8fR1jogPFe8Wg8g4SQ==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/rrule": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.4.tgz", + "integrity": "sha512-sLdnh4lmjUqq8liFiOUXD5kWp/FcnbDLPwq5YAc/RrN6120XOPb86Ae5zxF7ttBVq8O3LxjjORMEit1baluahA==", + "dependencies": { + "tslib": "^1.10.0" + }, + "optionalDependencies": { + "luxon": "^1.21.3" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.3.tgz", + "integrity": "sha512-5NMHI1+YFYw4sN3yfKjpLuV9B5l7MqQ6FlkTcC4FT+oHbBRUZoSjHrrt/mE0nFXJyY2kQtU9ou9HxvFVjLFuuw==", + "dev": true, + "dependencies": { + "chokidar": ">=2.0.0 <4.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0", + "sass": "^1.3.0", + "webpack": "^4.36.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/sass-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/sass-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "dependencies": { + "https-proxy-agent": "^2.2.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", + "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "node_modules/selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "dependencies": { + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "engines": { + "node": ">= 6.9.0" + } + }, + "node_modules/selenium-webdriver/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/selfsigned": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "dev": true, + "dependencies": { + "node-forge": "0.9.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-dsl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", + "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", + "dev": true, + "dependencies": { + "semver": "^5.3.0" + } + }, + "node_modules/semver-dsl/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-intersect": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", + "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", + "dev": true, + "dependencies": { + "semver": "^5.0.0" + } + }, + "node_modules/semver-intersect/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "dependencies": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "dev": true + }, + "node_modules/socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "dependencies": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-client/node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "dependencies": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-parser/node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/socket.io/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "node_modules/sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "dependencies": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/socks": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", + "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", + "dev": true, + "dependencies": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "dev": true, + "dependencies": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-loader": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", + "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", + "dev": true, + "dependencies": { + "async": "^2.5.0", + "loader-utils": "^1.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/source-map-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/source-map-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/speed-measure-webpack-plugin": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz", + "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "webpack": "^1 || ^2 || ^3 || ^4" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/streamroller": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.6.tgz", + "integrity": "sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "date-format": "^2.0.0", + "debug": "^3.2.6", + "fs-extra": "^7.0.1", + "lodash": "^4.17.14" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/streamroller/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", + "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", + "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-loader": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz", + "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.6.4" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/style-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylus": { + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "dev": true, + "dependencies": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + }, + "peerDependencies": { + "stylus": ">=0.52.4" + } + }, + "node_modules/stylus-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/stylus-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/stylus/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stylus/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.4.4.tgz", + "integrity": "sha512-49Hy/+WnqQhxtGGjcGlhRlE7+hooX2A0/JOeJnA78fCEqDRlhURWujHY05aCl+lJ6G2qQ+1wlQTg4PqMPUcFVA==", + "dev": true, + "dependencies": { + "@fullhuman/postcss-purgecss": "^2.1.2", + "autoprefixer": "^9.4.5", + "browserslist": "^4.12.0", + "bytes": "^3.0.0", + "chalk": "^4.0.0", + "color": "^3.1.2", + "detective": "^5.2.0", + "fs-extra": "^8.0.0", + "lodash": "^4.17.15", + "node-emoji": "^1.8.1", + "normalize.css": "^8.0.1", + "postcss": "^7.0.11", + "postcss-functions": "^3.0.0", + "postcss-js": "^2.0.0", + "postcss-nested": "^4.1.1", + "postcss-selector-parser": "^6.0.0", + "pretty-hrtime": "^1.0.3", + "reduce-css-calc": "^2.1.6", + "resolve": "^1.14.2" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/tailwindcss/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tailwindcss/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/tailwindcss/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tailwindcss/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/tailwindcss/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/tailwindcss/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tailwindcss/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser": { + "version": "4.6.10", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz", + "integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz", + "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==", + "dev": true, + "dependencies": { + "cacache": "^13.0.1", + "find-cache-dir": "^3.2.0", + "jest-worker": "^25.1.0", + "p-limit": "^2.2.2", + "schema-utils": "^2.6.4", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.4.3", + "webpack-sources": "^1.4.3" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/cacache": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", + "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", + "dev": true, + "dependencies": { + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^2.7.1", + "ssri": "^7.0.0", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/terser-webpack-plugin/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/terser-webpack-plugin/node_modules/ssri": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", + "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/terser/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/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-node": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", + "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + }, + "peerDependencies": { + "typescript": ">=2.0" + } + }, + "node_modules/tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" + }, + "node_modules/tslint": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.2.tgz", + "integrity": "sha512-UyNrLdK3E0fQG/xWNqAFAC5ugtFyPO4JJR1KyyfQAyzR8W0fTRrC91A8Wej4BntFzcvETdCSDa/4PnNYJQLYiA==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.10.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", + "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universal-analytics": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz", + "integrity": "sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==", + "dev": true, + "dependencies": { + "debug": "^3.0.0", + "request": "^2.88.0", + "uuid": "^3.0.0" + } + }, + "node_modules/universal-analytics/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/util-promisify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", + "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "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/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "dev": true, + "dependencies": { + "chokidar": "^2.1.8", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "node_modules/watchpack/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/watchpack/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/watchpack/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "bundleDependencies": [ + "node-pre-gyp" + ], + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/debug": { + "version": "3.2.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/ignore-walk": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/ini": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.3", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/needle": { + "version": "2.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.14.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/nopt": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/npm-bundled": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/npm-packlist": { + "version": "1.4.8", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/osenv": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/rc": { + "version": "1.2.8", + "dev": true, + "inBundle": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/sax": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/tar": { + "version": "4.4.13", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/fsevents/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/watchpack/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/watchpack/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-animations-js": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.2.tgz", + "integrity": "sha512-TOMFWtQdxzjWp8qx4DAraTWTsdhxVSiWa6NkPFSaPtZ1diKUxTn4yTix73A1euG1WbSOMMPcY51cnjTIHrGtDA==" + }, + "node_modules/webdriver-js-extender": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", + "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", + "dev": true, + "dependencies": { + "@types/selenium-webdriver": "^3.0.0", + "selenium-webdriver": "^3.0.1" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/webpack": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", + "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", + "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", + "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", + "dev": true, + "dependencies": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.6", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.25", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.19", + "sockjs-client": "1.4.0", + "spdy": "^4.0.1", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "12.0.5" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/webpack-dev-server/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/webpack-dev-server/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "bundleDependencies": [ + "node-pre-gyp" + ], + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/debug": { + "version": "3.2.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/ignore-walk": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/ini": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.3", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/needle": { + "version": "2.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.14.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/nopt": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/npm-bundled": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/npm-packlist": { + "version": "1.4.8", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/osenv": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/rc": { + "version": "1.2.8", + "dev": true, + "inBundle": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/sax": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/tar": { + "version": "4.4.13", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/fsevents/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "optional": true + }, + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-dev-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack-sources/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/webpack-subresource-integrity": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.4.0.tgz", + "integrity": "sha512-GB1kB/LwAWC3CxwcedGhMkxGpNZxSheCe1q+KJP1bakuieAdX/rGHEcf5zsEzhKXpqsGqokgsDoD9dIkr61VDQ==", + "dev": true, + "dependencies": { + "webpack-sources": "^1.3.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "html-webpack-plugin": "^2.21.0 || ~3 || >=4.0.0-alpha.2 <5", + "webpack": "^1.12.11 || ~2 || ~3 || ~4" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/webpack/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/webpack/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack/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/webpack/node_modules/ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/webpack/node_modules/terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/when": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", + "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", + "dev": true + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/worker-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/worker-plugin/-/worker-plugin-4.0.2.tgz", + "integrity": "sha512-V+1zSZMOOKk+uBzKyNIODLQLsx59zSIOaI75J1EMS0iR1qy+KQR3y/pQ3T0vIhvPfDFapGRMsoMvQNEL3okqSA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0" + }, + "peerDependencies": { + "webpack": ">= 4" + } + }, + "node_modules/worker-plugin/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/worker-plugin/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "dependencies": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "node_modules/yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/zone.js": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", + "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" + } + }, "dependencies": { "@angular-devkit/architect": { "version": "0.901.4", @@ -243,7 +18580,8 @@ "@angular/animations": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.1.4.tgz", - "integrity": "sha512-gMo/DbCm5BDArladMAeC7/75T2DvhLr4CSUGJt/P/aimTEG2ywoAALs3pzwSSe4qxrHiR0OIksVW3l4km3iXEw==" + "integrity": "sha512-gMo/DbCm5BDArladMAeC7/75T2DvhLr4CSUGJt/P/aimTEG2ywoAALs3pzwSSe4qxrHiR0OIksVW3l4km3iXEw==", + "requires": {} }, "@angular/cdk": { "version": "9.2.2", @@ -304,12 +18642,14 @@ "@angular/common": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/common/-/common-9.1.4.tgz", - "integrity": "sha512-JvCoCWVbx0tF7l/0WTi24ui/mc2SElyVSNchR4VK/FViARnkvnSBdI/Ef5QWXrsPyKU4PYBtnWWgyxRspH+FBA==" + "integrity": "sha512-JvCoCWVbx0tF7l/0WTi24ui/mc2SElyVSNchR4VK/FViARnkvnSBdI/Ef5QWXrsPyKU4PYBtnWWgyxRspH+FBA==", + "requires": {} }, "@angular/compiler": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.4.tgz", - "integrity": "sha512-B+f3lviFNEJtL9V9exSKYPSz2Ddb6dxgPzQR7GSjGikDo+fKMtC1PjNwgJooS9gavhQx30uwkEEMIPYQbM6nNA==" + "integrity": "sha512-B+f3lviFNEJtL9V9exSKYPSz2Ddb6dxgPzQR7GSjGikDo+fKMtC1PjNwgJooS9gavhQx30uwkEEMIPYQbM6nNA==", + "requires": {} }, "@angular/compiler-cli": { "version": "9.1.4", @@ -511,12 +18851,14 @@ "@angular/core": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.1.4.tgz", - "integrity": "sha512-ND240vncmVD2KVe/KSQU3d/DxxoRipFg1+jFOFZGt0n0orCBHk/V1fu9iaG1sRyldL0+rCQ+fTI+1N4DTmMnxA==" + "integrity": "sha512-ND240vncmVD2KVe/KSQU3d/DxxoRipFg1+jFOFZGt0n0orCBHk/V1fu9iaG1sRyldL0+rCQ+fTI+1N4DTmMnxA==", + "requires": {} }, "@angular/forms": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-9.1.4.tgz", - "integrity": "sha512-Njt+pMLfPBchL0/ayIjJqXL6ZfM4Ccvf7KO1wS1HMzh3QlmfNa0JSgc4pfrbRJAMN9g7V/FYLyKejs1bJZkenA==" + "integrity": "sha512-Njt+pMLfPBchL0/ayIjJqXL6ZfM4Ccvf7KO1wS1HMzh3QlmfNa0JSgc4pfrbRJAMN9g7V/FYLyKejs1bJZkenA==", + "requires": {} }, "@angular/language-service": { "version": "9.1.4", @@ -527,27 +18869,32 @@ "@angular/material": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/@angular/material/-/material-9.2.2.tgz", - "integrity": "sha512-gdQiMJ6PtW/5fd+0mglHFyzxULDCBGjn9RTET3sUq2rkc9+jBXr4OvnsUyBWSnqqv97XqotVDIx5JgE4/YX/Rw==" + "integrity": "sha512-gdQiMJ6PtW/5fd+0mglHFyzxULDCBGjn9RTET3sUq2rkc9+jBXr4OvnsUyBWSnqqv97XqotVDIx5JgE4/YX/Rw==", + "requires": {} }, "@angular/material-moment-adapter": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-9.2.2.tgz", - "integrity": "sha512-hijj2VVC7Oy9XGVYE+FsdI521w/9v453jP2VUH+CCRoeoCopdNS+dh1vacSAGf21UXwH9LJ5E6kI9RsmfwF/Ig==" + "integrity": "sha512-hijj2VVC7Oy9XGVYE+FsdI521w/9v453jP2VUH+CCRoeoCopdNS+dh1vacSAGf21UXwH9LJ5E6kI9RsmfwF/Ig==", + "requires": {} }, "@angular/platform-browser": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.4.tgz", - "integrity": "sha512-mBCHfTl+5tQfaUiGlDujP7mFBzovFc54Zi2kcCE8DSdSSVQ2TPBo6hXa6y2cL3hJPFZzQ7mC4ORFrsGADhHn/w==" + "integrity": "sha512-mBCHfTl+5tQfaUiGlDujP7mFBzovFc54Zi2kcCE8DSdSSVQ2TPBo6hXa6y2cL3hJPFZzQ7mC4ORFrsGADhHn/w==", + "requires": {} }, "@angular/platform-browser-dynamic": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.4.tgz", - "integrity": "sha512-YtVbnxyS6FU7xNpA6A95tmSfrB8+WC7OH3mbP8M9NaGk0OYz8B/JOe1HByP4JRpEGCvBtXdJ2NSW/MpLIT8SiQ==" + "integrity": "sha512-YtVbnxyS6FU7xNpA6A95tmSfrB8+WC7OH3mbP8M9NaGk0OYz8B/JOe1HByP4JRpEGCvBtXdJ2NSW/MpLIT8SiQ==", + "requires": {} }, "@angular/router": { "version": "9.1.4", "resolved": "https://registry.npmjs.org/@angular/router/-/router-9.1.4.tgz", - "integrity": "sha512-yUyjCgG2P2Jh8MvoyC6yirmAtx1Qe7MKLuLvsa9WOB571QNEcNLTYMfAMHUKsQTcE/+o984QyLlneoibgI9wFA==" + "integrity": "sha512-yUyjCgG2P2Jh8MvoyC6yirmAtx1Qe7MKLuLvsa9WOB571QNEcNLTYMfAMHUKsQTcE/+o984QyLlneoibgI9wFA==", + "requires": {} }, "@babel/code-frame": { "version": "7.8.3", @@ -1739,27 +20086,32 @@ "@fullcalendar/daygrid": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-4.4.0.tgz", - "integrity": "sha512-pDfvL0XZxKHTZ4VFOmwaYe3LmuABEIZsEopeqQ8y5O6BDen9KCbJqgHeCI8FpASSBd6bNlUx7il7EHdSoHhgIw==" + "integrity": "sha512-pDfvL0XZxKHTZ4VFOmwaYe3LmuABEIZsEopeqQ8y5O6BDen9KCbJqgHeCI8FpASSBd6bNlUx7il7EHdSoHhgIw==", + "requires": {} }, "@fullcalendar/interaction": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-4.4.0.tgz", - "integrity": "sha512-nGu0ZzYYlNpIhqfyv3JupteWKFETs3W1MzbRJcEZkuPncn4BooEi4A2blgHfacHAmmpaNkT84tAmhzi734MFBA==" + "integrity": "sha512-nGu0ZzYYlNpIhqfyv3JupteWKFETs3W1MzbRJcEZkuPncn4BooEi4A2blgHfacHAmmpaNkT84tAmhzi734MFBA==", + "requires": {} }, "@fullcalendar/list": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-4.4.0.tgz", - "integrity": "sha512-uUDSPS71czNTK5Z3x3HzeE3KIvqkCfvhY+mGFdaAL6+7VpCwEIfB6s3GIJOjzu9TONmczMk4jdq0b1WUFLY5PQ==" + "integrity": "sha512-uUDSPS71czNTK5Z3x3HzeE3KIvqkCfvhY+mGFdaAL6+7VpCwEIfB6s3GIJOjzu9TONmczMk4jdq0b1WUFLY5PQ==", + "requires": {} }, "@fullcalendar/moment": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@fullcalendar/moment/-/moment-4.4.0.tgz", - "integrity": "sha512-sW2F7z0E1+kBvBduGiXVYJtIWj2AWeUQQoiLA+xgprsyljzigwnI+9J2iviaB9uL7LIbCSnPrOZmhpVTufmPvQ==" + "integrity": "sha512-sW2F7z0E1+kBvBduGiXVYJtIWj2AWeUQQoiLA+xgprsyljzigwnI+9J2iviaB9uL7LIbCSnPrOZmhpVTufmPvQ==", + "requires": {} }, "@fullcalendar/rrule": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@fullcalendar/rrule/-/rrule-4.4.0.tgz", - "integrity": "sha512-pXe3kSShg9CQ5gr0J0IGMYAwVlBv6j9yotRfJUrCY7xUWNkqTLAmburW7Q7KNlDMOLuiFbM/twBYZYiIjjTWpg==" + "integrity": "sha512-pXe3kSShg9CQ5gr0J0IGMYAwVlBv6j9yotRfJUrCY7xUWNkqTLAmburW7Q7KNlDMOLuiFbM/twBYZYiIjjTWpg==", + "requires": {} }, "@fullcalendar/timegrid": { "version": "4.4.0", @@ -2196,16 +20548,6 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -2303,13 +20645,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "dev": true, + "requires": {} }, "ajv-keywords": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true + "dev": true, + "requires": {} }, "alphanum-sort": { "version": "1.0.2", @@ -3272,7 +21616,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", - "dev": true + "dev": true, + "requires": {} }, "class-utils": { "version": "0.3.6", @@ -6974,6 +25319,16 @@ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -7254,7 +25609,8 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.3.tgz", "integrity": "sha512-ci0VrjuCaFj+9d1tYlTE3KIPUCp0rz874zWWU3JgCMqGIyw5ke+BXWFPOAGAqUdCJcrMwneyvp1zFXA74MiPUA==", - "dev": true + "dev": true, + "requires": {} }, "karma-source-map-support": { "version": "1.4.0", @@ -8151,7 +26507,8 @@ "ngx-quill": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/ngx-quill/-/ngx-quill-9.1.0.tgz", - "integrity": "sha512-3VkacaTNGP3akHpjmxT+mvhfM/YeDsuQCwZWI1kKvB66BKSIaiZJOM8E9MHV++QOHSQ0nJzU6TUgYgxaAaSj0g==" + "integrity": "sha512-3VkacaTNGP3akHpjmxT+mvhfM/YeDsuQCwZWI1kKvB66BKSIaiZJOM8E9MHV++QOHSQ0nJzU6TUgYgxaAaSj0g==", + "requires": {} }, "nice-try": { "version": "1.0.5", @@ -8367,9 +26724,9 @@ "integrity": "sha512-6jb34hX/iYNQebqWUHtU8YF6Cjb1H6ouTFPClYsyiW6lpFkljTpdeftm53rRojtja1rKAvKNIIiTS5Sjpw4wsA==", "dev": true, "requires": { - "JSONStream": "^1.3.4", "bluebird": "^3.5.1", "figgy-pudding": "^3.4.1", + "JSONStream": "^1.3.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "npm-package-arg": "^6.1.0", @@ -11894,6 +30251,15 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -11959,15 +30325,6 @@ "es-abstract": "^1.17.5" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -13573,24 +31930,24 @@ "dev": true, "optional": true }, - "string-width": { - "version": "1.0.2", + "string_decoder": { + "version": "1.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "safe-buffer": "~5.1.0" } }, - "string_decoder": { - "version": "1.1.1", + "string-width": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "strip-ansi": { @@ -14520,24 +32877,24 @@ "dev": true, "optional": true }, - "string-width": { - "version": "1.0.2", + "string_decoder": { + "version": "1.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "safe-buffer": "~5.1.0" } }, - "string_decoder": { - "version": "1.1.1", + "string-width": { + "version": "1.0.2", "bundled": true, "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "strip-ansi": { diff --git a/webapp/frontend/src/app/data/mock/device/details/sda.ts b/webapp/frontend/src/app/data/mock/device/details/sda.ts index 2766943..16b2d97 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sda.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sda.ts @@ -1,1569 +1,264 @@ export const sda = { "data": { - "CreatedAt": "2020-08-28T07:55:27.751071002Z", - "UpdatedAt": "2020-09-08T21:39:26.571901-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "interface_speed": "", - "host_id": "NAS", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 1024209543168, - "form_factor": "", - "smart_support": false, - "device_protocol": "NVMe", - "device_type": "nvme", - "smart_results": [{ - "ID": 46, - "CreatedAt": "2020-09-08T21:39:26.572596-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572596-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.301226-07:00", + "UpdatedAt": "2021-10-24T16:37:56.981833-07:00", "DeletedAt": null, + "wwn": "0x5002538e40a22954", + "device_name": "sda", + "manufacturer": "ATA", + "model_name": "Samsung_SSD_860_EVO_500GB", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "S3YZNB0KBXXXXXX", + "firmware": "002C", + "rotational_speed": 0, + "capacity": 500107862016, + "form_factor": "", + "smart_support": false, + "device_protocol": "NVMe", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart_results": [{ + "date": "2021-10-24T23:20:44Z", "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T05:01:02-07:00", - "smart_status": "passed", + "device_protocol": "NVMe", "temp": 36, "power_on_hours": 2401, "power_cycle_count": 266, - "ata_attributes": [], - "nvme_attributes": [{ - "ID": 113, - "CreatedAt": "2020-09-08T21:39:26.572894-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572894-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 97, - "CreatedAt": "2020-09-07T15:47:21.336744707Z", - "UpdatedAt": "2020-09-07T15:47:21.336744707Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-07T15:38:56.633368699Z", - "UpdatedAt": "2020-09-07T15:38:56.633368699Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-07T15:26:07.504953448Z", - "UpdatedAt": "2020-09-07T15:26:07.504953448Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 49, - "CreatedAt": "2020-09-07T15:19:17.467897283Z", - "UpdatedAt": "2020-09-07T15:19:17.467897283Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-09-07T15:10:40.246090797Z", - "UpdatedAt": "2020-09-07T15:10:40.246090797Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 17, - "CreatedAt": "2020-09-06T23:14:39.849191275Z", - "UpdatedAt": "2020-09-06T23:14:39.849191275Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.833308403Z", - "UpdatedAt": "2020-08-28T07:55:27.833308403Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 114, - "CreatedAt": "2020-09-08T21:39:26.573359-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573359-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 98, - "CreatedAt": "2020-09-07T15:47:21.336894307Z", - "UpdatedAt": "2020-09-07T15:47:21.336894307Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-07T15:38:56.6334864Z", - "UpdatedAt": "2020-09-07T15:38:56.6334864Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 66, - "CreatedAt": "2020-09-07T15:26:07.505094452Z", - "UpdatedAt": "2020-09-07T15:26:07.505094452Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 50, - "CreatedAt": "2020-09-07T15:19:17.468022483Z", - "UpdatedAt": "2020-09-07T15:19:17.468022483Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-09-07T15:10:40.246266999Z", - "UpdatedAt": "2020-09-07T15:10:40.246266999Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 18, - "CreatedAt": "2020-09-06T23:14:39.849315479Z", - "UpdatedAt": "2020-09-06T23:14:39.849315479Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.833462173Z", - "UpdatedAt": "2020-08-28T07:55:27.833462173Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 115, - "CreatedAt": "2020-09-08T21:39:26.573466-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573466-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 99, - "CreatedAt": "2020-09-07T15:47:21.336981607Z", - "UpdatedAt": "2020-09-07T15:47:21.336981607Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-07T15:38:56.6335637Z", - "UpdatedAt": "2020-09-07T15:38:56.6335637Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 67, - "CreatedAt": "2020-09-07T15:26:07.505182255Z", - "UpdatedAt": "2020-09-07T15:26:07.505182255Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 51, - "CreatedAt": "2020-09-07T15:19:17.468100282Z", - "UpdatedAt": "2020-09-07T15:19:17.468100282Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-09-07T15:10:40.246339099Z", - "UpdatedAt": "2020-09-07T15:10:40.246339099Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 19, - "CreatedAt": "2020-09-06T23:14:39.849394281Z", - "UpdatedAt": "2020-09-06T23:14:39.849394281Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.833551437Z", - "UpdatedAt": "2020-08-28T07:55:27.833551437Z", - "DeletedAt": null, - "smart_id": 4, + "attrs": { + "available_spare": { "attribute_id": "available_spare", - "name": "Available Spare", "value": 100, "thresh": 10, - "transformed_value": 0 - }] - }, { - "ID": 116, - "CreatedAt": "2020-09-08T21:39:26.57354-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57354-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 100, - "CreatedAt": "2020-09-07T15:47:21.337060308Z", - "UpdatedAt": "2020-09-07T15:47:21.337060308Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-07T15:38:56.633637401Z", - "UpdatedAt": "2020-09-07T15:38:56.633637401Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 68, - "CreatedAt": "2020-09-07T15:26:07.505262357Z", - "UpdatedAt": "2020-09-07T15:26:07.505262357Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 52, - "CreatedAt": "2020-09-07T15:19:17.468187982Z", - "UpdatedAt": "2020-09-07T15:19:17.468187982Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-09-07T15:10:40.2464335Z", - "UpdatedAt": "2020-09-07T15:10:40.2464335Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 20, - "CreatedAt": "2020-09-06T23:14:39.849473683Z", - "UpdatedAt": "2020-09-06T23:14:39.849473683Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "percentage_used", - "name": "Percentage Used", + "transformed_value": 0, + "status": 0 + }, + "controller_busy_time": { + "attribute_id": "controller_busy_time", + "value": 3060, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "critical_comp_time": { + "attribute_id": "critical_comp_time", "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.833639555Z", - "UpdatedAt": "2020-08-28T07:55:27.833639555Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "percentage_used", - "name": "Percentage Used", + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "critical_warning": { + "attribute_id": "critical_warning", "value": 0, "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 117, - "CreatedAt": "2020-09-08T21:39:26.573622-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573622-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 101, - "CreatedAt": "2020-09-07T15:47:21.337139008Z", - "UpdatedAt": "2020-09-07T15:47:21.337139008Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 85, - "CreatedAt": "2020-09-07T15:38:56.633701001Z", - "UpdatedAt": "2020-09-07T15:38:56.633701001Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 69, - "CreatedAt": "2020-09-07T15:26:07.505347059Z", - "UpdatedAt": "2020-09-07T15:26:07.505347059Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-09-07T15:19:17.468256482Z", - "UpdatedAt": "2020-09-07T15:19:17.468256482Z", - "DeletedAt": null, - "smart_id": 22, + "transformed_value": 0, + "status": 0 + }, + "data_units_read": { "attribute_id": "data_units_read", - "name": "Data Units Read", "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-09-07T15:10:40.2465052Z", - "UpdatedAt": "2020-09-07T15:10:40.2465052Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 21, - "CreatedAt": "2020-09-06T23:14:39.849535985Z", - "UpdatedAt": "2020-09-06T23:14:39.849535985Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.833723448Z", - "UpdatedAt": "2020-08-28T07:55:27.833723448Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 118, - "CreatedAt": "2020-09-08T21:39:26.57369-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57369-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 102, - "CreatedAt": "2020-09-07T15:47:21.337239108Z", - "UpdatedAt": "2020-09-07T15:47:21.337239108Z", - "DeletedAt": null, - "smart_id": 40, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "data_units_written": { "attribute_id": "data_units_written", - "name": "Data Units Written", "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-07T15:38:56.633767202Z", - "UpdatedAt": "2020-09-07T15:38:56.633767202Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 70, - "CreatedAt": "2020-09-07T15:26:07.505469162Z", - "UpdatedAt": "2020-09-07T15:26:07.505469162Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-07T15:19:17.468321982Z", - "UpdatedAt": "2020-09-07T15:19:17.468321982Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-09-07T15:10:40.246568201Z", - "UpdatedAt": "2020-09-07T15:10:40.246568201Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 22, - "CreatedAt": "2020-09-06T23:14:39.849595287Z", - "UpdatedAt": "2020-09-06T23:14:39.849595287Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.833814267Z", - "UpdatedAt": "2020-08-28T07:55:27.833814267Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 119, - "CreatedAt": "2020-09-08T21:39:26.573761-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573761-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 103, - "CreatedAt": "2020-09-07T15:47:21.337318208Z", - "UpdatedAt": "2020-09-07T15:47:21.337318208Z", - "DeletedAt": null, - "smart_id": 40, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "host_reads": { "attribute_id": "host_reads", - "name": "Host Reads", "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-07T15:38:56.633832703Z", - "UpdatedAt": "2020-09-07T15:38:56.633832703Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 71, - "CreatedAt": "2020-09-07T15:26:07.505549465Z", - "UpdatedAt": "2020-09-07T15:26:07.505549465Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-07T15:19:17.468389981Z", - "UpdatedAt": "2020-09-07T15:19:17.468389981Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-09-07T15:10:40.246645901Z", - "UpdatedAt": "2020-09-07T15:10:40.246645901Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 23, - "CreatedAt": "2020-09-06T23:14:39.849654489Z", - "UpdatedAt": "2020-09-06T23:14:39.849654489Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.833887571Z", - "UpdatedAt": "2020-08-28T07:55:27.833887571Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 120, - "CreatedAt": "2020-09-08T21:39:26.573834-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573834-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 104, - "CreatedAt": "2020-09-07T15:47:21.337427308Z", - "UpdatedAt": "2020-09-07T15:47:21.337427308Z", - "DeletedAt": null, - "smart_id": 40, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "host_writes": { "attribute_id": "host_writes", - "name": "Host Writes", "value": 83170961, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "media_errors": { + "attribute_id": "media_errors", + "value": 0, "thresh": 0, - "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-07T15:38:56.633900603Z", - "UpdatedAt": "2020-09-07T15:38:56.633900603Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 72, - "CreatedAt": "2020-09-07T15:26:07.505627267Z", - "UpdatedAt": "2020-09-07T15:26:07.505627267Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-07T15:19:17.468456681Z", - "UpdatedAt": "2020-09-07T15:19:17.468456681Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 40, - "CreatedAt": "2020-09-07T15:10:40.246709102Z", - "UpdatedAt": "2020-09-07T15:10:40.246709102Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 24, - "CreatedAt": "2020-09-06T23:14:39.849714291Z", - "UpdatedAt": "2020-09-06T23:14:39.849714291Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.833973719Z", - "UpdatedAt": "2020-08-28T07:55:27.833973719Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 121, - "CreatedAt": "2020-09-08T21:39:26.5739-07:00", - "UpdatedAt": "2020-09-08T21:39:26.5739-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 105, - "CreatedAt": "2020-09-07T15:47:21.337516009Z", - "UpdatedAt": "2020-09-07T15:47:21.337516009Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-07T15:38:56.633969604Z", - "UpdatedAt": "2020-09-07T15:38:56.633969604Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 73, - "CreatedAt": "2020-09-07T15:26:07.505724769Z", - "UpdatedAt": "2020-09-07T15:26:07.505724769Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-07T15:19:17.468521581Z", - "UpdatedAt": "2020-09-07T15:19:17.468521581Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 41, - "CreatedAt": "2020-09-07T15:10:40.246774002Z", - "UpdatedAt": "2020-09-07T15:10:40.246774002Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 25, - "CreatedAt": "2020-09-06T23:14:39.849784693Z", - "UpdatedAt": "2020-09-06T23:14:39.849784693Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.834051665Z", - "UpdatedAt": "2020-08-28T07:55:27.834051665Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 122, - "CreatedAt": "2020-09-08T21:39:26.573967-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573967-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 106, - "CreatedAt": "2020-09-07T15:47:21.337609809Z", - "UpdatedAt": "2020-09-07T15:47:21.337609809Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-07T15:38:56.634034304Z", - "UpdatedAt": "2020-09-07T15:38:56.634034304Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 74, - "CreatedAt": "2020-09-07T15:26:07.505806272Z", - "UpdatedAt": "2020-09-07T15:26:07.505806272Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-07T15:19:17.468586181Z", - "UpdatedAt": "2020-09-07T15:19:17.468586181Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 42, - "CreatedAt": "2020-09-07T15:10:40.246861903Z", - "UpdatedAt": "2020-09-07T15:10:40.246861903Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 26, - "CreatedAt": "2020-09-06T23:14:39.849849495Z", - "UpdatedAt": "2020-09-06T23:14:39.849849495Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, + "transformed_value": 0, + "status": 0 + }, + "num_err_log_entries": { + "attribute_id": "num_err_log_entries", + "value": 0, "thresh": 0, - "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.834128174Z", - "UpdatedAt": "2020-08-28T07:55:27.834128174Z", - "DeletedAt": null, - "smart_id": 4, + "transformed_value": 0, + "status": 0 + }, + "percentage_used": { + "attribute_id": "percentage_used", + "value": 0, + "thresh": 100, + "transformed_value": 0, + "status": 0 + }, + "power_cycles": { "attribute_id": "power_cycles", - "name": "Power Cycles", "value": 266, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 123, - "CreatedAt": "2020-09-08T21:39:26.57404-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57404-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 107, - "CreatedAt": "2020-09-07T15:47:21.337689109Z", - "UpdatedAt": "2020-09-07T15:47:21.337689109Z", - "DeletedAt": null, - "smart_id": 40, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "power_on_hours": { "attribute_id": "power_on_hours", - "name": "Power on Hours", "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-07T15:38:56.634101905Z", - "UpdatedAt": "2020-09-07T15:38:56.634101905Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 75, - "CreatedAt": "2020-09-07T15:26:07.505880974Z", - "UpdatedAt": "2020-09-07T15:26:07.505880974Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-07T15:19:17.468654081Z", - "UpdatedAt": "2020-09-07T15:19:17.468654081Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 43, - "CreatedAt": "2020-09-07T15:10:40.246931403Z", - "UpdatedAt": "2020-09-07T15:10:40.246931403Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-09-06T23:14:39.849908596Z", - "UpdatedAt": "2020-09-06T23:14:39.849908596Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.834210433Z", - "UpdatedAt": "2020-08-28T07:55:27.834210433Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 124, - "CreatedAt": "2020-09-08T21:39:26.574108-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574108-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 108, - "CreatedAt": "2020-09-07T15:47:21.337764809Z", - "UpdatedAt": "2020-09-07T15:47:21.337764809Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 92, - "CreatedAt": "2020-09-07T15:38:56.634171906Z", - "UpdatedAt": "2020-09-07T15:38:56.634171906Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 76, - "CreatedAt": "2020-09-07T15:26:07.505955776Z", - "UpdatedAt": "2020-09-07T15:26:07.505955776Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-07T15:19:17.46871948Z", - "UpdatedAt": "2020-09-07T15:19:17.46871948Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 44, - "CreatedAt": "2020-09-07T15:10:40.247002504Z", - "UpdatedAt": "2020-09-07T15:10:40.247002504Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-09-06T23:14:39.849968798Z", - "UpdatedAt": "2020-09-06T23:14:39.849968798Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.834292136Z", - "UpdatedAt": "2020-08-28T07:55:27.834292136Z", - "DeletedAt": null, - "smart_id": 4, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "temperature": { + "attribute_id": "temperature", + "value": 36, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "unsafe_shutdowns": { "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", "value": 43, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 125, - "CreatedAt": "2020-09-08T21:39:26.574178-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574178-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 109, - "CreatedAt": "2020-09-07T15:47:21.337839409Z", - "UpdatedAt": "2020-09-07T15:47:21.337839409Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 93, - "CreatedAt": "2020-09-07T15:38:56.634234206Z", - "UpdatedAt": "2020-09-07T15:38:56.634234206Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 77, - "CreatedAt": "2020-09-07T15:26:07.506062879Z", - "UpdatedAt": "2020-09-07T15:26:07.506062879Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-07T15:19:17.46878678Z", - "UpdatedAt": "2020-09-07T15:19:17.46878678Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 45, - "CreatedAt": "2020-09-07T15:10:40.247110105Z", - "UpdatedAt": "2020-09-07T15:10:40.247110105Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-09-06T23:14:39.850046301Z", - "UpdatedAt": "2020-09-06T23:14:39.850046301Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.834373811Z", - "UpdatedAt": "2020-08-28T07:55:27.834373811Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 126, - "CreatedAt": "2020-09-08T21:39:26.574242-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574242-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 110, - "CreatedAt": "2020-09-07T15:47:21.337915109Z", - "UpdatedAt": "2020-09-07T15:47:21.337915109Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 94, - "CreatedAt": "2020-09-07T15:38:56.634303007Z", - "UpdatedAt": "2020-09-07T15:38:56.634303007Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 78, - "CreatedAt": "2020-09-07T15:26:07.506140681Z", - "UpdatedAt": "2020-09-07T15:26:07.506140681Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-07T15:19:17.46885548Z", - "UpdatedAt": "2020-09-07T15:19:17.46885548Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 46, - "CreatedAt": "2020-09-07T15:10:40.247212006Z", - "UpdatedAt": "2020-09-07T15:10:40.247212006Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-09-06T23:14:39.850150504Z", - "UpdatedAt": "2020-09-06T23:14:39.850150504Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 14, - "CreatedAt": "2020-08-28T07:55:27.834456493Z", - "UpdatedAt": "2020-08-28T07:55:27.834456493Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 127, - "CreatedAt": "2020-09-08T21:39:26.574309-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574309-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 111, - "CreatedAt": "2020-09-07T15:47:21.33801171Z", - "UpdatedAt": "2020-09-07T15:47:21.33801171Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 95, - "CreatedAt": "2020-09-07T15:38:56.634377407Z", - "UpdatedAt": "2020-09-07T15:38:56.634377407Z", - "DeletedAt": null, - "smart_id": 34, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "warning_temp_time": { "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-07T15:26:07.506214683Z", - "UpdatedAt": "2020-09-07T15:26:07.506214683Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-07T15:19:17.468958879Z", - "UpdatedAt": "2020-09-07T15:19:17.468958879Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 47, - "CreatedAt": "2020-09-07T15:10:40.247310706Z", - "UpdatedAt": "2020-09-07T15:10:40.247310706Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-09-06T23:14:39.850219706Z", - "UpdatedAt": "2020-09-06T23:14:39.850219706Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 15, - "CreatedAt": "2020-08-28T07:55:27.834538882Z", - "UpdatedAt": "2020-08-28T07:55:27.834538882Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 128, - "CreatedAt": "2020-09-08T21:39:26.574383-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574383-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 112, - "CreatedAt": "2020-09-07T15:47:21.33808201Z", - "UpdatedAt": "2020-09-07T15:47:21.33808201Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 96, - "CreatedAt": "2020-09-07T15:38:56.634438008Z", - "UpdatedAt": "2020-09-07T15:38:56.634438008Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-07T15:26:07.506290585Z", - "UpdatedAt": "2020-09-07T15:26:07.506290585Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-07T15:19:17.469037079Z", - "UpdatedAt": "2020-09-07T15:19:17.469037079Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 48, - "CreatedAt": "2020-09-07T15:10:40.247471107Z", - "UpdatedAt": "2020-09-07T15:10:40.247471107Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 32, - "CreatedAt": "2020-09-06T23:14:39.850278807Z", - "UpdatedAt": "2020-09-06T23:14:39.850278807Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 16, - "CreatedAt": "2020-08-28T07:55:27.834645921Z", - "UpdatedAt": "2020-08-28T07:55:27.834645921Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }], - "scsi_attributes": [] + "thresh": -1, + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 }] - }, "metadata": { + }, + "metadata": { "available_spare": { + "display_name": "Available Spare", "ideal": "high", "critical": true, "description": "Contains a normalized percentage (0 to 100%) of the remaining spare capacity available.", "display_type": "" }, "controller_busy_time": { + "display_name": "Controller Busy Time", "ideal": "", "critical": false, "description": "Contains the amount of time the controller is busy with I/O commands. The controller is busy when there is a command outstanding to an I/O Queue (specifically, a command was issued via an I/O Submission Queue Tail doorbell write and the corresponding completion queue entry has not been posted yet to the associated I/O Completion Queue). This value is reported in minutes.", "display_type": "" }, "critical_comp_time": { + "display_name": "Critical CompTime", "ideal": "", "critical": false, "description": "Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.", "display_type": "" }, "critical_warning": { + "display_name": "Critical Warning", "ideal": "low", "critical": true, "description": "This field indicates critical warnings for the state of the controller. Each bit corresponds to a critical warning type; multiple bits may be set. If a bit is cleared to ‘0’, then that critical warning does not apply. Critical warnings may result in an asynchronous event notification to the host. Bits in this field represent the current associated state and are not persistent.", "display_type": "" }, "data_units_read": { + "display_name": "Data Units Read", "ideal": "", "critical": false, "description": "Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data read to 512 byte units.", "display_type": "" }, "data_units_written": { + "display_name": "Data Units Written", "ideal": "", "critical": false, "description": "Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data written to 512 byte units.", "display_type": "" }, "host_reads": { + "display_name": "Host Reads", "ideal": "", "critical": false, "description": "Contains the number of read commands completed by the controller", "display_type": "" }, "host_writes": { + "display_name": "Host Writes", "ideal": "", "critical": false, "description": "Contains the number of write commands completed by the controller", "display_type": "" }, "media_errors": { + "display_name": "Media Errors", "ideal": "low", "critical": true, "description": "Contains the number of occurrences where the controller detected an unrecovered data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field.", "display_type": "" }, "num_err_log_entries": { + "display_name": "Numb Err Log Entries", "ideal": "low", "critical": true, "description": "Contains the number of Error Information log entries over the life of the controller.", "display_type": "" }, "percentage_used": { + "display_name": "Percentage Used", "ideal": "low", "critical": true, "description": "Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. Percentages greater than 254 shall be represented as 255. This value shall be updated once per power-on hour (when the controller is not in a sleep state).", "display_type": "" }, "power_cycles": { + "display_name": "Power Cycles", "ideal": "", "critical": false, "description": "Contains the number of power cycles.", "display_type": "" }, "power_on_hours": { + "display_name": "Power on Hours", "ideal": "", "critical": false, "description": "Contains the number of power-on hours. Power on hours is always logging, even when in low power mode.", "display_type": "" }, - "temperature": {"ideal": "", "critical": false, "description": "", "display_type": ""}, + "temperature": { + "display_name": "Temperature", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, "unsafe_shutdowns": { + "display_name": "Unsafe Shutdowns", "ideal": "", "critical": false, "description": "Contains the number of unsafe shutdowns. This count is incremented when a shutdown notification (CC.SHN) is not received prior to loss of power.", "display_type": "" }, "warning_temp_time": { + "display_name": "Warning Temp Time", "ideal": "", "critical": false, "description": "Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold (WCTEMP) field and less than the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.", "display_type": "" } - }, "success": true + }, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdb.ts b/webapp/frontend/src/app/data/mock/device/details/sdb.ts index e6b3771..5e817bd 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdb.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdb.ts @@ -1,4407 +1,472 @@ export const sdb = { "data": { - "CreatedAt": "2020-08-28T07:55:27.755292213Z", - "UpdatedAt": "2020-09-08T21:39:26.56453-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "6.0 Gb/s", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 5400, - "capacity": 14000519643136, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "sat", - "smart_results": [{ - "ID": 44, - "CreatedAt": "2020-09-08T21:39:26.565492-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565492-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.302191-07:00", + "UpdatedAt": "2021-10-24T17:06:39.436996-07:00", "DeletedAt": null, + "wwn": "0x5000cca264eb01d7", + "device_name": "sdb", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK1XXXXX", + "firmware": "81.00A81", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "ATA", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 2 + }, + "smart_results": [{ + "date": "2021-10-24T20:34:04Z", "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", + "device_protocol": "ATA", "temp": 32, "power_on_hours": 1730, "power_cycle_count": 9, - "ata_attributes": [{ - "ID": 390, - "CreatedAt": "2020-09-08T21:39:26.565859-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565859-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.034155719633986996, - "history": [{ - "ID": 372, - "CreatedAt": "2020-09-08T21:39:26.554625-07:00", - "UpdatedAt": "2020-09-08T21:39:26.554625-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 337, - "CreatedAt": "2020-09-07T15:47:21.319715469Z", - "UpdatedAt": "2020-09-07T15:47:21.319715469Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 319, - "CreatedAt": "2020-09-07T15:47:21.30624404Z", - "UpdatedAt": "2020-09-07T15:47:21.30624404Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 284, - "CreatedAt": "2020-09-07T15:38:56.621607095Z", - "UpdatedAt": "2020-09-07T15:38:56.621607095Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 266, - "CreatedAt": "2020-09-07T15:38:56.608981483Z", - "UpdatedAt": "2020-09-07T15:38:56.608981483Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 231, - "CreatedAt": "2020-09-07T15:26:07.492775316Z", - "UpdatedAt": "2020-09-07T15:26:07.492775316Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 213, - "CreatedAt": "2020-09-07T15:26:07.479127343Z", - "UpdatedAt": "2020-09-07T15:26:07.479127343Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 178, - "CreatedAt": "2020-09-07T15:19:17.454721127Z", - "UpdatedAt": "2020-09-07T15:19:17.454721127Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 160, - "CreatedAt": "2020-09-07T15:19:17.441278472Z", - "UpdatedAt": "2020-09-07T15:19:17.441278472Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 125, - "CreatedAt": "2020-09-07T15:10:40.234375512Z", - "UpdatedAt": "2020-09-07T15:10:40.234375512Z", - "DeletedAt": null, - "smart_id": 14, + "attrs": { + "1": { "attribute_id": 1, - "name": "Read Error Rate", "value": 100, - "worst": 100, "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 107, - "CreatedAt": "2020-09-07T15:10:40.221903021Z", - "UpdatedAt": "2020-09-07T15:10:40.221903021Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, "worst": 100, - "thresh": 1, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 72, - "CreatedAt": "2020-09-06T23:14:39.838774963Z", - "UpdatedAt": "2020-09-06T23:14:39.838774963Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 1, - "name": "Read Error Rate", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.034155719633986996 + }, + "10": { + "attribute_id": 10, "value": 100, - "worst": 100, "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-06T23:14:39.828352851Z", - "UpdatedAt": "2020-09-06T23:14:39.828352851Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, "worst": 100, - "thresh": 1, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 19, - "CreatedAt": "2020-08-28T07:55:27.811031219Z", - "UpdatedAt": "2020-08-28T07:55:27.811031219Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 1, - "name": "Read Error Rate", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.05459827163896099 + }, + "12": { + "attribute_id": 12, "value": 100, + "thresh": 0, "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", + "raw_value": 9, + "raw_string": "9", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.793568936Z", - "UpdatedAt": "2020-08-28T07:55:27.793568936Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 1, - "name": "Read Error Rate", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.019835987118930823 + }, + "192": { + "attribute_id": 192, "value": 100, + "thresh": 0, "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 391, - "CreatedAt": "2020-09-08T21:39:26.566009-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566009-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 373, - "CreatedAt": "2020-09-08T21:39:26.555538-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555538-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 338, - "CreatedAt": "2020-09-07T15:47:21.31987157Z", - "UpdatedAt": "2020-09-07T15:47:21.31987157Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 320, - "CreatedAt": "2020-09-07T15:47:21.30639844Z", - "UpdatedAt": "2020-09-07T15:47:21.30639844Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 285, - "CreatedAt": "2020-09-07T15:38:56.621740196Z", - "UpdatedAt": "2020-09-07T15:38:56.621740196Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 267, - "CreatedAt": "2020-09-07T15:38:56.609155985Z", - "UpdatedAt": "2020-09-07T15:38:56.609155985Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 232, - "CreatedAt": "2020-09-07T15:26:07.49293042Z", - "UpdatedAt": "2020-09-07T15:26:07.49293042Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 214, - "CreatedAt": "2020-09-07T15:26:07.479321549Z", - "UpdatedAt": "2020-09-07T15:26:07.479321549Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 179, - "CreatedAt": "2020-09-07T15:19:17.454872527Z", - "UpdatedAt": "2020-09-07T15:19:17.454872527Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 161, - "CreatedAt": "2020-09-07T15:19:17.441578271Z", - "UpdatedAt": "2020-09-07T15:19:17.441578271Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 126, - "CreatedAt": "2020-09-07T15:10:40.234501713Z", - "UpdatedAt": "2020-09-07T15:10:40.234501713Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 108, - "CreatedAt": "2020-09-07T15:10:40.222051722Z", - "UpdatedAt": "2020-09-07T15:10:40.222051722Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 73, - "CreatedAt": "2020-09-06T23:14:39.838895667Z", - "UpdatedAt": "2020-09-06T23:14:39.838895667Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-06T23:14:39.828477555Z", - "UpdatedAt": "2020-09-06T23:14:39.828477555Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 20, - "CreatedAt": "2020-08-28T07:55:27.81120328Z", - "UpdatedAt": "2020-08-28T07:55:27.81120328Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.793695119Z", - "UpdatedAt": "2020-08-28T07:55:27.793695119Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 392, - "CreatedAt": "2020-09-08T21:39:26.566086-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566086-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.11452195377351217, - "history": [{ - "ID": 374, - "CreatedAt": "2020-09-08T21:39:26.555647-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555647-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 339, - "CreatedAt": "2020-09-07T15:47:21.31996407Z", - "UpdatedAt": "2020-09-07T15:47:21.31996407Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 321, - "CreatedAt": "2020-09-07T15:47:21.30649104Z", - "UpdatedAt": "2020-09-07T15:47:21.30649104Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 286, - "CreatedAt": "2020-09-07T15:38:56.621825497Z", - "UpdatedAt": "2020-09-07T15:38:56.621825497Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 268, - "CreatedAt": "2020-09-07T15:38:56.609869491Z", - "UpdatedAt": "2020-09-07T15:38:56.609869491Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 233, - "CreatedAt": "2020-09-07T15:26:07.493026823Z", - "UpdatedAt": "2020-09-07T15:26:07.493026823Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 215, - "CreatedAt": "2020-09-07T15:26:07.479457552Z", - "UpdatedAt": "2020-09-07T15:26:07.479457552Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 180, - "CreatedAt": "2020-09-07T15:19:17.454960826Z", - "UpdatedAt": "2020-09-07T15:19:17.454960826Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 162, - "CreatedAt": "2020-09-07T15:19:17.441750771Z", - "UpdatedAt": "2020-09-07T15:19:17.441750771Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 127, - "CreatedAt": "2020-09-07T15:10:40.234580613Z", - "UpdatedAt": "2020-09-07T15:10:40.234580613Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 109, - "CreatedAt": "2020-09-07T15:10:40.222249924Z", - "UpdatedAt": "2020-09-07T15:10:40.222249924Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 74, - "CreatedAt": "2020-09-06T23:14:39.838970169Z", - "UpdatedAt": "2020-09-06T23:14:39.838970169Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-06T23:14:39.828556257Z", - "UpdatedAt": "2020-09-06T23:14:39.828556257Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 21, - "CreatedAt": "2020-08-28T07:55:27.811301517Z", - "UpdatedAt": "2020-08-28T07:55:27.811301517Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.793803735Z", - "UpdatedAt": "2020-08-28T07:55:27.793803735Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 393, - "CreatedAt": "2020-09-08T21:39:26.56616-07:00", - "UpdatedAt": "2020-09-08T21:39:26.56616-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01989335424860646, - "history": [{ - "ID": 375, - "CreatedAt": "2020-09-08T21:39:26.555728-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555728-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 340, - "CreatedAt": "2020-09-07T15:47:21.32004967Z", - "UpdatedAt": "2020-09-07T15:47:21.32004967Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 322, - "CreatedAt": "2020-09-07T15:47:21.30657324Z", - "UpdatedAt": "2020-09-07T15:47:21.30657324Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 287, - "CreatedAt": "2020-09-07T15:38:56.621906897Z", - "UpdatedAt": "2020-09-07T15:38:56.621906897Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 269, - "CreatedAt": "2020-09-07T15:38:56.609959692Z", - "UpdatedAt": "2020-09-07T15:38:56.609959692Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 234, - "CreatedAt": "2020-09-07T15:26:07.493143826Z", - "UpdatedAt": "2020-09-07T15:26:07.493143826Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 216, - "CreatedAt": "2020-09-07T15:26:07.479584956Z", - "UpdatedAt": "2020-09-07T15:26:07.479584956Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 181, - "CreatedAt": "2020-09-07T15:19:17.455045926Z", - "UpdatedAt": "2020-09-07T15:19:17.455045926Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 163, - "CreatedAt": "2020-09-07T15:19:17.442228869Z", - "UpdatedAt": "2020-09-07T15:19:17.442228869Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 128, - "CreatedAt": "2020-09-07T15:10:40.234652914Z", - "UpdatedAt": "2020-09-07T15:10:40.234652914Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 110, - "CreatedAt": "2020-09-07T15:10:40.222378024Z", - "UpdatedAt": "2020-09-07T15:10:40.222378024Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 75, - "CreatedAt": "2020-09-06T23:14:39.839060472Z", - "UpdatedAt": "2020-09-06T23:14:39.839060472Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-06T23:14:39.82862886Z", - "UpdatedAt": "2020-09-06T23:14:39.82862886Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 22, - "CreatedAt": "2020-08-28T07:55:27.811385053Z", - "UpdatedAt": "2020-08-28T07:55:27.811385053Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.79389462Z", - "UpdatedAt": "2020-08-28T07:55:27.79389462Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 394, - "CreatedAt": "2020-09-08T21:39:26.566242-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566242-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025169175350572493, - "history": [{ - "ID": 376, - "CreatedAt": "2020-09-08T21:39:26.555865-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555865-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 341, - "CreatedAt": "2020-09-07T15:47:21.32013207Z", - "UpdatedAt": "2020-09-07T15:47:21.32013207Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 323, - "CreatedAt": "2020-09-07T15:47:21.306652041Z", - "UpdatedAt": "2020-09-07T15:47:21.306652041Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 288, - "CreatedAt": "2020-09-07T15:38:56.621982198Z", - "UpdatedAt": "2020-09-07T15:38:56.621982198Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 270, - "CreatedAt": "2020-09-07T15:38:56.610037693Z", - "UpdatedAt": "2020-09-07T15:38:56.610037693Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 235, - "CreatedAt": "2020-09-07T15:26:07.493235628Z", - "UpdatedAt": "2020-09-07T15:26:07.493235628Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 217, - "CreatedAt": "2020-09-07T15:26:07.479976967Z", - "UpdatedAt": "2020-09-07T15:26:07.479976967Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 182, - "CreatedAt": "2020-09-07T15:19:17.455121626Z", - "UpdatedAt": "2020-09-07T15:19:17.455121626Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 164, - "CreatedAt": "2020-09-07T15:19:17.442543768Z", - "UpdatedAt": "2020-09-07T15:19:17.442543768Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 129, - "CreatedAt": "2020-09-07T15:10:40.234722314Z", - "UpdatedAt": "2020-09-07T15:10:40.234722314Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 111, - "CreatedAt": "2020-09-07T15:10:40.222455425Z", - "UpdatedAt": "2020-09-07T15:10:40.222455425Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 76, - "CreatedAt": "2020-09-06T23:14:39.839234477Z", - "UpdatedAt": "2020-09-06T23:14:39.839234477Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-06T23:14:39.828698262Z", - "UpdatedAt": "2020-09-06T23:14:39.828698262Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 23, - "CreatedAt": "2020-08-28T07:55:27.811468471Z", - "UpdatedAt": "2020-08-28T07:55:27.811468471Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.793989682Z", - "UpdatedAt": "2020-08-28T07:55:27.793989682Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 395, - "CreatedAt": "2020-09-08T21:39:26.566309-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566309-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01087335627722523, - "history": [{ - "ID": 377, - "CreatedAt": "2020-09-08T21:39:26.555941-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555941-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 342, - "CreatedAt": "2020-09-07T15:47:21.320264671Z", - "UpdatedAt": "2020-09-07T15:47:21.320264671Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 324, - "CreatedAt": "2020-09-07T15:47:21.307035342Z", - "UpdatedAt": "2020-09-07T15:47:21.307035342Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 289, - "CreatedAt": "2020-09-07T15:38:56.622059399Z", - "UpdatedAt": "2020-09-07T15:38:56.622059399Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 271, - "CreatedAt": "2020-09-07T15:38:56.610108993Z", - "UpdatedAt": "2020-09-07T15:38:56.610108993Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 236, - "CreatedAt": "2020-09-07T15:26:07.493371532Z", - "UpdatedAt": "2020-09-07T15:26:07.493371532Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 218, - "CreatedAt": "2020-09-07T15:26:07.480271875Z", - "UpdatedAt": "2020-09-07T15:26:07.480271875Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 183, - "CreatedAt": "2020-09-07T15:19:17.455196926Z", - "UpdatedAt": "2020-09-07T15:19:17.455196926Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 165, - "CreatedAt": "2020-09-07T15:19:17.442652368Z", - "UpdatedAt": "2020-09-07T15:19:17.442652368Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 130, - "CreatedAt": "2020-09-07T15:10:40.234829815Z", - "UpdatedAt": "2020-09-07T15:10:40.234829815Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 112, - "CreatedAt": "2020-09-07T15:10:40.222525726Z", - "UpdatedAt": "2020-09-07T15:10:40.222525726Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 77, - "CreatedAt": "2020-09-06T23:14:39.839317879Z", - "UpdatedAt": "2020-09-06T23:14:39.839317879Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-06T23:14:39.828766564Z", - "UpdatedAt": "2020-09-06T23:14:39.828766564Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 24, - "CreatedAt": "2020-08-28T07:55:27.811550965Z", - "UpdatedAt": "2020-08-28T07:55:27.811550965Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.794077393Z", - "UpdatedAt": "2020-08-28T07:55:27.794077393Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 396, - "CreatedAt": "2020-09-08T21:39:26.566388-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566388-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 378, - "CreatedAt": "2020-09-08T21:39:26.556011-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556011-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 343, - "CreatedAt": "2020-09-07T15:47:21.320351671Z", - "UpdatedAt": "2020-09-07T15:47:21.320351671Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 325, - "CreatedAt": "2020-09-07T15:47:21.307191042Z", - "UpdatedAt": "2020-09-07T15:47:21.307191042Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 290, - "CreatedAt": "2020-09-07T15:38:56.622135099Z", - "UpdatedAt": "2020-09-07T15:38:56.622135099Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 272, - "CreatedAt": "2020-09-07T15:38:56.610177694Z", - "UpdatedAt": "2020-09-07T15:38:56.610177694Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 237, - "CreatedAt": "2020-09-07T15:26:07.493474635Z", - "UpdatedAt": "2020-09-07T15:26:07.493474635Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 219, - "CreatedAt": "2020-09-07T15:26:07.480369577Z", - "UpdatedAt": "2020-09-07T15:26:07.480369577Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 184, - "CreatedAt": "2020-09-07T15:19:17.455270825Z", - "UpdatedAt": "2020-09-07T15:19:17.455270825Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 166, - "CreatedAt": "2020-09-07T15:19:17.442737567Z", - "UpdatedAt": "2020-09-07T15:19:17.442737567Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 131, - "CreatedAt": "2020-09-07T15:10:40.234912916Z", - "UpdatedAt": "2020-09-07T15:10:40.234912916Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 113, - "CreatedAt": "2020-09-07T15:10:40.222607826Z", - "UpdatedAt": "2020-09-07T15:10:40.222607826Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 78, - "CreatedAt": "2020-09-06T23:14:39.839390682Z", - "UpdatedAt": "2020-09-06T23:14:39.839390682Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-06T23:14:39.828832166Z", - "UpdatedAt": "2020-09-06T23:14:39.828832166Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 25, - "CreatedAt": "2020-08-28T07:55:27.811628355Z", - "UpdatedAt": "2020-08-28T07:55:27.811628355Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.794167288Z", - "UpdatedAt": "2020-08-28T07:55:27.794167288Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 397, - "CreatedAt": "2020-09-08T21:39:26.566454-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566454-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 379, - "CreatedAt": "2020-09-08T21:39:26.556082-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556082-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 344, - "CreatedAt": "2020-09-07T15:47:21.320434771Z", - "UpdatedAt": "2020-09-07T15:47:21.320434771Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 326, - "CreatedAt": "2020-09-07T15:47:21.307320542Z", - "UpdatedAt": "2020-09-07T15:47:21.307320542Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 291, - "CreatedAt": "2020-09-07T15:38:56.622211Z", - "UpdatedAt": "2020-09-07T15:38:56.622211Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 273, - "CreatedAt": "2020-09-07T15:38:56.610246595Z", - "UpdatedAt": "2020-09-07T15:38:56.610246595Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 238, - "CreatedAt": "2020-09-07T15:26:07.493636539Z", - "UpdatedAt": "2020-09-07T15:26:07.493636539Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 220, - "CreatedAt": "2020-09-07T15:26:07.48045858Z", - "UpdatedAt": "2020-09-07T15:26:07.48045858Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 185, - "CreatedAt": "2020-09-07T15:19:17.455349925Z", - "UpdatedAt": "2020-09-07T15:19:17.455349925Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 167, - "CreatedAt": "2020-09-07T15:19:17.442814567Z", - "UpdatedAt": "2020-09-07T15:19:17.442814567Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 132, - "CreatedAt": "2020-09-07T15:10:40.235014517Z", - "UpdatedAt": "2020-09-07T15:10:40.235014517Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 114, - "CreatedAt": "2020-09-07T15:10:40.222673127Z", - "UpdatedAt": "2020-09-07T15:10:40.222673127Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-06T23:14:39.839467884Z", - "UpdatedAt": "2020-09-06T23:14:39.839467884Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-06T23:14:39.828900468Z", - "UpdatedAt": "2020-09-06T23:14:39.828900468Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 26, - "CreatedAt": "2020-08-28T07:55:27.8117049Z", - "UpdatedAt": "2020-08-28T07:55:27.8117049Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.794251087Z", - "UpdatedAt": "2020-08-28T07:55:27.794251087Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 398, - "CreatedAt": "2020-09-08T21:39:26.566526-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566526-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.05459827163896099, - "history": [{ - "ID": 380, - "CreatedAt": "2020-09-08T21:39:26.556157-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556157-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 345, - "CreatedAt": "2020-09-07T15:47:21.320529071Z", - "UpdatedAt": "2020-09-07T15:47:21.320529071Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 327, - "CreatedAt": "2020-09-07T15:47:21.307449642Z", - "UpdatedAt": "2020-09-07T15:47:21.307449642Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 292, - "CreatedAt": "2020-09-07T15:38:56.622285101Z", - "UpdatedAt": "2020-09-07T15:38:56.622285101Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 274, - "CreatedAt": "2020-09-07T15:38:56.610358696Z", - "UpdatedAt": "2020-09-07T15:38:56.610358696Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 239, - "CreatedAt": "2020-09-07T15:26:07.493765343Z", - "UpdatedAt": "2020-09-07T15:26:07.493765343Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 221, - "CreatedAt": "2020-09-07T15:26:07.480546682Z", - "UpdatedAt": "2020-09-07T15:26:07.480546682Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 186, - "CreatedAt": "2020-09-07T15:19:17.455425525Z", - "UpdatedAt": "2020-09-07T15:19:17.455425525Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 168, - "CreatedAt": "2020-09-07T15:19:17.442892767Z", - "UpdatedAt": "2020-09-07T15:19:17.442892767Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 133, - "CreatedAt": "2020-09-07T15:10:40.235101017Z", - "UpdatedAt": "2020-09-07T15:10:40.235101017Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 115, - "CreatedAt": "2020-09-07T15:10:40.222780027Z", - "UpdatedAt": "2020-09-07T15:10:40.222780027Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-06T23:14:39.839545886Z", - "UpdatedAt": "2020-09-06T23:14:39.839545886Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-06T23:14:39.82896797Z", - "UpdatedAt": "2020-09-06T23:14:39.82896797Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-08-28T07:55:27.81178263Z", - "UpdatedAt": "2020-08-28T07:55:27.81178263Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.794343259Z", - "UpdatedAt": "2020-08-28T07:55:27.794343259Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 399, - "CreatedAt": "2020-09-08T21:39:26.566594-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566594-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.019835987118930823, - "history": [{ - "ID": 381, - "CreatedAt": "2020-09-08T21:39:26.556225-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556225-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 346, - "CreatedAt": "2020-09-07T15:47:21.320607871Z", - "UpdatedAt": "2020-09-07T15:47:21.320607871Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 328, - "CreatedAt": "2020-09-07T15:47:21.307575143Z", - "UpdatedAt": "2020-09-07T15:47:21.307575143Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 293, - "CreatedAt": "2020-09-07T15:38:56.622436802Z", - "UpdatedAt": "2020-09-07T15:38:56.622436802Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 275, - "CreatedAt": "2020-09-07T15:38:56.610431596Z", - "UpdatedAt": "2020-09-07T15:38:56.610431596Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 240, - "CreatedAt": "2020-09-07T15:26:07.493897347Z", - "UpdatedAt": "2020-09-07T15:26:07.493897347Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 222, - "CreatedAt": "2020-09-07T15:26:07.480631784Z", - "UpdatedAt": "2020-09-07T15:26:07.480631784Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 187, - "CreatedAt": "2020-09-07T15:19:17.455500025Z", - "UpdatedAt": "2020-09-07T15:19:17.455500025Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 169, - "CreatedAt": "2020-09-07T15:19:17.442969566Z", - "UpdatedAt": "2020-09-07T15:19:17.442969566Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 134, - "CreatedAt": "2020-09-07T15:10:40.23543132Z", - "UpdatedAt": "2020-09-07T15:10:40.23543132Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 116, - "CreatedAt": "2020-09-07T15:10:40.222855428Z", - "UpdatedAt": "2020-09-07T15:10:40.222855428Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-06T23:14:39.839623189Z", - "UpdatedAt": "2020-09-06T23:14:39.839623189Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-06T23:14:39.829035472Z", - "UpdatedAt": "2020-09-06T23:14:39.829035472Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-08-28T07:55:27.811864251Z", - "UpdatedAt": "2020-08-28T07:55:27.811864251Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.79442562Z", - "UpdatedAt": "2020-08-28T07:55:27.79442562Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 400, - "CreatedAt": "2020-09-08T21:39:26.566661-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566661-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 382, - "CreatedAt": "2020-09-08T21:39:26.556294-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556294-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 347, - "CreatedAt": "2020-09-07T15:47:21.320688272Z", - "UpdatedAt": "2020-09-07T15:47:21.320688272Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 329, - "CreatedAt": "2020-09-07T15:47:21.307698843Z", - "UpdatedAt": "2020-09-07T15:47:21.307698843Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 294, - "CreatedAt": "2020-09-07T15:38:56.622559903Z", - "UpdatedAt": "2020-09-07T15:38:56.622559903Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 276, - "CreatedAt": "2020-09-07T15:38:56.610502597Z", - "UpdatedAt": "2020-09-07T15:38:56.610502597Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 241, - "CreatedAt": "2020-09-07T15:26:07.493985749Z", - "UpdatedAt": "2020-09-07T15:26:07.493985749Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 223, - "CreatedAt": "2020-09-07T15:26:07.480743187Z", - "UpdatedAt": "2020-09-07T15:26:07.480743187Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 188, - "CreatedAt": "2020-09-07T15:19:17.455575224Z", - "UpdatedAt": "2020-09-07T15:19:17.455575224Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 170, - "CreatedAt": "2020-09-07T15:19:17.443042566Z", - "UpdatedAt": "2020-09-07T15:19:17.443042566Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 135, - "CreatedAt": "2020-09-07T15:10:40.23553022Z", - "UpdatedAt": "2020-09-07T15:10:40.23553022Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 117, - "CreatedAt": "2020-09-07T15:10:40.222932429Z", - "UpdatedAt": "2020-09-07T15:10:40.222932429Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-06T23:14:39.839696091Z", - "UpdatedAt": "2020-09-06T23:14:39.839696091Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-06T23:14:39.829103574Z", - "UpdatedAt": "2020-09-06T23:14:39.829103574Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-08-28T07:55:27.811945021Z", - "UpdatedAt": "2020-08-28T07:55:27.811945021Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.794526672Z", - "UpdatedAt": "2020-08-28T07:55:27.794526672Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 401, - "CreatedAt": "2020-09-08T21:39:26.566727-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566727-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01634692899031039, - "history": [{ - "ID": 383, - "CreatedAt": "2020-09-08T21:39:26.556363-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556363-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 348, - "CreatedAt": "2020-09-07T15:47:21.320764972Z", - "UpdatedAt": "2020-09-07T15:47:21.320764972Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 330, - "CreatedAt": "2020-09-07T15:47:21.308110544Z", - "UpdatedAt": "2020-09-07T15:47:21.308110544Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 295, - "CreatedAt": "2020-09-07T15:38:56.622638304Z", - "UpdatedAt": "2020-09-07T15:38:56.622638304Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 277, - "CreatedAt": "2020-09-07T15:38:56.610569797Z", - "UpdatedAt": "2020-09-07T15:38:56.610569797Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 242, - "CreatedAt": "2020-09-07T15:26:07.494076151Z", - "UpdatedAt": "2020-09-07T15:26:07.494076151Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 224, - "CreatedAt": "2020-09-07T15:26:07.48083529Z", - "UpdatedAt": "2020-09-07T15:26:07.48083529Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 189, - "CreatedAt": "2020-09-07T15:19:17.455652324Z", - "UpdatedAt": "2020-09-07T15:19:17.455652324Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 171, - "CreatedAt": "2020-09-07T15:19:17.443115666Z", - "UpdatedAt": "2020-09-07T15:19:17.443115666Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 136, - "CreatedAt": "2020-09-07T15:10:40.235693822Z", - "UpdatedAt": "2020-09-07T15:10:40.235693822Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 118, - "CreatedAt": "2020-09-07T15:10:40.223005329Z", - "UpdatedAt": "2020-09-07T15:10:40.223005329Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-06T23:14:39.839769893Z", - "UpdatedAt": "2020-09-06T23:14:39.839769893Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-06T23:14:39.829170476Z", - "UpdatedAt": "2020-09-06T23:14:39.829170476Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-08-28T07:55:27.812020236Z", - "UpdatedAt": "2020-08-28T07:55:27.812020236Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.794617502Z", - "UpdatedAt": "2020-08-28T07:55:27.794617502Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 402, - "CreatedAt": "2020-09-08T21:39:26.566795-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566795-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 384, - "CreatedAt": "2020-09-08T21:39:26.556431-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556431-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 349, - "CreatedAt": "2020-09-07T15:47:21.320843672Z", - "UpdatedAt": "2020-09-07T15:47:21.320843672Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 331, - "CreatedAt": "2020-09-07T15:47:21.308263444Z", - "UpdatedAt": "2020-09-07T15:47:21.308263444Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 296, - "CreatedAt": "2020-09-07T15:38:56.622711005Z", - "UpdatedAt": "2020-09-07T15:38:56.622711005Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 278, - "CreatedAt": "2020-09-07T15:38:56.610644498Z", - "UpdatedAt": "2020-09-07T15:38:56.610644498Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 243, - "CreatedAt": "2020-09-07T15:26:07.494160354Z", - "UpdatedAt": "2020-09-07T15:26:07.494160354Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 225, - "CreatedAt": "2020-09-07T15:26:07.480920492Z", - "UpdatedAt": "2020-09-07T15:26:07.480920492Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 190, - "CreatedAt": "2020-09-07T15:19:17.455725424Z", - "UpdatedAt": "2020-09-07T15:19:17.455725424Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 172, - "CreatedAt": "2020-09-07T15:19:17.443238266Z", - "UpdatedAt": "2020-09-07T15:19:17.443238266Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 137, - "CreatedAt": "2020-09-07T15:10:40.235762522Z", - "UpdatedAt": "2020-09-07T15:10:40.235762522Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 119, - "CreatedAt": "2020-09-07T15:10:40.22311063Z", - "UpdatedAt": "2020-09-07T15:10:40.22311063Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-06T23:14:39.839842395Z", - "UpdatedAt": "2020-09-06T23:14:39.839842395Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 66, - "CreatedAt": "2020-09-06T23:14:39.829237678Z", - "UpdatedAt": "2020-09-06T23:14:39.829237678Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-08-28T07:55:27.812094858Z", - "UpdatedAt": "2020-08-28T07:55:27.812094858Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.794713765Z", - "UpdatedAt": "2020-08-28T07:55:27.794713765Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 403, - "CreatedAt": "2020-09-08T21:39:26.566869-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566869-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32, - "status": "passed", - "history": [{ - "ID": 385, - "CreatedAt": "2020-09-08T21:39:26.556503-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556503-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 350, - "CreatedAt": "2020-09-07T15:47:21.320921272Z", - "UpdatedAt": "2020-09-07T15:47:21.320921272Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 332, - "CreatedAt": "2020-09-07T15:47:21.308359744Z", - "UpdatedAt": "2020-09-07T15:47:21.308359744Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 297, - "CreatedAt": "2020-09-07T15:38:56.622787005Z", - "UpdatedAt": "2020-09-07T15:38:56.622787005Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 279, - "CreatedAt": "2020-09-07T15:38:56.610731899Z", - "UpdatedAt": "2020-09-07T15:38:56.610731899Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 244, - "CreatedAt": "2020-09-07T15:26:07.494245356Z", - "UpdatedAt": "2020-09-07T15:26:07.494245356Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 226, - "CreatedAt": "2020-09-07T15:26:07.481005295Z", - "UpdatedAt": "2020-09-07T15:26:07.481005295Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 191, - "CreatedAt": "2020-09-07T15:19:17.455795324Z", - "UpdatedAt": "2020-09-07T15:19:17.455795324Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 173, - "CreatedAt": "2020-09-07T15:19:17.443317065Z", - "UpdatedAt": "2020-09-07T15:19:17.443317065Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 138, - "CreatedAt": "2020-09-07T15:10:40.235933223Z", - "UpdatedAt": "2020-09-07T15:10:40.235933223Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 120, - "CreatedAt": "2020-09-07T15:10:40.223208631Z", - "UpdatedAt": "2020-09-07T15:10:40.223208631Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 85, - "CreatedAt": "2020-09-06T23:14:39.839917897Z", - "UpdatedAt": "2020-09-06T23:14:39.839917897Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 67, - "CreatedAt": "2020-09-06T23:14:39.82930548Z", - "UpdatedAt": "2020-09-06T23:14:39.82930548Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 32, - "CreatedAt": "2020-08-28T07:55:27.812170947Z", - "UpdatedAt": "2020-08-28T07:55:27.812170947Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 14, - "CreatedAt": "2020-08-28T07:55:27.794809537Z", - "UpdatedAt": "2020-08-28T07:55:27.794809537Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }] - }, { - "ID": 404, - "CreatedAt": "2020-09-08T21:39:26.566946-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566946-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.007389855800729792, - "history": [{ - "ID": 386, - "CreatedAt": "2020-09-08T21:39:26.556577-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556577-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 351, - "CreatedAt": "2020-09-07T15:47:21.320997672Z", - "UpdatedAt": "2020-09-07T15:47:21.320997672Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 333, - "CreatedAt": "2020-09-07T15:47:21.308448945Z", - "UpdatedAt": "2020-09-07T15:47:21.308448945Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 298, - "CreatedAt": "2020-09-07T15:38:56.622861506Z", - "UpdatedAt": "2020-09-07T15:38:56.622861506Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 280, - "CreatedAt": "2020-09-07T15:38:56.6108076Z", - "UpdatedAt": "2020-09-07T15:38:56.6108076Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 245, - "CreatedAt": "2020-09-07T15:26:07.494329358Z", - "UpdatedAt": "2020-09-07T15:26:07.494329358Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 227, - "CreatedAt": "2020-09-07T15:26:07.481094797Z", - "UpdatedAt": "2020-09-07T15:26:07.481094797Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 192, - "CreatedAt": "2020-09-07T15:19:17.455872523Z", - "UpdatedAt": "2020-09-07T15:19:17.455872523Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 174, - "CreatedAt": "2020-09-07T15:19:17.443397465Z", - "UpdatedAt": "2020-09-07T15:19:17.443397465Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 139, - "CreatedAt": "2020-09-07T15:10:40.236025724Z", - "UpdatedAt": "2020-09-07T15:10:40.236025724Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 121, - "CreatedAt": "2020-09-07T15:10:40.223270031Z", - "UpdatedAt": "2020-09-07T15:10:40.223270031Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-06T23:14:39.8399883Z", - "UpdatedAt": "2020-09-06T23:14:39.8399883Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 68, - "CreatedAt": "2020-09-06T23:14:39.829370082Z", - "UpdatedAt": "2020-09-06T23:14:39.829370082Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-08-28T07:55:27.812246492Z", - "UpdatedAt": "2020-08-28T07:55:27.812246492Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 15, - "CreatedAt": "2020-08-28T07:55:27.794890531Z", - "UpdatedAt": "2020-08-28T07:55:27.794890531Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 405, - "CreatedAt": "2020-09-08T21:39:26.567013-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567013-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025540791394761345, - "history": [{ - "ID": 387, - "CreatedAt": "2020-09-08T21:39:26.55665-07:00", - "UpdatedAt": "2020-09-08T21:39:26.55665-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 352, - "CreatedAt": "2020-09-07T15:47:21.321080072Z", - "UpdatedAt": "2020-09-07T15:47:21.321080072Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 334, - "CreatedAt": "2020-09-07T15:47:21.308534945Z", - "UpdatedAt": "2020-09-07T15:47:21.308534945Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 299, - "CreatedAt": "2020-09-07T15:38:56.622933307Z", - "UpdatedAt": "2020-09-07T15:38:56.622933307Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 281, - "CreatedAt": "2020-09-07T15:38:56.6108811Z", - "UpdatedAt": "2020-09-07T15:38:56.6108811Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 246, - "CreatedAt": "2020-09-07T15:26:07.494412661Z", - "UpdatedAt": "2020-09-07T15:26:07.494412661Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 228, - "CreatedAt": "2020-09-07T15:26:07.481180499Z", - "UpdatedAt": "2020-09-07T15:26:07.481180499Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 193, - "CreatedAt": "2020-09-07T15:19:17.455947323Z", - "UpdatedAt": "2020-09-07T15:19:17.455947323Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 175, - "CreatedAt": "2020-09-07T15:19:17.443471765Z", - "UpdatedAt": "2020-09-07T15:19:17.443471765Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 140, - "CreatedAt": "2020-09-07T15:10:40.236107525Z", - "UpdatedAt": "2020-09-07T15:10:40.236107525Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 122, - "CreatedAt": "2020-09-07T15:10:40.223335031Z", - "UpdatedAt": "2020-09-07T15:10:40.223335031Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-06T23:14:39.840059202Z", - "UpdatedAt": "2020-09-06T23:14:39.840059202Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 69, - "CreatedAt": "2020-09-06T23:14:39.829440284Z", - "UpdatedAt": "2020-09-06T23:14:39.829440284Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-08-28T07:55:27.812321365Z", - "UpdatedAt": "2020-08-28T07:55:27.812321365Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 16, - "CreatedAt": "2020-08-28T07:55:27.794983884Z", - "UpdatedAt": "2020-08-28T07:55:27.794983884Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 406, - "CreatedAt": "2020-09-08T21:39:26.567084-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567084-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028675322159886437, - "history": [{ - "ID": 388, - "CreatedAt": "2020-09-08T21:39:26.556721-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556721-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 353, - "CreatedAt": "2020-09-07T15:47:21.321156173Z", - "UpdatedAt": "2020-09-07T15:47:21.321156173Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 335, - "CreatedAt": "2020-09-07T15:47:21.308621645Z", - "UpdatedAt": "2020-09-07T15:47:21.308621645Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 300, - "CreatedAt": "2020-09-07T15:38:56.623001907Z", - "UpdatedAt": "2020-09-07T15:38:56.623001907Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 282, - "CreatedAt": "2020-09-07T15:38:56.610954501Z", - "UpdatedAt": "2020-09-07T15:38:56.610954501Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 247, - "CreatedAt": "2020-09-07T15:26:07.494502663Z", - "UpdatedAt": "2020-09-07T15:26:07.494502663Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 329, + "raw_string": "329", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 229, - "CreatedAt": "2020-09-07T15:26:07.481263302Z", - "UpdatedAt": "2020-09-07T15:26:07.481263302Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01634692899031039 + }, + "193": { + "attribute_id": 193, "value": 100, + "thresh": 0, "worst": 100, + "raw_value": 329, + "raw_string": "329", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "194": { + "attribute_id": 194, + "value": 51, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 51, + "raw_value": 163210330144, + "raw_string": "32 (Min/Max 24/38)", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 194, - "CreatedAt": "2020-09-07T15:19:17.456016623Z", - "UpdatedAt": "2020-09-07T15:19:17.456016623Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 32, + "status": 0 + }, + "196": { + "attribute_id": 196, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 176, - "CreatedAt": "2020-09-07T15:19:17.443544465Z", - "UpdatedAt": "2020-09-07T15:19:17.443544465Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.007389855800729792 + }, + "197": { + "attribute_id": 197, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 141, - "CreatedAt": "2020-09-07T15:10:40.236230025Z", - "UpdatedAt": "2020-09-07T15:10:40.236230025Z", - "DeletedAt": null, - "smart_id": 14, + "transformed_value": 0, + "status": 0, + "failure_rate": 0.025540791394761345 + }, + "198": { "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 123, - "CreatedAt": "2020-09-07T15:10:40.223397332Z", - "UpdatedAt": "2020-09-07T15:10:40.223397332Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.028675322159886437 + }, + "199": { + "attribute_id": 199, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-06T23:14:39.840162905Z", - "UpdatedAt": "2020-09-06T23:14:39.840162905Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0 + }, + "2": { + "attribute_id": 2, + "value": 135, + "thresh": 54, + "worst": 135, + "raw_value": 108, + "raw_string": "108", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "22": { + "attribute_id": 22, "value": 100, + "thresh": 25, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 100, + "raw_string": "100", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 70, - "CreatedAt": "2020-09-06T23:14:39.829535987Z", - "UpdatedAt": "2020-09-06T23:14:39.829535987Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0 + }, + "3": { + "attribute_id": 3, + "value": 81, + "thresh": 1, + "worst": 81, + "raw_value": 30089675132, + "raw_string": "380 (Average 380)", + "when_failed": "", + "transformed_value": 0, + "status": 2, + "status_reason": "Observed Failure Rate for Attribute is greater than 10%", + "failure_rate": 0.11452195377351217 + }, + "4": { + "attribute_id": 4, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-08-28T07:55:27.812396538Z", - "UpdatedAt": "2020-08-28T07:55:27.812396538Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01989335424860646 + }, + "5": { + "attribute_id": 5, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 17, - "CreatedAt": "2020-08-28T07:55:27.795066287Z", - "UpdatedAt": "2020-08-28T07:55:27.795066287Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.025169175350572493 + }, + "7": { + "attribute_id": 7, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 407, - "CreatedAt": "2020-09-08T21:39:26.567154-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567154-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 389, - "CreatedAt": "2020-09-08T21:39:26.556788-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556788-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01087335627722523 + }, + "8": { + "attribute_id": 8, + "value": 133, + "thresh": 20, + "worst": 133, + "raw_value": 18, + "raw_string": "18", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "9": { + "attribute_id": 9, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 1730, + "raw_string": "1730", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 354, - "CreatedAt": "2020-09-07T15:47:21.321272273Z", - "UpdatedAt": "2020-09-07T15:47:21.321272273Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 + }, { + "date": "2021-10-24T23:20:44Z", + "device_wwn": "0x5000cca264eb01d7", + "device_protocol": "ATA", + "temp": 32, + "power_on_hours": 1730, + "power_cycle_count": 9, + "attrs": { + "1": { + "attribute_id": 1, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 336, - "CreatedAt": "2020-09-07T15:47:21.308717545Z", - "UpdatedAt": "2020-09-07T15:47:21.308717545Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.034155719633986996 + }, + "10": { + "attribute_id": 10, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 301, - "CreatedAt": "2020-09-07T15:38:56.623082408Z", - "UpdatedAt": "2020-09-07T15:38:56.623082408Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.05459827163896099 + }, + "12": { + "attribute_id": 12, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 283, - "CreatedAt": "2020-09-07T15:38:56.611027902Z", - "UpdatedAt": "2020-09-07T15:38:56.611027902Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.019835987118930823 + }, + "192": { + "attribute_id": 192, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 329, + "raw_string": "329", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 248, - "CreatedAt": "2020-09-07T15:26:07.494585565Z", - "UpdatedAt": "2020-09-07T15:26:07.494585565Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01634692899031039 + }, + "193": { + "attribute_id": 193, "value": 100, + "thresh": 0, "worst": 100, + "raw_value": 329, + "raw_string": "329", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "194": { + "attribute_id": 194, + "value": 51, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 51, + "raw_value": 163210330144, + "raw_string": "32 (Min/Max 24/38)", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 230, - "CreatedAt": "2020-09-07T15:26:07.481350204Z", - "UpdatedAt": "2020-09-07T15:26:07.481350204Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 32, + "status": 0 + }, + "196": { + "attribute_id": 196, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 195, - "CreatedAt": "2020-09-07T15:19:17.456093323Z", - "UpdatedAt": "2020-09-07T15:19:17.456093323Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.007389855800729792 + }, + "197": { + "attribute_id": 197, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 177, - "CreatedAt": "2020-09-07T15:19:17.443622964Z", - "UpdatedAt": "2020-09-07T15:19:17.443622964Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.025540791394761345 + }, + "198": { + "attribute_id": 198, "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 142, - "CreatedAt": "2020-09-07T15:10:40.236299626Z", - "UpdatedAt": "2020-09-07T15:10:40.236299626Z", - "DeletedAt": null, - "smart_id": 14, + "transformed_value": 0, + "status": 0, + "failure_rate": 0.028675322159886437 + }, + "199": { "attribute_id": 199, - "name": "UltraDMA CRC Error Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 124, - "CreatedAt": "2020-09-07T15:10:40.223460532Z", - "UpdatedAt": "2020-09-07T15:10:40.223460532Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0 + }, + "2": { + "attribute_id": 2, + "value": 135, + "thresh": 54, + "worst": 135, + "raw_value": 108, + "raw_string": "108", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "22": { + "attribute_id": 22, "value": 100, + "thresh": 25, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 100, + "raw_string": "100", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-06T23:14:39.840242107Z", - "UpdatedAt": "2020-09-06T23:14:39.840242107Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0 + }, + "3": { + "attribute_id": 3, + "value": 81, + "thresh": 1, + "worst": 81, + "raw_value": 30089675132, + "raw_string": "380 (Average 380)", + "when_failed": "", + "transformed_value": 0, + "status": 2, + "status_reason": "Observed Failure Rate for Attribute is greater than 10%", + "failure_rate": 0.11452195377351217 + }, + "4": { + "attribute_id": 4, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 71, - "CreatedAt": "2020-09-06T23:14:39.82963599Z", - "UpdatedAt": "2020-09-06T23:14:39.82963599Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01989335424860646 + }, + "5": { + "attribute_id": 5, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-08-28T07:55:27.812495499Z", - "UpdatedAt": "2020-08-28T07:55:27.812495499Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.025169175350572493 + }, + "7": { + "attribute_id": 7, "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 18, - "CreatedAt": "2020-08-28T07:55:27.795190163Z", - "UpdatedAt": "2020-08-28T07:55:27.795190163Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01087335627722523 + }, + "8": { + "attribute_id": 8, + "value": 133, + "thresh": 20, + "worst": 133, + "raw_value": 18, + "raw_string": "18", + "when_failed": "", + "transformed_value": 0, + "status": 0 + }, + "9": { + "attribute_id": 9, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 1730, + "raw_string": "1730", "when_failed": "", - "transformed_value": 0 - }] - }], - "nvme_attributes": [], - "scsi_attributes": [] + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 }] - }, "metadata": { + }, + "metadata": { "1": { + "display_name": "Read Error Rate", "ideal": "low", "critical": false, "description": "(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -4420,12 +485,22 @@ export const sdb = { "high": 125, "annual_failure_rate": 0.06390002135229157, "error_interval": [0.05852004676110847, 0.06964160930553712] - }, {"low": 125, "high": 140, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 125, + "high": 140, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 140, "high": 155, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 155, "high": 170, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 155, + "high": 170, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 170, "high": 185, "annual_failure_rate": 0, @@ -4439,6 +514,7 @@ export const sdb = { "display_type": "normalized" }, "10": { + "display_name": "Spin Retry Count", "ideal": "low", "critical": true, "description": "Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", @@ -4456,6 +532,7 @@ export const sdb = { "display_type": "raw" }, "11": { + "display_name": "Recalibration Retries or Calibration Retry Count", "ideal": "low", "critical": false, "description": "This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", @@ -4469,17 +546,32 @@ export const sdb = { "high": 80, "annual_failure_rate": 0.5555555555555556, "error_interval": [0.014065448880161053, 3.095357439410498] - }, {"low": 80, "high": 160, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 80, + "high": 160, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 160, "high": 240, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 240, "high": 320, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 240, + "high": 320, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 320, "high": 400, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 400, "high": 480, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 400, + "high": 480, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 480, "high": 560, "annual_failure_rate": 0, @@ -4488,6 +580,7 @@ export const sdb = { "display_type": "raw" }, "12": { + "display_name": "Power Cycle Count", "ideal": "low", "critical": false, "description": "This attribute indicates the count of full hard disk power on/off cycles.", @@ -4530,79 +623,98 @@ export const sdb = { "display_type": "raw" }, "13": { + "display_name": "Soft Read Error Rate", "ideal": "low", "critical": false, "description": "Uncorrected read errors reported to the operating system.", "display_type": "normalized" }, - "170": {"ideal": "", "critical": false, "description": "See attribute E8.", "display_type": "normalized"}, + "170": { + "display_name": "Available Reserved Space", + "ideal": "", + "critical": false, + "description": "See attribute E8.", + "display_type": "normalized" + }, "171": { + "display_name": "SSD Program Fail Count", "ideal": "", "critical": false, "description": "(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.", "display_type": "normalized" }, "172": { + "display_name": "SSD Erase Fail Count", "ideal": "", "critical": false, "description": "(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.", "display_type": "normalized" }, "173": { + "display_name": "SSD Wear Leveling Count", "ideal": "", "critical": false, "description": "Counts the maximum worst erase count on any block.", "display_type": "normalized" }, "174": { + "display_name": "Unexpected Power Loss Count", "ideal": "", "critical": false, "description": "Also known as \"Power-off Retract Count\" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an \"unclean shutdown\" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.", "display_type": "" }, "175": { + "display_name": "Power Loss Protection Failure", "ideal": "", "critical": false, "description": "Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.", "display_type": "normalized" }, "176": { + "display_name": "Erase Fail Count", "ideal": "", "critical": false, "description": "S.M.A.R.T. parameter indicates a number of flash erase command failures.", "display_type": "normalized" }, "177": { + "display_name": "Wear Range Delta", "ideal": "", "critical": false, "description": "Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ", "display_type": "normalized" }, "179": { + "display_name": "Used Reserved Block Count Total", "ideal": "", "critical": false, "description": "Pre-Fail attribute used at least in Samsung devices.", "display_type": "normalized" }, "180": { + "display_name": "Unused Reserved Block Count Total", "ideal": "", "critical": false, "description": "\"Pre-Fail\" attribute used at least in HP devices. ", "display_type": "normalized" }, "181": { + "display_name": "Program Fail Count Total", "ideal": "", "critical": false, "description": "Total number of Flash program operation failures since the drive was deployed.", "display_type": "normalized" }, "182": { + "display_name": "Erase Fail Count", "ideal": "", "critical": false, "description": "\"Pre-Fail\" Attribute used at least in Samsung devices.", "display_type": "normalized" }, "183": { + "display_name": "SATA Downshift Error Count or Runtime Bad Block", "ideal": "low", "critical": false, "description": "Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.", @@ -4646,10 +758,16 @@ export const sdb = { "high": 130, "annual_failure_rate": 0.40299684542586756, "error_interval": [0.16202563309223209, 0.8303275247667772] - }, {"low": 130, "high": 260, "annual_failure_rate": 0, "error_interval": [0, 0]}], + }, { + "low": 130, + "high": 260, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "184": { + "display_name": "End-to-End error", "ideal": "low", "critical": true, "description": "This attribute is a part of Hewlett-Packard\"s SMART IV technology, as well as part of other vendors\" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive\"s cache RAM", @@ -4658,12 +776,22 @@ export const sdb = { "high": 94, "annual_failure_rate": 1.631212012870933, "error_interval": [1.055634407303844, 2.407990716767714] - }, {"low": 94, "high": 95, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 94, + "high": 95, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 95, "high": 96, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 96, "high": 97, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 96, + "high": 97, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 97, "high": 97, "annual_failure_rate": 0, @@ -4687,18 +815,21 @@ export const sdb = { "display_type": "normalized" }, "185": { + "display_name": "Head Stability", "ideal": "", "critical": false, "description": "Western Digital attribute.", "display_type": "normalized" }, "186": { + "display_name": "Induced Op-Vibration Detection", "ideal": "", "critical": false, "description": "Western Digital attribute.", "display_type": "normalized" }, "187": { + "display_name": "Reported Uncorrectable Errors", "ideal": "low", "critical": true, "description": "The count of errors that could not be recovered using hardware ECC (see attribute 195).", @@ -4751,6 +882,7 @@ export const sdb = { "display_type": "raw" }, "188": { + "display_name": "Command Timeout", "ideal": "low", "critical": true, "description": "The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.", @@ -4803,6 +935,7 @@ export const sdb = { "display_type": "raw" }, "189": { + "display_name": "High Fly Writes", "ideal": "low", "critical": false, "description": "HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.", @@ -4850,18 +983,21 @@ export const sdb = { "display_type": "raw" }, "190": { + "display_name": "Temperature Difference", "ideal": "", "critical": false, "description": "Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.", "display_type": "normalized" }, "191": { + "display_name": "G-sense Error Rate", "ideal": "low", "critical": false, "description": "The count of errors resulting from externally induced shock and vibration. ", "display_type": "normalized" }, "192": { + "display_name": "Power-off Retract Count", "ideal": "low", "critical": false, "description": "Number of power-off or emergency retract cycles.", @@ -4909,12 +1045,14 @@ export const sdb = { "display_type": "raw" }, "193": { + "display_name": "Load Cycle Count", "ideal": "low", "critical": false, "description": "Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.", "display_type": "normalized" }, "194": { + "display_name": "Temperature", "ideal": "low", "critical": false, "description": "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", @@ -4922,6 +1060,7 @@ export const sdb = { "display_type": "transformed" }, "195": { + "display_name": "Hardware ECC Recovered", "ideal": "", "critical": false, "description": "(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -4945,12 +1084,22 @@ export const sdb = { "high": 60, "annual_failure_rate": 0.05672658497265746, "error_interval": [0.043182904776447234, 0.07317316161437043] - }, {"low": 60, "high": 72, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 60, + "high": 72, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 72, "high": 84, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 84, "high": 96, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 84, + "high": 96, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 96, "high": 108, "annual_failure_rate": 0.04074570216566197, @@ -4959,6 +1108,7 @@ export const sdb = { "display_type": "normalized" }, "196": { + "display_name": "Reallocation Event Count", "ideal": "low", "critical": true, "description": "Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.", @@ -5011,6 +1161,7 @@ export const sdb = { "display_type": "raw" }, "197": { + "display_name": "Current Pending Sector Count", "ideal": "low", "critical": true, "description": "Count of \"unstable\" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it\"s written.", @@ -5063,6 +1214,7 @@ export const sdb = { "display_type": "raw" }, "198": { + "display_name": "(Offline) Uncorrectable Sector Count", "ideal": "low", "critical": true, "description": "The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.", @@ -5115,6 +1267,7 @@ export const sdb = { "display_type": "raw" }, "199": { + "display_name": "UltraDMA CRC Error Count", "ideal": "low", "critical": false, "description": "The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).", @@ -5167,246 +1320,287 @@ export const sdb = { "display_type": "raw" }, "2": { + "display_name": "Throughput Performance", "ideal": "high", "critical": false, "description": "Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.", "display_type": "normalized" }, "200": { + "display_name": "Multi-Zone Error Rate", "ideal": "low", "critical": false, "description": "The count of errors found when writing a sector. The higher the value, the worse the disk\"s mechanical condition is.", "display_type": "normalized" }, "201": { + "display_name": "Soft Read Error Rate", "ideal": "low", "critical": true, "description": "Count indicates the number of uncorrectable software read errors.", "display_type": "normalized" }, "202": { + "display_name": "Data Address Mark errors", "ideal": "low", "critical": false, "description": "Count of Data Address Mark errors (or vendor-specific).", "display_type": "normalized" }, "203": { + "display_name": "Run Out Cancel", "ideal": "low", "critical": false, "description": "The number of errors caused by incorrect checksum during the error correction.", "display_type": "normalized" }, "204": { + "display_name": "Soft ECC Correction", "ideal": "low", "critical": false, "description": "Count of errors corrected by the internal error correction software.", "display_type": "" }, "205": { + "display_name": "Thermal Asperity Rate", "ideal": "low", "critical": false, "description": "Count of errors due to high temperature.", "display_type": "normalized" }, "206": { + "display_name": "Flying Height", "ideal": "", "critical": false, "description": "Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.", "display_type": "normalized" }, "207": { + "display_name": "Spin High Current", "ideal": "low", "critical": false, "description": "Amount of surge current used to spin up the drive.", "display_type": "normalized" }, "208": { + "display_name": "Spin Buzz", "ideal": "", "critical": false, "description": "Count of buzz routines needed to spin up the drive due to insufficient power.", "display_type": "normalized" }, "209": { + "display_name": "Offline Seek Performance", "ideal": "", "critical": false, "description": "Drive\"s seek performance during its internal tests.", "display_type": "normalized" }, "210": { + "display_name": "Vibration During Write", "ideal": "", "critical": false, "description": "Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.", "display_type": "normalized" }, "211": { + "display_name": "Vibration During Write", "ideal": "", "critical": false, "description": "A recording of a vibration encountered during write operations.", "display_type": "normalized" }, "212": { + "display_name": "Shock During Write", "ideal": "", "critical": false, "description": "A recording of shock encountered during write operations.", "display_type": "normalized" }, "22": { + "display_name": "Current Helium Level", "ideal": "high", "critical": false, "description": "Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.", "display_type": "normalized" }, "220": { + "display_name": "Disk Shift", "ideal": "low", "critical": false, "description": "Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.", "display_type": "normalized" }, "221": { + "display_name": "G-Sense Error Rate", "ideal": "low", "critical": false, "description": "The count of errors resulting from externally induced shock and vibration.", "display_type": "normalized" }, "222": { + "display_name": "Loaded Hours", "ideal": "", "critical": false, "description": "Time spent operating under data load (movement of magnetic head armature).", "display_type": "normalized" }, "223": { + "display_name": "Load/Unload Retry Count", "ideal": "", "critical": false, "description": "Count of times head changes position.", "display_type": "normalized" }, "224": { + "display_name": "Load Friction", "ideal": "low", "critical": false, "description": "Resistance caused by friction in mechanical parts while operating.", "display_type": "normalized" }, "225": { + "display_name": "Load/Unload Cycle Count", "ideal": "low", "critical": false, "description": "Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ", "display_type": "normalized" }, "226": { + "display_name": "Load \"In\"-time", "ideal": "", "critical": false, "description": "Total time of loading on the magnetic heads actuator (time not spent in parking area).", "display_type": "normalized" }, "227": { + "display_name": "Torque Amplification Count", "ideal": "low", "critical": false, "description": "Count of attempts to compensate for platter speed variations.[66]", "display_type": "" }, "228": { + "display_name": "Power-Off Retract Cycle", "ideal": "low", "critical": false, "description": "The number of power-off cycles which are counted whenever there is a \"retract event\" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.", "display_type": "" }, "230": { + "display_name": "GMR Head Amplitude ", "ideal": "", "critical": false, "description": "Amplitude of \"thrashing\" (repetitive head moving motions between operations).", "display_type": "normalized" }, "231": { + "display_name": "Life Left", "ideal": "", "critical": false, "description": "Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.", "display_type": "normalized" }, "232": { + "display_name": "Endurance Remaining", "ideal": "", "critical": false, "description": "Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.", "display_type": "normalized" }, "233": { + "display_name": "Media Wearout Indicator", "ideal": "", "critical": false, "description": "Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.", "display_type": "normalized" }, "234": { + "display_name": "Average erase count", "ideal": "", "critical": false, "description": "Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).", "display_type": "normalized" }, "235": { + "display_name": "Good Block Count", "ideal": "", "critical": false, "description": "Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.", "display_type": "normalized" }, "240": { + "display_name": "Head Flying Hours", "ideal": "", "critical": false, "description": "Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.", "display_type": "normalized" }, "241": { + "display_name": "Total LBAs Written", "ideal": "", "critical": false, "description": "Total count of LBAs written.", "display_type": "normalized" }, "242": { + "display_name": "Total LBAs Read", "ideal": "", "critical": false, "description": "Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.", "display_type": "normalized" }, "243": { + "display_name": "Total LBAs Written Expanded", "ideal": "", "critical": false, "description": "The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.", "display_type": "normalized" }, "244": { + "display_name": "Total LBAs Read Expanded", "ideal": "", "critical": false, "description": "The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.", "display_type": "normalized" }, "249": { + "display_name": "NAND Writes (1GiB)", "ideal": "", "critical": false, "description": "Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.", "display_type": "normalized" }, "250": { + "display_name": "Read Error Retry Rate", "ideal": "low", "critical": false, "description": "Count of errors while reading from a disk.", "display_type": "normalized" }, "251": { + "display_name": "Minimum Spares Remaining", "ideal": "", "critical": false, "description": "The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.", "display_type": "normalized" }, "252": { + "display_name": "Newly Added Bad Flash Block", "ideal": "", "critical": false, "description": "The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.", "display_type": "normalized" }, "254": { + "display_name": "Free Fall Protection", "ideal": "low", "critical": false, "description": "Count of \"Free Fall Events\" detected.", "display_type": "normalized" }, "3": { + "display_name": "Spin-Up Time", "ideal": "low", "critical": false, "description": "Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).", @@ -5454,6 +1648,7 @@ export const sdb = { "display_type": "normalized" }, "4": { + "display_name": "Start/Stop Count", "ideal": "", "critical": false, "description": "A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.", @@ -5492,10 +1687,16 @@ export const sdb = { "high": 91, "annual_failure_rate": 0.12262136155304391, "error_interval": [0.0670382394080032, 0.20573780888032978] - }, {"low": 91, "high": 104, "annual_failure_rate": 0, "error_interval": [0, 0]}], + }, { + "low": 91, + "high": 104, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "5": { + "display_name": "Reallocated Sectors Count", "ideal": "low", "critical": true, "description": "Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.", @@ -5548,12 +1749,14 @@ export const sdb = { "display_type": "raw" }, "6": { + "display_name": "Read Channel Margin", "ideal": "", "critical": false, "description": "Margin of a channel while reading data. The function of this attribute is not specified.", "display_type": "normalized" }, "7": { + "display_name": "Seek Error Rate", "ideal": "", "critical": false, "description": "(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -5572,12 +1775,22 @@ export const sdb = { "high": 112, "annual_failure_rate": 0.01087335627722523, "error_interval": [0.008732197944943352, 0.013380600544561905] - }, {"low": 112, "high": 130, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 112, + "high": 130, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 130, "high": 148, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 148, "high": 166, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 148, + "high": 166, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 166, "high": 184, "annual_failure_rate": 0, @@ -5591,16 +1804,19 @@ export const sdb = { "display_type": "normalized" }, "8": { + "display_name": "Seek Time Performance", "ideal": "high", "critical": false, "description": "Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.", "display_type": "normalized" }, "9": { + "display_name": "Power-On Hours", "ideal": "", "critical": false, "description": "Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or \"wrap around\" (reset to zero periodically).", "display_type": "normalized" } - }, "success": true + }, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdc.ts b/webapp/frontend/src/app/data/mock/device/details/sdc.ts index 5d6935e..66fa65d 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdc.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdc.ts @@ -1,2128 +1,243 @@ export const sdc = { "data": { - "CreatedAt": "2020-08-28T07:55:27.75951336Z", - "UpdatedAt": "2020-09-08T21:39:26.568442-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "1.5 Gb/s", - "host_id": "NAS", - "serial_number": "9RK4XXXXX", - "firmware": "MS1OA650", - "rotational_speed": 7200, - "capacity": 500107862016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "usbjmicron", - "smart_results": [{ - "ID": 45, - "CreatedAt": "2020-09-08T21:39:26.569345-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569345-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T06:48:23-07:00", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": [{ - "ID": 408, - "CreatedAt": "2020-09-08T21:39:26.569651-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569651-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.034155719633986996, - "history": [{ - "ID": 355, - "CreatedAt": "2020-09-07T15:47:21.331077494Z", - "UpdatedAt": "2020-09-07T15:47:21.331077494Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 302, - "CreatedAt": "2020-09-07T15:38:56.628275154Z", - "UpdatedAt": "2020-09-07T15:38:56.628275154Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 249, - "CreatedAt": "2020-09-07T15:26:07.499652704Z", - "UpdatedAt": "2020-09-07T15:26:07.499652704Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 196, - "CreatedAt": "2020-09-07T15:19:17.461974003Z", - "UpdatedAt": "2020-09-07T15:19:17.461974003Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 143, - "CreatedAt": "2020-09-07T15:10:40.241379163Z", - "UpdatedAt": "2020-09-07T15:10:40.241379163Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-06T23:14:39.844234727Z", - "UpdatedAt": "2020-09-06T23:14:39.844234727Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-08-28T07:55:27.822615291Z", - "UpdatedAt": "2020-08-28T07:55:27.822615291Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 409, - "CreatedAt": "2020-09-08T21:39:26.569778-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569778-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 356, - "CreatedAt": "2020-09-07T15:47:21.331211195Z", - "UpdatedAt": "2020-09-07T15:47:21.331211195Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 303, - "CreatedAt": "2020-09-07T15:38:56.628397755Z", - "UpdatedAt": "2020-09-07T15:38:56.628397755Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 250, - "CreatedAt": "2020-09-07T15:26:07.499816008Z", - "UpdatedAt": "2020-09-07T15:26:07.499816008Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 197, - "CreatedAt": "2020-09-07T15:19:17.462101002Z", - "UpdatedAt": "2020-09-07T15:19:17.462101002Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 144, - "CreatedAt": "2020-09-07T15:10:40.241492664Z", - "UpdatedAt": "2020-09-07T15:10:40.241492664Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-06T23:14:39.84435983Z", - "UpdatedAt": "2020-09-06T23:14:39.84435983Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-08-28T07:55:27.822739564Z", - "UpdatedAt": "2020-08-28T07:55:27.822739564Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 410, - "CreatedAt": "2020-09-08T21:39:26.569881-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569881-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.009100406705780476, - "history": [{ - "ID": 357, - "CreatedAt": "2020-09-07T15:47:21.331308395Z", - "UpdatedAt": "2020-09-07T15:47:21.331308395Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 304, - "CreatedAt": "2020-09-07T15:38:56.628487555Z", - "UpdatedAt": "2020-09-07T15:38:56.628487555Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 251, - "CreatedAt": "2020-09-07T15:26:07.499919611Z", - "UpdatedAt": "2020-09-07T15:26:07.499919611Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 198, - "CreatedAt": "2020-09-07T15:19:17.462188402Z", - "UpdatedAt": "2020-09-07T15:19:17.462188402Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 145, - "CreatedAt": "2020-09-07T15:10:40.241569664Z", - "UpdatedAt": "2020-09-07T15:10:40.241569664Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 92, - "CreatedAt": "2020-09-06T23:14:39.844441733Z", - "UpdatedAt": "2020-09-06T23:14:39.844441733Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-08-28T07:55:27.822829942Z", - "UpdatedAt": "2020-08-28T07:55:27.822829942Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 411, - "CreatedAt": "2020-09-08T21:39:26.569964-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569964-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12262136155304391, - "history": [{ - "ID": 358, - "CreatedAt": "2020-09-07T15:47:21.331396495Z", - "UpdatedAt": "2020-09-07T15:47:21.331396495Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 305, - "CreatedAt": "2020-09-07T15:38:56.628567356Z", - "UpdatedAt": "2020-09-07T15:38:56.628567356Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 252, - "CreatedAt": "2020-09-07T15:26:07.500014814Z", - "UpdatedAt": "2020-09-07T15:26:07.500014814Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 199, - "CreatedAt": "2020-09-07T15:19:17.462366102Z", - "UpdatedAt": "2020-09-07T15:19:17.462366102Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 146, - "CreatedAt": "2020-09-07T15:10:40.241649265Z", - "UpdatedAt": "2020-09-07T15:10:40.241649265Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 93, - "CreatedAt": "2020-09-06T23:14:39.844534936Z", - "UpdatedAt": "2020-09-06T23:14:39.844534936Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 40, - "CreatedAt": "2020-08-28T07:55:27.822921756Z", - "UpdatedAt": "2020-08-28T07:55:27.822921756Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 412, - "CreatedAt": "2020-09-08T21:39:26.570087-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570087-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0, - "status": "failed", - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 1.5028253400346423, - "history": [{ - "ID": 359, - "CreatedAt": "2020-09-07T15:47:21.331487495Z", - "UpdatedAt": "2020-09-07T15:47:21.331487495Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 306, - "CreatedAt": "2020-09-07T15:38:56.628646457Z", - "UpdatedAt": "2020-09-07T15:38:56.628646457Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 253, - "CreatedAt": "2020-09-07T15:26:07.500102516Z", - "UpdatedAt": "2020-09-07T15:26:07.500102516Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 200, - "CreatedAt": "2020-09-07T15:19:17.462455401Z", - "UpdatedAt": "2020-09-07T15:19:17.462455401Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 147, - "CreatedAt": "2020-09-07T15:10:40.241718365Z", - "UpdatedAt": "2020-09-07T15:10:40.241718365Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 94, - "CreatedAt": "2020-09-06T23:14:39.844608938Z", - "UpdatedAt": "2020-09-06T23:14:39.844608938Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 41, - "CreatedAt": "2020-08-28T07:55:27.823009241Z", - "UpdatedAt": "2020-08-28T07:55:27.823009241Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }] - }, { - "ID": 413, - "CreatedAt": "2020-09-08T21:39:26.570167-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570167-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01087335627722523, - "history": [{ - "ID": 360, - "CreatedAt": "2020-09-07T15:47:21.331571895Z", - "UpdatedAt": "2020-09-07T15:47:21.331571895Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 307, - "CreatedAt": "2020-09-07T15:38:56.628722958Z", - "UpdatedAt": "2020-09-07T15:38:56.628722958Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 254, - "CreatedAt": "2020-09-07T15:26:07.500193018Z", - "UpdatedAt": "2020-09-07T15:26:07.500193018Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 201, - "CreatedAt": "2020-09-07T15:19:17.462534501Z", - "UpdatedAt": "2020-09-07T15:19:17.462534501Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 148, - "CreatedAt": "2020-09-07T15:10:40.241808366Z", - "UpdatedAt": "2020-09-07T15:10:40.241808366Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 95, - "CreatedAt": "2020-09-06T23:14:39.84467344Z", - "UpdatedAt": "2020-09-06T23:14:39.84467344Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 42, - "CreatedAt": "2020-08-28T07:55:27.823120387Z", - "UpdatedAt": "2020-08-28T07:55:27.823120387Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 414, - "CreatedAt": "2020-09-08T21:39:26.57024-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57024-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 361, - "CreatedAt": "2020-09-07T15:47:21.331652696Z", - "UpdatedAt": "2020-09-07T15:47:21.331652696Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 308, - "CreatedAt": "2020-09-07T15:38:56.628830258Z", - "UpdatedAt": "2020-09-07T15:38:56.628830258Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 255, - "CreatedAt": "2020-09-07T15:26:07.500281521Z", - "UpdatedAt": "2020-09-07T15:26:07.500281521Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 202, - "CreatedAt": "2020-09-07T15:19:17.462611201Z", - "UpdatedAt": "2020-09-07T15:19:17.462611201Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 149, - "CreatedAt": "2020-09-07T15:10:40.241893167Z", - "UpdatedAt": "2020-09-07T15:10:40.241893167Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 96, - "CreatedAt": "2020-09-06T23:14:39.844746142Z", - "UpdatedAt": "2020-09-06T23:14:39.844746142Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 43, - "CreatedAt": "2020-08-28T07:55:27.823221736Z", - "UpdatedAt": "2020-08-28T07:55:27.823221736Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 415, - "CreatedAt": "2020-09-08T21:39:26.570316-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570316-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 362, - "CreatedAt": "2020-09-07T15:47:21.331733496Z", - "UpdatedAt": "2020-09-07T15:47:21.331733496Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 309, - "CreatedAt": "2020-09-07T15:38:56.628909459Z", - "UpdatedAt": "2020-09-07T15:38:56.628909459Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 256, - "CreatedAt": "2020-09-07T15:26:07.500372023Z", - "UpdatedAt": "2020-09-07T15:26:07.500372023Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 203, - "CreatedAt": "2020-09-07T15:19:17.4627161Z", - "UpdatedAt": "2020-09-07T15:19:17.4627161Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 150, - "CreatedAt": "2020-09-07T15:10:40.241974767Z", - "UpdatedAt": "2020-09-07T15:10:40.241974767Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 97, - "CreatedAt": "2020-09-06T23:14:39.844810044Z", - "UpdatedAt": "2020-09-06T23:14:39.844810044Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 44, - "CreatedAt": "2020-08-28T07:55:27.823321577Z", - "UpdatedAt": "2020-08-28T07:55:27.823321577Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 416, - "CreatedAt": "2020-09-08T21:39:26.570394-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570394-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.05459827163896099, - "history": [{ - "ID": 363, - "CreatedAt": "2020-09-07T15:47:21.331813896Z", - "UpdatedAt": "2020-09-07T15:47:21.331813896Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 310, - "CreatedAt": "2020-09-07T15:38:56.62898266Z", - "UpdatedAt": "2020-09-07T15:38:56.62898266Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 257, - "CreatedAt": "2020-09-07T15:26:07.500462326Z", - "UpdatedAt": "2020-09-07T15:26:07.500462326Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 204, - "CreatedAt": "2020-09-07T15:19:17.462794Z", - "UpdatedAt": "2020-09-07T15:19:17.462794Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 151, - "CreatedAt": "2020-09-07T15:10:40.242057668Z", - "UpdatedAt": "2020-09-07T15:10:40.242057668Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 98, - "CreatedAt": "2020-09-06T23:14:39.844880446Z", - "UpdatedAt": "2020-09-06T23:14:39.844880446Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 45, - "CreatedAt": "2020-08-28T07:55:27.823417848Z", - "UpdatedAt": "2020-08-28T07:55:27.823417848Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 417, - "CreatedAt": "2020-09-08T21:39:26.570475-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570475-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12354840389522469, - "history": [{ - "ID": 364, - "CreatedAt": "2020-09-07T15:47:21.331899296Z", - "UpdatedAt": "2020-09-07T15:47:21.331899296Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 311, - "CreatedAt": "2020-09-07T15:38:56.629065161Z", - "UpdatedAt": "2020-09-07T15:38:56.629065161Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 258, - "CreatedAt": "2020-09-07T15:26:07.500549628Z", - "UpdatedAt": "2020-09-07T15:26:07.500549628Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 205, - "CreatedAt": "2020-09-07T15:19:17.4628661Z", - "UpdatedAt": "2020-09-07T15:19:17.4628661Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 152, - "CreatedAt": "2020-09-07T15:10:40.242167169Z", - "UpdatedAt": "2020-09-07T15:10:40.242167169Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 99, - "CreatedAt": "2020-09-06T23:14:39.844953848Z", - "UpdatedAt": "2020-09-06T23:14:39.844953848Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 46, - "CreatedAt": "2020-08-28T07:55:27.823514062Z", - "UpdatedAt": "2020-08-28T07:55:27.823514062Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 418, - "CreatedAt": "2020-09-08T21:39:26.570559-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570559-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 365, - "CreatedAt": "2020-09-07T15:47:21.332006096Z", - "UpdatedAt": "2020-09-07T15:47:21.332006096Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 312, - "CreatedAt": "2020-09-07T15:38:56.629162161Z", - "UpdatedAt": "2020-09-07T15:38:56.629162161Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 259, - "CreatedAt": "2020-09-07T15:26:07.500657031Z", - "UpdatedAt": "2020-09-07T15:26:07.500657031Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 206, - "CreatedAt": "2020-09-07T15:19:17.462996099Z", - "UpdatedAt": "2020-09-07T15:19:17.462996099Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 153, - "CreatedAt": "2020-09-07T15:10:40.242253969Z", - "UpdatedAt": "2020-09-07T15:10:40.242253969Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 100, - "CreatedAt": "2020-09-06T23:14:39.84503215Z", - "UpdatedAt": "2020-09-06T23:14:39.84503215Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 47, - "CreatedAt": "2020-08-28T07:55:27.823595321Z", - "UpdatedAt": "2020-08-28T07:55:27.823595321Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 419, - "CreatedAt": "2020-09-08T21:39:26.57063-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57063-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 366, - "CreatedAt": "2020-09-07T15:47:21.332093797Z", - "UpdatedAt": "2020-09-07T15:47:21.332093797Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 313, - "CreatedAt": "2020-09-07T15:38:56.629235062Z", - "UpdatedAt": "2020-09-07T15:38:56.629235062Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 260, - "CreatedAt": "2020-09-07T15:26:07.500743533Z", - "UpdatedAt": "2020-09-07T15:26:07.500743533Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 207, - "CreatedAt": "2020-09-07T15:19:17.463072899Z", - "UpdatedAt": "2020-09-07T15:19:17.463072899Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 154, - "CreatedAt": "2020-09-07T15:10:40.24235167Z", - "UpdatedAt": "2020-09-07T15:10:40.24235167Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 101, - "CreatedAt": "2020-09-06T23:14:39.845090052Z", - "UpdatedAt": "2020-09-06T23:14:39.845090052Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 48, - "CreatedAt": "2020-08-28T07:55:27.823681715Z", - "UpdatedAt": "2020-08-28T07:55:27.823681715Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 420, - "CreatedAt": "2020-09-08T21:39:26.570714-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570714-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25, - "status": "passed", - "history": [{ - "ID": 367, - "CreatedAt": "2020-09-07T15:47:21.332179497Z", - "UpdatedAt": "2020-09-07T15:47:21.332179497Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 314, - "CreatedAt": "2020-09-07T15:38:56.629309963Z", - "UpdatedAt": "2020-09-07T15:38:56.629309963Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 261, - "CreatedAt": "2020-09-07T15:26:07.500841536Z", - "UpdatedAt": "2020-09-07T15:26:07.500841536Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 208, - "CreatedAt": "2020-09-07T15:19:17.463146099Z", - "UpdatedAt": "2020-09-07T15:19:17.463146099Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 155, - "CreatedAt": "2020-09-07T15:10:40.242422871Z", - "UpdatedAt": "2020-09-07T15:10:40.242422871Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 102, - "CreatedAt": "2020-09-06T23:14:39.845149154Z", - "UpdatedAt": "2020-09-06T23:14:39.845149154Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 49, - "CreatedAt": "2020-08-28T07:55:27.823787578Z", - "UpdatedAt": "2020-08-28T07:55:27.823787578Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }] - }, { - "ID": 421, - "CreatedAt": "2020-09-08T21:39:26.570794-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570794-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Could not determine Observed Failure Rate for Critical Attribute", - "history": [{ - "ID": 368, - "CreatedAt": "2020-09-07T15:47:21.332261097Z", - "UpdatedAt": "2020-09-07T15:47:21.332261097Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 315, - "CreatedAt": "2020-09-07T15:38:56.629382363Z", - "UpdatedAt": "2020-09-07T15:38:56.629382363Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 262, - "CreatedAt": "2020-09-07T15:26:07.500933439Z", - "UpdatedAt": "2020-09-07T15:26:07.500933439Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 209, - "CreatedAt": "2020-09-07T15:19:17.463228599Z", - "UpdatedAt": "2020-09-07T15:19:17.463228599Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 156, - "CreatedAt": "2020-09-07T15:10:40.242496871Z", - "UpdatedAt": "2020-09-07T15:10:40.242496871Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 103, - "CreatedAt": "2020-09-06T23:14:39.845209356Z", - "UpdatedAt": "2020-09-06T23:14:39.845209356Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 50, - "CreatedAt": "2020-08-28T07:55:27.823890798Z", - "UpdatedAt": "2020-08-28T07:55:27.823890798Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 422, - "CreatedAt": "2020-09-08T21:39:26.570866-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570866-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0, - "status": "failed", - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 0.6108100007493069, - "history": [{ - "ID": 369, - "CreatedAt": "2020-09-07T15:47:21.332346697Z", - "UpdatedAt": "2020-09-07T15:47:21.332346697Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 197, - "name": "Current Pending Sector Count", + "device": { + "CreatedAt": "2021-06-24T21:17:31.303033-07:00", + "UpdatedAt": "2021-10-24T16:37:56.74865-07:00", + "DeletedAt": null, + "wwn": "0x5000cca264ec3183", + "device_name": "sdc", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK4XXXXX", + "firmware": "MS1OA650", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "ATA", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 3 + }, + "smart_results": [{ + "date": "2021-10-24T23:20:44Z", + "device_wwn": "0x5000cca264ec3183", + "device_protocol": "ATA", + "temp": 25, + "power_on_hours": 65592, + "power_cycle_count": 86, + "attrs": { + "1": { + "attribute_id": 1, "value": 100, + "thresh": 16, "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "raw_value": 0, + "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 316, - "CreatedAt": "2020-09-07T15:38:56.629465264Z", - "UpdatedAt": "2020-09-07T15:38:56.629465264Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 197, - "name": "Current Pending Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.034155719633986996 + }, + "10": { + "attribute_id": 10, "value": 100, + "thresh": 60, "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "raw_value": 0, + "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 263, - "CreatedAt": "2020-09-07T15:26:07.501028141Z", - "UpdatedAt": "2020-09-07T15:26:07.501028141Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 197, - "name": "Current Pending Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.05459827163896099 + }, + "12": { + "attribute_id": 12, "value": 100, + "thresh": 0, "worst": 100, + "raw_value": 86, + "raw_string": "86", + "when_failed": "", + "transformed_value": 0, + "status": 2, + "status_reason": "Observed Failure Rate for Attribute is greater than 10%", + "failure_rate": 0.12354840389522469 + }, + "192": { + "attribute_id": 192, + "value": 95, "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "worst": 95, + "raw_value": 6244, + "raw_string": "6244", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 210, - "CreatedAt": "2020-09-07T15:19:17.463302498Z", - "UpdatedAt": "2020-09-07T15:19:17.463302498Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, + "transformed_value": 0, + "status": 0 + }, + "193": { + "attribute_id": 193, + "value": 95, "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "worst": 95, + "raw_value": 6244, + "raw_string": "6244", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 157, - "CreatedAt": "2020-09-07T15:10:40.242564072Z", - "UpdatedAt": "2020-09-07T15:10:40.242564072Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, + "transformed_value": 0, + "status": 0 + }, + "194": { + "attribute_id": 194, + "value": 240, "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "worst": 240, + "raw_value": 167504969753, + "raw_string": "25 (Min/Max 19/39)", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 104, - "CreatedAt": "2020-09-06T23:14:39.845294758Z", - "UpdatedAt": "2020-09-06T23:14:39.845294758Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, + "transformed_value": 25, + "status": 0 + }, + "196": { + "attribute_id": 196, + "value": 1, "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "worst": 1, + "raw_value": 3831, + "raw_string": "3831", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 51, - "CreatedAt": "2020-08-28T07:55:27.823980673Z", - "UpdatedAt": "2020-08-28T07:55:27.823980673Z", - "DeletedAt": null, - "smart_id": 3, + "transformed_value": 0, + "status": 2, + "status_reason": "Could not determine Observed Failure Rate for Critical Attribute" + }, + "197": { "attribute_id": 197, - "name": "Current Pending Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 8, "raw_string": "8", "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 423, - "CreatedAt": "2020-09-08T21:39:26.570936-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570936-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028675322159886437, - "history": [{ - "ID": 370, - "CreatedAt": "2020-09-07T15:47:21.332430997Z", - "UpdatedAt": "2020-09-07T15:47:21.332430997Z", - "DeletedAt": null, - "smart_id": 39, + "transformed_value": 0, + "status": 1, + "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", + "failure_rate": 0.6108100007493069 + }, + "198": { "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 317, - "CreatedAt": "2020-09-07T15:38:56.629541365Z", - "UpdatedAt": "2020-09-07T15:38:56.629541365Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 264, - "CreatedAt": "2020-09-07T15:26:07.501116944Z", - "UpdatedAt": "2020-09-07T15:26:07.501116944Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, + "transformed_value": 0, + "status": 0, + "failure_rate": 0.028675322159886437 + }, + "199": { + "attribute_id": 199, + "value": 200, "thresh": 0, + "worst": 200, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 211, - "CreatedAt": "2020-09-07T15:19:17.463380498Z", - "UpdatedAt": "2020-09-07T15:19:17.463380498Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "transformed_value": 0, + "status": 0 + }, + "2": { + "attribute_id": 2, + "value": 136, + "thresh": 54, + "worst": 136, + "raw_value": 91, + "raw_string": "91", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 158, - "CreatedAt": "2020-09-07T15:10:40.242633572Z", - "UpdatedAt": "2020-09-07T15:10:40.242633572Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "transformed_value": 0, + "status": 0 + }, + "3": { + "attribute_id": 3, + "value": 125, + "thresh": 24, + "worst": 125, + "raw_value": 17192124596, + "raw_string": "180 (Average 187)", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 105, - "CreatedAt": "2020-09-06T23:14:39.84535416Z", - "UpdatedAt": "2020-09-06T23:14:39.84535416Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.009100406705780476 + }, + "4": { + "attribute_id": 4, "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 86, + "raw_string": "86", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 52, - "CreatedAt": "2020-08-28T07:55:27.824077866Z", - "UpdatedAt": "2020-08-28T07:55:27.824077866Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + "transformed_value": 0, + "status": 2, + "status_reason": "Observed Failure Rate for Attribute is greater than 10%", + "failure_rate": 0.12262136155304391 + }, + "5": { + "attribute_id": 5, + "value": 1, + "thresh": 5, + "worst": 1, + "raw_value": 1975, + "raw_string": "1975", + "when_failed": "now", + "transformed_value": 0, + "status": 1, + "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", + "failure_rate": 1.5028253400346423 + }, + "7": { + "attribute_id": 7, "value": 100, + "thresh": 67, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 424, - "CreatedAt": "2020-09-08T21:39:26.571034-07:00", - "UpdatedAt": "2020-09-08T21:39:26.571034-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 371, - "CreatedAt": "2020-09-07T15:47:21.332512198Z", - "UpdatedAt": "2020-09-07T15:47:21.332512198Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 318, - "CreatedAt": "2020-09-07T15:38:56.629610265Z", - "UpdatedAt": "2020-09-07T15:38:56.629610265Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 265, - "CreatedAt": "2020-09-07T15:26:07.501203046Z", - "UpdatedAt": "2020-09-07T15:26:07.501203046Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 212, - "CreatedAt": "2020-09-07T15:19:17.463463398Z", - "UpdatedAt": "2020-09-07T15:19:17.463463398Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 159, - "CreatedAt": "2020-09-07T15:10:40.242702673Z", - "UpdatedAt": "2020-09-07T15:10:40.242702673Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 106, - "CreatedAt": "2020-09-06T23:14:39.845437463Z", - "UpdatedAt": "2020-09-06T23:14:39.845437463Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "transformed_value": 0, + "status": 0, + "failure_rate": 0.01087335627722523 + }, + "8": { + "attribute_id": 8, + "value": 118, + "thresh": 20, + "worst": 118, + "raw_value": 33, + "raw_string": "33", "when_failed": "", - "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-08-28T07:55:27.824166466Z", - "UpdatedAt": "2020-08-28T07:55:27.824166466Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, + "transformed_value": 0, + "status": 0 + }, + "9": { + "attribute_id": 9, + "value": 91, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 91, + "raw_value": 65592, + "raw_string": "65592", "when_failed": "", - "transformed_value": 0 - }] - }], - "nvme_attributes": [], - "scsi_attributes": [] + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 }] - }, "metadata": { + }, + "metadata": { "1": { + "display_name": "Read Error Rate", "ideal": "low", "critical": false, "description": "(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -2141,12 +256,22 @@ export const sdc = { "high": 125, "annual_failure_rate": 0.06390002135229157, "error_interval": [0.05852004676110847, 0.06964160930553712] - }, {"low": 125, "high": 140, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 125, + "high": 140, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 140, "high": 155, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 155, "high": 170, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 155, + "high": 170, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 170, "high": 185, "annual_failure_rate": 0, @@ -2160,6 +285,7 @@ export const sdc = { "display_type": "normalized" }, "10": { + "display_name": "Spin Retry Count", "ideal": "low", "critical": true, "description": "Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", @@ -2177,6 +303,7 @@ export const sdc = { "display_type": "raw" }, "11": { + "display_name": "Recalibration Retries or Calibration Retry Count", "ideal": "low", "critical": false, "description": "This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", @@ -2190,17 +317,32 @@ export const sdc = { "high": 80, "annual_failure_rate": 0.5555555555555556, "error_interval": [0.014065448880161053, 3.095357439410498] - }, {"low": 80, "high": 160, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 80, + "high": 160, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 160, "high": 240, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 240, "high": 320, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 240, + "high": 320, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 320, "high": 400, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 400, "high": 480, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 400, + "high": 480, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 480, "high": 560, "annual_failure_rate": 0, @@ -2209,6 +351,7 @@ export const sdc = { "display_type": "raw" }, "12": { + "display_name": "Power Cycle Count", "ideal": "low", "critical": false, "description": "This attribute indicates the count of full hard disk power on/off cycles.", @@ -2251,79 +394,98 @@ export const sdc = { "display_type": "raw" }, "13": { + "display_name": "Soft Read Error Rate", "ideal": "low", "critical": false, "description": "Uncorrected read errors reported to the operating system.", "display_type": "normalized" }, - "170": {"ideal": "", "critical": false, "description": "See attribute E8.", "display_type": "normalized"}, + "170": { + "display_name": "Available Reserved Space", + "ideal": "", + "critical": false, + "description": "See attribute E8.", + "display_type": "normalized" + }, "171": { + "display_name": "SSD Program Fail Count", "ideal": "", "critical": false, "description": "(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.", "display_type": "normalized" }, "172": { + "display_name": "SSD Erase Fail Count", "ideal": "", "critical": false, "description": "(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.", "display_type": "normalized" }, "173": { + "display_name": "SSD Wear Leveling Count", "ideal": "", "critical": false, "description": "Counts the maximum worst erase count on any block.", "display_type": "normalized" }, "174": { + "display_name": "Unexpected Power Loss Count", "ideal": "", "critical": false, "description": "Also known as \"Power-off Retract Count\" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an \"unclean shutdown\" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.", "display_type": "" }, "175": { + "display_name": "Power Loss Protection Failure", "ideal": "", "critical": false, "description": "Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.", "display_type": "normalized" }, "176": { + "display_name": "Erase Fail Count", "ideal": "", "critical": false, "description": "S.M.A.R.T. parameter indicates a number of flash erase command failures.", "display_type": "normalized" }, "177": { + "display_name": "Wear Range Delta", "ideal": "", "critical": false, "description": "Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ", "display_type": "normalized" }, "179": { + "display_name": "Used Reserved Block Count Total", "ideal": "", "critical": false, "description": "Pre-Fail attribute used at least in Samsung devices.", "display_type": "normalized" }, "180": { + "display_name": "Unused Reserved Block Count Total", "ideal": "", "critical": false, "description": "\"Pre-Fail\" attribute used at least in HP devices. ", "display_type": "normalized" }, "181": { + "display_name": "Program Fail Count Total", "ideal": "", "critical": false, "description": "Total number of Flash program operation failures since the drive was deployed.", "display_type": "normalized" }, "182": { + "display_name": "Erase Fail Count", "ideal": "", "critical": false, "description": "\"Pre-Fail\" Attribute used at least in Samsung devices.", "display_type": "normalized" }, "183": { + "display_name": "SATA Downshift Error Count or Runtime Bad Block", "ideal": "low", "critical": false, "description": "Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.", @@ -2367,10 +529,16 @@ export const sdc = { "high": 130, "annual_failure_rate": 0.40299684542586756, "error_interval": [0.16202563309223209, 0.8303275247667772] - }, {"low": 130, "high": 260, "annual_failure_rate": 0, "error_interval": [0, 0]}], + }, { + "low": 130, + "high": 260, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "184": { + "display_name": "End-to-End error", "ideal": "low", "critical": true, "description": "This attribute is a part of Hewlett-Packard\"s SMART IV technology, as well as part of other vendors\" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive\"s cache RAM", @@ -2379,12 +547,22 @@ export const sdc = { "high": 94, "annual_failure_rate": 1.631212012870933, "error_interval": [1.055634407303844, 2.407990716767714] - }, {"low": 94, "high": 95, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 94, + "high": 95, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 95, "high": 96, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 96, "high": 97, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 96, + "high": 97, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 97, "high": 97, "annual_failure_rate": 0, @@ -2408,18 +586,21 @@ export const sdc = { "display_type": "normalized" }, "185": { + "display_name": "Head Stability", "ideal": "", "critical": false, "description": "Western Digital attribute.", "display_type": "normalized" }, "186": { + "display_name": "Induced Op-Vibration Detection", "ideal": "", "critical": false, "description": "Western Digital attribute.", "display_type": "normalized" }, "187": { + "display_name": "Reported Uncorrectable Errors", "ideal": "low", "critical": true, "description": "The count of errors that could not be recovered using hardware ECC (see attribute 195).", @@ -2472,6 +653,7 @@ export const sdc = { "display_type": "raw" }, "188": { + "display_name": "Command Timeout", "ideal": "low", "critical": true, "description": "The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.", @@ -2524,6 +706,7 @@ export const sdc = { "display_type": "raw" }, "189": { + "display_name": "High Fly Writes", "ideal": "low", "critical": false, "description": "HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.", @@ -2571,18 +754,21 @@ export const sdc = { "display_type": "raw" }, "190": { + "display_name": "Temperature Difference", "ideal": "", "critical": false, "description": "Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.", "display_type": "normalized" }, "191": { + "display_name": "G-sense Error Rate", "ideal": "low", "critical": false, "description": "The count of errors resulting from externally induced shock and vibration. ", "display_type": "normalized" }, "192": { + "display_name": "Power-off Retract Count", "ideal": "low", "critical": false, "description": "Number of power-off or emergency retract cycles.", @@ -2630,12 +816,14 @@ export const sdc = { "display_type": "raw" }, "193": { + "display_name": "Load Cycle Count", "ideal": "low", "critical": false, "description": "Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.", "display_type": "normalized" }, "194": { + "display_name": "Temperature", "ideal": "low", "critical": false, "description": "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", @@ -2643,6 +831,7 @@ export const sdc = { "display_type": "transformed" }, "195": { + "display_name": "Hardware ECC Recovered", "ideal": "", "critical": false, "description": "(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -2666,12 +855,22 @@ export const sdc = { "high": 60, "annual_failure_rate": 0.05672658497265746, "error_interval": [0.043182904776447234, 0.07317316161437043] - }, {"low": 60, "high": 72, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 60, + "high": 72, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 72, "high": 84, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 84, "high": 96, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 84, + "high": 96, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 96, "high": 108, "annual_failure_rate": 0.04074570216566197, @@ -2680,6 +879,7 @@ export const sdc = { "display_type": "normalized" }, "196": { + "display_name": "Reallocation Event Count", "ideal": "low", "critical": true, "description": "Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.", @@ -2732,6 +932,7 @@ export const sdc = { "display_type": "raw" }, "197": { + "display_name": "Current Pending Sector Count", "ideal": "low", "critical": true, "description": "Count of \"unstable\" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it\"s written.", @@ -2784,6 +985,7 @@ export const sdc = { "display_type": "raw" }, "198": { + "display_name": "(Offline) Uncorrectable Sector Count", "ideal": "low", "critical": true, "description": "The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.", @@ -2836,6 +1038,7 @@ export const sdc = { "display_type": "raw" }, "199": { + "display_name": "UltraDMA CRC Error Count", "ideal": "low", "critical": false, "description": "The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).", @@ -2888,246 +1091,287 @@ export const sdc = { "display_type": "raw" }, "2": { + "display_name": "Throughput Performance", "ideal": "high", "critical": false, "description": "Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.", "display_type": "normalized" }, "200": { + "display_name": "Multi-Zone Error Rate", "ideal": "low", "critical": false, "description": "The count of errors found when writing a sector. The higher the value, the worse the disk\"s mechanical condition is.", "display_type": "normalized" }, "201": { + "display_name": "Soft Read Error Rate", "ideal": "low", "critical": true, "description": "Count indicates the number of uncorrectable software read errors.", "display_type": "normalized" }, "202": { + "display_name": "Data Address Mark errors", "ideal": "low", "critical": false, "description": "Count of Data Address Mark errors (or vendor-specific).", "display_type": "normalized" }, "203": { + "display_name": "Run Out Cancel", "ideal": "low", "critical": false, "description": "The number of errors caused by incorrect checksum during the error correction.", "display_type": "normalized" }, "204": { + "display_name": "Soft ECC Correction", "ideal": "low", "critical": false, "description": "Count of errors corrected by the internal error correction software.", "display_type": "" }, "205": { + "display_name": "Thermal Asperity Rate", "ideal": "low", "critical": false, "description": "Count of errors due to high temperature.", "display_type": "normalized" }, "206": { + "display_name": "Flying Height", "ideal": "", "critical": false, "description": "Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.", "display_type": "normalized" }, "207": { + "display_name": "Spin High Current", "ideal": "low", "critical": false, "description": "Amount of surge current used to spin up the drive.", "display_type": "normalized" }, "208": { + "display_name": "Spin Buzz", "ideal": "", "critical": false, "description": "Count of buzz routines needed to spin up the drive due to insufficient power.", "display_type": "normalized" }, "209": { + "display_name": "Offline Seek Performance", "ideal": "", "critical": false, "description": "Drive\"s seek performance during its internal tests.", "display_type": "normalized" }, "210": { + "display_name": "Vibration During Write", "ideal": "", "critical": false, "description": "Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.", "display_type": "normalized" }, "211": { + "display_name": "Vibration During Write", "ideal": "", "critical": false, "description": "A recording of a vibration encountered during write operations.", "display_type": "normalized" }, "212": { + "display_name": "Shock During Write", "ideal": "", "critical": false, "description": "A recording of shock encountered during write operations.", "display_type": "normalized" }, "22": { + "display_name": "Current Helium Level", "ideal": "high", "critical": false, "description": "Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.", "display_type": "normalized" }, "220": { + "display_name": "Disk Shift", "ideal": "low", "critical": false, "description": "Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.", "display_type": "normalized" }, "221": { + "display_name": "G-Sense Error Rate", "ideal": "low", "critical": false, "description": "The count of errors resulting from externally induced shock and vibration.", "display_type": "normalized" }, "222": { + "display_name": "Loaded Hours", "ideal": "", "critical": false, "description": "Time spent operating under data load (movement of magnetic head armature).", "display_type": "normalized" }, "223": { + "display_name": "Load/Unload Retry Count", "ideal": "", "critical": false, "description": "Count of times head changes position.", "display_type": "normalized" }, "224": { + "display_name": "Load Friction", "ideal": "low", "critical": false, "description": "Resistance caused by friction in mechanical parts while operating.", "display_type": "normalized" }, "225": { + "display_name": "Load/Unload Cycle Count", "ideal": "low", "critical": false, "description": "Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ", "display_type": "normalized" }, "226": { + "display_name": "Load \"In\"-time", "ideal": "", "critical": false, "description": "Total time of loading on the magnetic heads actuator (time not spent in parking area).", "display_type": "normalized" }, "227": { + "display_name": "Torque Amplification Count", "ideal": "low", "critical": false, "description": "Count of attempts to compensate for platter speed variations.[66]", "display_type": "" }, "228": { + "display_name": "Power-Off Retract Cycle", "ideal": "low", "critical": false, "description": "The number of power-off cycles which are counted whenever there is a \"retract event\" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.", "display_type": "" }, "230": { + "display_name": "GMR Head Amplitude ", "ideal": "", "critical": false, "description": "Amplitude of \"thrashing\" (repetitive head moving motions between operations).", "display_type": "normalized" }, "231": { + "display_name": "Life Left", "ideal": "", "critical": false, "description": "Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.", "display_type": "normalized" }, "232": { + "display_name": "Endurance Remaining", "ideal": "", "critical": false, "description": "Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.", "display_type": "normalized" }, "233": { + "display_name": "Media Wearout Indicator", "ideal": "", "critical": false, "description": "Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.", "display_type": "normalized" }, "234": { + "display_name": "Average erase count", "ideal": "", "critical": false, "description": "Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).", "display_type": "normalized" }, "235": { + "display_name": "Good Block Count", "ideal": "", "critical": false, "description": "Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.", "display_type": "normalized" }, "240": { + "display_name": "Head Flying Hours", "ideal": "", "critical": false, "description": "Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.", "display_type": "normalized" }, "241": { + "display_name": "Total LBAs Written", "ideal": "", "critical": false, "description": "Total count of LBAs written.", "display_type": "normalized" }, "242": { + "display_name": "Total LBAs Read", "ideal": "", "critical": false, "description": "Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.", "display_type": "normalized" }, "243": { + "display_name": "Total LBAs Written Expanded", "ideal": "", "critical": false, "description": "The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.", "display_type": "normalized" }, "244": { + "display_name": "Total LBAs Read Expanded", "ideal": "", "critical": false, "description": "The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.", "display_type": "normalized" }, "249": { + "display_name": "NAND Writes (1GiB)", "ideal": "", "critical": false, "description": "Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.", "display_type": "normalized" }, "250": { + "display_name": "Read Error Retry Rate", "ideal": "low", "critical": false, "description": "Count of errors while reading from a disk.", "display_type": "normalized" }, "251": { + "display_name": "Minimum Spares Remaining", "ideal": "", "critical": false, "description": "The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.", "display_type": "normalized" }, "252": { + "display_name": "Newly Added Bad Flash Block", "ideal": "", "critical": false, "description": "The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.", "display_type": "normalized" }, "254": { + "display_name": "Free Fall Protection", "ideal": "low", "critical": false, "description": "Count of \"Free Fall Events\" detected.", "display_type": "normalized" }, "3": { + "display_name": "Spin-Up Time", "ideal": "low", "critical": false, "description": "Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).", @@ -3175,6 +1419,7 @@ export const sdc = { "display_type": "normalized" }, "4": { + "display_name": "Start/Stop Count", "ideal": "", "critical": false, "description": "A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.", @@ -3213,10 +1458,16 @@ export const sdc = { "high": 91, "annual_failure_rate": 0.12262136155304391, "error_interval": [0.0670382394080032, 0.20573780888032978] - }, {"low": 91, "high": 104, "annual_failure_rate": 0, "error_interval": [0, 0]}], + }, { + "low": 91, + "high": 104, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "5": { + "display_name": "Reallocated Sectors Count", "ideal": "low", "critical": true, "description": "Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.", @@ -3269,12 +1520,14 @@ export const sdc = { "display_type": "raw" }, "6": { + "display_name": "Read Channel Margin", "ideal": "", "critical": false, "description": "Margin of a channel while reading data. The function of this attribute is not specified.", "display_type": "normalized" }, "7": { + "display_name": "Seek Error Rate", "ideal": "", "critical": false, "description": "(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", @@ -3293,12 +1546,22 @@ export const sdc = { "high": 112, "annual_failure_rate": 0.01087335627722523, "error_interval": [0.008732197944943352, 0.013380600544561905] - }, {"low": 112, "high": 130, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 112, + "high": 130, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 130, "high": 148, "annual_failure_rate": 0, "error_interval": [0, 0] - }, {"low": 148, "high": 166, "annual_failure_rate": 0, "error_interval": [0, 0]}, { + }, { + "low": 148, + "high": 166, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 166, "high": 184, "annual_failure_rate": 0, @@ -3312,16 +1575,19 @@ export const sdc = { "display_type": "normalized" }, "8": { + "display_name": "Seek Time Performance", "ideal": "high", "critical": false, "description": "Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.", "display_type": "normalized" }, "9": { + "display_name": "Power-On Hours", "ideal": "", "critical": false, "description": "Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or \"wrap around\" (reset to zero periodically).", "display_type": "normalized" } - }, "success": true + }, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdd.ts b/webapp/frontend/src/app/data/mock/device/details/sdd.ts index 5884342..3442593 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdd.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdd.ts @@ -1,1240 +1,222 @@ export const sdd = { "data": { - "CreatedAt": "2020-08-28T07:55:27.76380029Z", - "UpdatedAt": "2020-09-08T21:39:26.575283-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 7200, - "capacity": 4000787030016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 47, - "CreatedAt": "2020-09-08T21:39:26.576373-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576373-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.30374-07:00", + "UpdatedAt": "2021-10-24T16:37:57.013758-07:00", "DeletedAt": null, + "wwn": "0x5000cca252c859cc", + "device_name": "sdd", + "manufacturer": "ATA", + "model_name": "WDC_WD80EFAX-68LHPN0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "7SGLXXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 8001563222016, + "form_factor": "", + "smart_support": false, + "device_protocol": "SCSI", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart_results": [{ + "date": "2021-10-24T23:20:44Z", "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T15:27:02-07:00", - "smart_status": "passed", + "device_protocol": "SCSI", "temp": 34, "power_on_hours": 43549, "power_cycle_count": 0, - "ata_attributes": [], - "nvme_attributes": [], - "scsi_attributes": [{ - "ID": 183, - "CreatedAt": "2020-09-08T21:39:26.576671-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576671-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 157, - "CreatedAt": "2020-09-07T15:47:21.34270442Z", - "UpdatedAt": "2020-09-07T15:47:21.34270442Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 131, - "CreatedAt": "2020-09-07T15:38:56.63806264Z", - "UpdatedAt": "2020-09-07T15:38:56.63806264Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 105, - "CreatedAt": "2020-09-07T15:26:07.511359323Z", - "UpdatedAt": "2020-09-07T15:26:07.511359323Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-07T15:19:17.472566367Z", - "UpdatedAt": "2020-09-07T15:19:17.472566367Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-09-07T15:10:40.252068341Z", - "UpdatedAt": "2020-09-07T15:10:40.252068341Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-09-06T23:14:39.854497534Z", - "UpdatedAt": "2020-09-06T23:14:39.854497534Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.845073051Z", - "UpdatedAt": "2020-08-28T07:55:27.845073051Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 184, - "CreatedAt": "2020-09-08T21:39:26.577142-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577142-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 158, - "CreatedAt": "2020-09-07T15:47:21.34285782Z", - "UpdatedAt": "2020-09-07T15:47:21.34285782Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 132, - "CreatedAt": "2020-09-07T15:38:56.638194141Z", - "UpdatedAt": "2020-09-07T15:38:56.638194141Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 106, - "CreatedAt": "2020-09-07T15:26:07.511676732Z", - "UpdatedAt": "2020-09-07T15:26:07.511676732Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-07T15:19:17.472704067Z", - "UpdatedAt": "2020-09-07T15:19:17.472704067Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-07T15:10:40.252408443Z", - "UpdatedAt": "2020-09-07T15:10:40.252408443Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-09-06T23:14:39.854629938Z", - "UpdatedAt": "2020-09-06T23:14:39.854629938Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.845217252Z", - "UpdatedAt": "2020-08-28T07:55:27.845217252Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 185, - "CreatedAt": "2020-09-08T21:39:26.577223-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577223-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 159, - "CreatedAt": "2020-09-07T15:47:21.342970521Z", - "UpdatedAt": "2020-09-07T15:47:21.342970521Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 133, - "CreatedAt": "2020-09-07T15:38:56.638272842Z", - "UpdatedAt": "2020-09-07T15:38:56.638272842Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 107, - "CreatedAt": "2020-09-07T15:26:07.511771334Z", - "UpdatedAt": "2020-09-07T15:26:07.511771334Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-07T15:19:17.472780267Z", - "UpdatedAt": "2020-09-07T15:19:17.472780267Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-07T15:10:40.252543044Z", - "UpdatedAt": "2020-09-07T15:10:40.252543044Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-09-06T23:14:39.85470424Z", - "UpdatedAt": "2020-09-06T23:14:39.85470424Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.845307694Z", - "UpdatedAt": "2020-08-28T07:55:27.845307694Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 186, - "CreatedAt": "2020-09-08T21:39:26.577322-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577322-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 160, - "CreatedAt": "2020-09-07T15:47:21.343052321Z", - "UpdatedAt": "2020-09-07T15:47:21.343052321Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 134, - "CreatedAt": "2020-09-07T15:38:56.638349442Z", - "UpdatedAt": "2020-09-07T15:38:56.638349442Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 108, - "CreatedAt": "2020-09-07T15:26:07.512120944Z", - "UpdatedAt": "2020-09-07T15:26:07.512120944Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-07T15:19:17.472863366Z", - "UpdatedAt": "2020-09-07T15:19:17.472863366Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-07T15:10:40.252654845Z", - "UpdatedAt": "2020-09-07T15:10:40.252654845Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-09-06T23:14:39.854773542Z", - "UpdatedAt": "2020-09-06T23:14:39.854773542Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.845417944Z", - "UpdatedAt": "2020-08-28T07:55:27.845417944Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 187, - "CreatedAt": "2020-09-08T21:39:26.577402-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577402-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 161, - "CreatedAt": "2020-09-07T15:47:21.343130621Z", - "UpdatedAt": "2020-09-07T15:47:21.343130621Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 135, - "CreatedAt": "2020-09-07T15:38:56.638419243Z", - "UpdatedAt": "2020-09-07T15:38:56.638419243Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 109, - "CreatedAt": "2020-09-07T15:26:07.512289049Z", - "UpdatedAt": "2020-09-07T15:26:07.512289049Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-07T15:19:17.472931366Z", - "UpdatedAt": "2020-09-07T15:19:17.472931366Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-07T15:10:40.252764246Z", - "UpdatedAt": "2020-09-07T15:10:40.252764246Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", + "attrs": { + "read_correction_algorithm_invocations": { + "attribute_id": "read_correction_algorithm_invocations", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_eccdelayed": { + "attribute_id": "read_errors_corrected_by_eccdelayed", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_eccfast": { + "attribute_id": "read_errors_corrected_by_eccfast", "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-09-06T23:14:39.854857145Z", - "UpdatedAt": "2020-09-06T23:14:39.854857145Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.84550537Z", - "UpdatedAt": "2020-08-28T07:55:27.84550537Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_rereads_rewrites": { + "attribute_id": "read_errors_corrected_by_rereads_rewrites", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "read_total_errors_corrected": { + "attribute_id": "read_total_errors_corrected", "value": 300357663, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_total_uncorrected_errors": { + "attribute_id": "read_total_uncorrected_errors", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "scsi_grown_defect_list": { + "attribute_id": "scsi_grown_defect_list", + "value": 56, "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 188, - "CreatedAt": "2020-09-08T21:39:26.577467-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577467-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 162, - "CreatedAt": "2020-09-07T15:47:21.343232021Z", - "UpdatedAt": "2020-09-07T15:47:21.343232021Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 136, - "CreatedAt": "2020-09-07T15:38:56.638492144Z", - "UpdatedAt": "2020-09-07T15:38:56.638492144Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 110, - "CreatedAt": "2020-09-07T15:26:07.512411952Z", - "UpdatedAt": "2020-09-07T15:26:07.512411952Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-07T15:19:17.473000166Z", - "UpdatedAt": "2020-09-07T15:19:17.473000166Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-07T15:10:40.252885147Z", - "UpdatedAt": "2020-09-07T15:10:40.252885147Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 32, - "CreatedAt": "2020-09-06T23:14:39.854921646Z", - "UpdatedAt": "2020-09-06T23:14:39.854921646Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.845607015Z", - "UpdatedAt": "2020-08-28T07:55:27.845607015Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 189, - "CreatedAt": "2020-09-08T21:39:26.577528-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577528-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 163, - "CreatedAt": "2020-09-07T15:47:21.343302621Z", - "UpdatedAt": "2020-09-07T15:47:21.343302621Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 137, - "CreatedAt": "2020-09-07T15:38:56.638557144Z", - "UpdatedAt": "2020-09-07T15:38:56.638557144Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 111, - "CreatedAt": "2020-09-07T15:26:07.512526855Z", - "UpdatedAt": "2020-09-07T15:26:07.512526855Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 85, - "CreatedAt": "2020-09-07T15:19:17.473078066Z", - "UpdatedAt": "2020-09-07T15:19:17.473078066Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-07T15:10:40.252987648Z", - "UpdatedAt": "2020-09-07T15:10:40.252987648Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-09-06T23:14:39.854986748Z", - "UpdatedAt": "2020-09-06T23:14:39.854986748Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.845686961Z", - "UpdatedAt": "2020-08-28T07:55:27.845686961Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 190, - "CreatedAt": "2020-09-08T21:39:26.577585-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577585-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 164, - "CreatedAt": "2020-09-07T15:47:21.343385821Z", - "UpdatedAt": "2020-09-07T15:47:21.343385821Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 138, - "CreatedAt": "2020-09-07T15:38:56.638623345Z", - "UpdatedAt": "2020-09-07T15:38:56.638623345Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 112, - "CreatedAt": "2020-09-07T15:26:07.51269696Z", - "UpdatedAt": "2020-09-07T15:26:07.51269696Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-07T15:19:17.473144665Z", - "UpdatedAt": "2020-09-07T15:19:17.473144665Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-07T15:10:40.253104448Z", - "UpdatedAt": "2020-09-07T15:10:40.253104448Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-09-06T23:14:39.85505285Z", - "UpdatedAt": "2020-09-06T23:14:39.85505285Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.845805078Z", - "UpdatedAt": "2020-08-28T07:55:27.845805078Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 191, - "CreatedAt": "2020-09-08T21:39:26.577642-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577642-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 165, - "CreatedAt": "2020-09-07T15:47:21.343465022Z", - "UpdatedAt": "2020-09-07T15:47:21.343465022Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 139, - "CreatedAt": "2020-09-07T15:38:56.638687045Z", - "UpdatedAt": "2020-09-07T15:38:56.638687045Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 113, - "CreatedAt": "2020-09-07T15:26:07.512816463Z", - "UpdatedAt": "2020-09-07T15:26:07.512816463Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-07T15:19:17.473246965Z", - "UpdatedAt": "2020-09-07T15:19:17.473246965Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-07T15:10:40.253434751Z", - "UpdatedAt": "2020-09-07T15:10:40.253434751Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-09-06T23:14:39.855116452Z", - "UpdatedAt": "2020-09-06T23:14:39.855116452Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.846267863Z", - "UpdatedAt": "2020-08-28T07:55:27.846267863Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 192, - "CreatedAt": "2020-09-08T21:39:26.577699-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577699-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 166, - "CreatedAt": "2020-09-07T15:47:21.343534322Z", - "UpdatedAt": "2020-09-07T15:47:21.343534322Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 140, - "CreatedAt": "2020-09-07T15:38:56.638979448Z", - "UpdatedAt": "2020-09-07T15:38:56.638979448Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 114, - "CreatedAt": "2020-09-07T15:26:07.513298876Z", - "UpdatedAt": "2020-09-07T15:26:07.513298876Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-07T15:19:17.473324965Z", - "UpdatedAt": "2020-09-07T15:19:17.473324965Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-07T15:10:40.253539552Z", - "UpdatedAt": "2020-09-07T15:10:40.253539552Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-09-06T23:14:39.855181654Z", - "UpdatedAt": "2020-09-06T23:14:39.855181654Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.846466097Z", - "UpdatedAt": "2020-08-28T07:55:27.846466097Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 193, - "CreatedAt": "2020-09-08T21:39:26.577768-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577768-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 167, - "CreatedAt": "2020-09-07T15:47:21.343602322Z", - "UpdatedAt": "2020-09-07T15:47:21.343602322Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 141, - "CreatedAt": "2020-09-07T15:38:56.639119449Z", - "UpdatedAt": "2020-09-07T15:38:56.639119449Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 115, - "CreatedAt": "2020-09-07T15:26:07.513392579Z", - "UpdatedAt": "2020-09-07T15:26:07.513392579Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-07T15:19:17.473396265Z", - "UpdatedAt": "2020-09-07T15:19:17.473396265Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-07T15:10:40.253617252Z", - "UpdatedAt": "2020-09-07T15:10:40.253617252Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-09-06T23:14:39.855245056Z", - "UpdatedAt": "2020-09-06T23:14:39.855245056Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.846680695Z", - "UpdatedAt": "2020-08-28T07:55:27.846680695Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 194, - "CreatedAt": "2020-09-08T21:39:26.577827-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577827-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 168, - "CreatedAt": "2020-09-07T15:47:21.343669122Z", - "UpdatedAt": "2020-09-07T15:47:21.343669122Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 142, - "CreatedAt": "2020-09-07T15:38:56.63923905Z", - "UpdatedAt": "2020-09-07T15:38:56.63923905Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 116, - "CreatedAt": "2020-09-07T15:26:07.513473381Z", - "UpdatedAt": "2020-09-07T15:26:07.513473381Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-07T15:19:17.473465964Z", - "UpdatedAt": "2020-09-07T15:19:17.473465964Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-07T15:10:40.253699153Z", - "UpdatedAt": "2020-09-07T15:10:40.253699153Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-09-06T23:14:39.855310158Z", - "UpdatedAt": "2020-09-06T23:14:39.855310158Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.847304842Z", - "UpdatedAt": "2020-08-28T07:55:27.847304842Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 195, - "CreatedAt": "2020-09-08T21:39:26.577884-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577884-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 169, - "CreatedAt": "2020-09-07T15:47:21.343735222Z", - "UpdatedAt": "2020-09-07T15:47:21.343735222Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 143, - "CreatedAt": "2020-09-07T15:38:56.639331551Z", - "UpdatedAt": "2020-09-07T15:38:56.639331551Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 117, - "CreatedAt": "2020-09-07T15:26:07.513551783Z", - "UpdatedAt": "2020-09-07T15:26:07.513551783Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-07T15:19:17.473531164Z", - "UpdatedAt": "2020-09-07T15:19:17.473531164Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-07T15:10:40.253767653Z", - "UpdatedAt": "2020-09-07T15:10:40.253767653Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-09-06T23:14:39.85537276Z", - "UpdatedAt": "2020-09-06T23:14:39.85537276Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.847458217Z", - "UpdatedAt": "2020-08-28T07:55:27.847458217Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }] + "transformed_value": 0, + "status": 0 + }, + "write_correction_algorithm_invocations": { + "attribute_id": "write_correction_algorithm_invocations", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_eccdelayed": { + "attribute_id": "write_errors_corrected_by_eccdelayed", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_eccfast": { + "attribute_id": "write_errors_corrected_by_eccfast", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_rereads_rewrites": { + "attribute_id": "write_errors_corrected_by_rereads_rewrites", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "write_total_errors_corrected": { + "attribute_id": "write_total_errors_corrected", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_total_uncorrected_errors": { + "attribute_id": "write_total_uncorrected_errors", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 }] - }, "metadata": { - "read.correction_algorithm_invocations": { + }, + "metadata": { + "read_correction_algorithm_invocations": { + "display_name": "Read Correction Algorithm Invocations", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccdelayed": { + "display_name": "Read Errors Corrected by ECC Delayed", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccfast": { + "display_name": "Read Errors Corrected by ECC Fast", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_rereads_rewrites": { + "display_name": "Read Errors Corrected by ReReads/ReWrites", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "read_total_errors_corrected": { + "display_name": "Read Total Errors Corrected", "ideal": "", "critical": false, "description": "", "display_type": "" }, - "read.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_rereads_rewrites": { + "read_total_uncorrected_errors": { + "display_name": "Read Total Uncorrected Errors", "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "read.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "scsi_grown_defect_list": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "write.correction_algorithm_invocations": { + "scsi_grown_defect_list": { + "display_name": "Grown Defect List", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "write_correction_algorithm_invocations": { + "display_name": "Write Correction Algorithm Invocations", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_eccdelayed": { + "display_name": "Write Errors Corrected by ECC Delayed", "ideal": "", "critical": false, "description": "", "display_type": "" }, - "write.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_rereads_rewrites": { + "write_errors_corrected_by_eccfast": { + "display_name": "Write Errors Corrected by ECC Fast", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_rereads_rewrites": { + "display_name": "Write Errors Corrected by ReReads/ReWrites", "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "write.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""} - }, "success": true + "write_total_errors_corrected": { + "display_name": "Write Total Errors Corrected", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_total_uncorrected_errors": { + "display_name": "Write Total Uncorrected Errors", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + } + }, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sde.ts b/webapp/frontend/src/app/data/mock/device/details/sde.ts index 3a05f9a..42c5f1a 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sde.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sde.ts @@ -1,1240 +1,222 @@ export const sde = { "data": { - "CreatedAt": "2020-08-28T07:55:27.768220079Z", - "UpdatedAt": "2020-09-08T21:39:26.578973-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ebc248", - "device_name": "sde", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK3XXXXX", - "firmware": "", - "rotational_speed": 10500, - "capacity": 1200243695616, - "form_factor": "2.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 48, - "CreatedAt": "2020-09-08T21:39:26.579623-07:00", - "UpdatedAt": "2020-09-08T21:39:26.579623-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.304461-07:00", + "UpdatedAt": "2021-10-24T16:40:16.495248-07:00", "DeletedAt": null, + "wwn": "0x5000cca264ebc248", + "device_name": "sde", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK3XXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "SCSI", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart_results": [{ + "date": "2021-10-24T23:20:44Z", "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T15:09:15-08:00", - "smart_status": "passed", + "device_protocol": "SCSI", "temp": 31, "power_on_hours": 5675, "power_cycle_count": 0, - "ata_attributes": [], - "nvme_attributes": [], - "scsi_attributes": [{ - "ID": 196, - "CreatedAt": "2020-09-08T21:39:26.57989-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57989-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 170, - "CreatedAt": "2020-09-07T15:47:21.347996632Z", - "UpdatedAt": "2020-09-07T15:47:21.347996632Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 144, - "CreatedAt": "2020-09-07T15:38:56.643262186Z", - "UpdatedAt": "2020-09-07T15:38:56.643262186Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 118, - "CreatedAt": "2020-09-07T15:26:07.517433189Z", - "UpdatedAt": "2020-09-07T15:26:07.517433189Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 92, - "CreatedAt": "2020-09-07T15:19:17.478404748Z", - "UpdatedAt": "2020-09-07T15:19:17.478404748Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 66, - "CreatedAt": "2020-09-07T15:10:40.257359179Z", - "UpdatedAt": "2020-09-07T15:10:40.257359179Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 40, - "CreatedAt": "2020-09-06T23:14:39.858833764Z", - "UpdatedAt": "2020-09-06T23:14:39.858833764Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 14, - "CreatedAt": "2020-08-28T07:55:27.880197174Z", - "UpdatedAt": "2020-08-28T07:55:27.880197174Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 197, - "CreatedAt": "2020-09-08T21:39:26.580007-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580007-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 171, - "CreatedAt": "2020-09-07T15:47:21.348133432Z", - "UpdatedAt": "2020-09-07T15:47:21.348133432Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 145, - "CreatedAt": "2020-09-07T15:38:56.643384087Z", - "UpdatedAt": "2020-09-07T15:38:56.643384087Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", + "attrs": { + "read_correction_algorithm_invocations": { + "attribute_id": "read_correction_algorithm_invocations", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_eccdelayed": { + "attribute_id": "read_errors_corrected_by_eccdelayed", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_eccfast": { + "attribute_id": "read_errors_corrected_by_eccfast", "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 119, - "CreatedAt": "2020-09-07T15:26:07.517563293Z", - "UpdatedAt": "2020-09-07T15:26:07.517563293Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_errors_corrected_by_rereads_rewrites": { + "attribute_id": "read_errors_corrected_by_rereads_rewrites", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "read_total_errors_corrected": { + "attribute_id": "read_total_errors_corrected", "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 93, - "CreatedAt": "2020-09-07T15:19:17.478524847Z", - "UpdatedAt": "2020-09-07T15:19:17.478524847Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 67, - "CreatedAt": "2020-09-07T15:10:40.25748088Z", - "UpdatedAt": "2020-09-07T15:10:40.25748088Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 41, - "CreatedAt": "2020-09-06T23:14:39.858944067Z", - "UpdatedAt": "2020-09-06T23:14:39.858944067Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 15, - "CreatedAt": "2020-08-28T07:55:27.880309617Z", - "UpdatedAt": "2020-08-28T07:55:27.880309617Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 198, - "CreatedAt": "2020-09-08T21:39:26.580075-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580075-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 172, - "CreatedAt": "2020-09-07T15:47:21.348217832Z", - "UpdatedAt": "2020-09-07T15:47:21.348217832Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 146, - "CreatedAt": "2020-09-07T15:38:56.643456487Z", - "UpdatedAt": "2020-09-07T15:38:56.643456487Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 120, - "CreatedAt": "2020-09-07T15:26:07.517650595Z", - "UpdatedAt": "2020-09-07T15:26:07.517650595Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 94, - "CreatedAt": "2020-09-07T15:19:17.478603147Z", - "UpdatedAt": "2020-09-07T15:19:17.478603147Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 68, - "CreatedAt": "2020-09-07T15:10:40.257557681Z", - "UpdatedAt": "2020-09-07T15:10:40.257557681Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 42, - "CreatedAt": "2020-09-06T23:14:39.859017069Z", - "UpdatedAt": "2020-09-06T23:14:39.859017069Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 16, - "CreatedAt": "2020-08-28T07:55:27.880411683Z", - "UpdatedAt": "2020-08-28T07:55:27.880411683Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 199, - "CreatedAt": "2020-09-08T21:39:26.580136-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580136-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 173, - "CreatedAt": "2020-09-07T15:47:21.348293632Z", - "UpdatedAt": "2020-09-07T15:47:21.348293632Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 147, - "CreatedAt": "2020-09-07T15:38:56.643525088Z", - "UpdatedAt": "2020-09-07T15:38:56.643525088Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 121, - "CreatedAt": "2020-09-07T15:26:07.517759798Z", - "UpdatedAt": "2020-09-07T15:26:07.517759798Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 95, - "CreatedAt": "2020-09-07T15:19:17.478705847Z", - "UpdatedAt": "2020-09-07T15:19:17.478705847Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 69, - "CreatedAt": "2020-09-07T15:10:40.257628781Z", - "UpdatedAt": "2020-09-07T15:10:40.257628781Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 43, - "CreatedAt": "2020-09-06T23:14:39.859087271Z", - "UpdatedAt": "2020-09-06T23:14:39.859087271Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 17, - "CreatedAt": "2020-08-28T07:55:27.880496133Z", - "UpdatedAt": "2020-08-28T07:55:27.880496133Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 200, - "CreatedAt": "2020-09-08T21:39:26.580199-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580199-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 174, - "CreatedAt": "2020-09-07T15:47:21.348561033Z", - "UpdatedAt": "2020-09-07T15:47:21.348561033Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 148, - "CreatedAt": "2020-09-07T15:38:56.643590489Z", - "UpdatedAt": "2020-09-07T15:38:56.643590489Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 122, - "CreatedAt": "2020-09-07T15:26:07.5178383Z", - "UpdatedAt": "2020-09-07T15:26:07.5178383Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 96, - "CreatedAt": "2020-09-07T15:19:17.478776947Z", - "UpdatedAt": "2020-09-07T15:19:17.478776947Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 70, - "CreatedAt": "2020-09-07T15:10:40.257696282Z", - "UpdatedAt": "2020-09-07T15:10:40.257696282Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 44, - "CreatedAt": "2020-09-06T23:14:39.859153473Z", - "UpdatedAt": "2020-09-06T23:14:39.859153473Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 18, - "CreatedAt": "2020-08-28T07:55:27.8805957Z", - "UpdatedAt": "2020-08-28T07:55:27.8805957Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 1410362924, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 201, - "CreatedAt": "2020-09-08T21:39:26.580259-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580259-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 175, - "CreatedAt": "2020-09-07T15:47:21.348729333Z", - "UpdatedAt": "2020-09-07T15:47:21.348729333Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 149, - "CreatedAt": "2020-09-07T15:38:56.643654789Z", - "UpdatedAt": "2020-09-07T15:38:56.643654789Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 123, - "CreatedAt": "2020-09-07T15:26:07.517916302Z", - "UpdatedAt": "2020-09-07T15:26:07.517916302Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 97, - "CreatedAt": "2020-09-07T15:19:17.478847046Z", - "UpdatedAt": "2020-09-07T15:19:17.478847046Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 71, - "CreatedAt": "2020-09-07T15:10:40.257761682Z", - "UpdatedAt": "2020-09-07T15:10:40.257761682Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 45, - "CreatedAt": "2020-09-06T23:14:39.859216975Z", - "UpdatedAt": "2020-09-06T23:14:39.859216975Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 19, - "CreatedAt": "2020-08-28T07:55:27.880669044Z", - "UpdatedAt": "2020-08-28T07:55:27.880669044Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 202, - "CreatedAt": "2020-09-08T21:39:26.580325-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580325-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 176, - "CreatedAt": "2020-09-07T15:47:21.348844733Z", - "UpdatedAt": "2020-09-07T15:47:21.348844733Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 150, - "CreatedAt": "2020-09-07T15:38:56.64372119Z", - "UpdatedAt": "2020-09-07T15:38:56.64372119Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 124, - "CreatedAt": "2020-09-07T15:26:07.517990504Z", - "UpdatedAt": "2020-09-07T15:26:07.517990504Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 98, - "CreatedAt": "2020-09-07T15:19:17.478914046Z", - "UpdatedAt": "2020-09-07T15:19:17.478914046Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 72, - "CreatedAt": "2020-09-07T15:10:40.257850983Z", - "UpdatedAt": "2020-09-07T15:10:40.257850983Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 46, - "CreatedAt": "2020-09-06T23:14:39.859281377Z", - "UpdatedAt": "2020-09-06T23:14:39.859281377Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 20, - "CreatedAt": "2020-08-28T07:55:27.880762037Z", - "UpdatedAt": "2020-08-28T07:55:27.880762037Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 203, - "CreatedAt": "2020-09-08T21:39:26.580401-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580401-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 177, - "CreatedAt": "2020-09-07T15:47:21.348954434Z", - "UpdatedAt": "2020-09-07T15:47:21.348954434Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 151, - "CreatedAt": "2020-09-07T15:38:56.64378519Z", - "UpdatedAt": "2020-09-07T15:38:56.64378519Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 125, - "CreatedAt": "2020-09-07T15:26:07.518063306Z", - "UpdatedAt": "2020-09-07T15:26:07.518063306Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 99, - "CreatedAt": "2020-09-07T15:19:17.478978246Z", - "UpdatedAt": "2020-09-07T15:19:17.478978246Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 73, - "CreatedAt": "2020-09-07T15:10:40.257919784Z", - "UpdatedAt": "2020-09-07T15:10:40.257919784Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 47, - "CreatedAt": "2020-09-06T23:14:39.859343279Z", - "UpdatedAt": "2020-09-06T23:14:39.859343279Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 21, - "CreatedAt": "2020-08-28T07:55:27.880831527Z", - "UpdatedAt": "2020-08-28T07:55:27.880831527Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 204, - "CreatedAt": "2020-09-08T21:39:26.580463-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580463-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 178, - "CreatedAt": "2020-09-07T15:47:21.349067634Z", - "UpdatedAt": "2020-09-07T15:47:21.349067634Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 152, - "CreatedAt": "2020-09-07T15:38:56.643850091Z", - "UpdatedAt": "2020-09-07T15:38:56.643850091Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 126, - "CreatedAt": "2020-09-07T15:26:07.518138308Z", - "UpdatedAt": "2020-09-07T15:26:07.518138308Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 100, - "CreatedAt": "2020-09-07T15:19:17.479060646Z", - "UpdatedAt": "2020-09-07T15:19:17.479060646Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 74, - "CreatedAt": "2020-09-07T15:10:40.257991684Z", - "UpdatedAt": "2020-09-07T15:10:40.257991684Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 48, - "CreatedAt": "2020-09-06T23:14:39.859415381Z", - "UpdatedAt": "2020-09-06T23:14:39.859415381Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 22, - "CreatedAt": "2020-08-28T07:55:27.88091659Z", - "UpdatedAt": "2020-08-28T07:55:27.88091659Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 205, - "CreatedAt": "2020-09-08T21:39:26.580519-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580519-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 179, - "CreatedAt": "2020-09-07T15:47:21.349173034Z", - "UpdatedAt": "2020-09-07T15:47:21.349173034Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 153, - "CreatedAt": "2020-09-07T15:38:56.643916492Z", - "UpdatedAt": "2020-09-07T15:38:56.643916492Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 127, - "CreatedAt": "2020-09-07T15:26:07.51821131Z", - "UpdatedAt": "2020-09-07T15:26:07.51821131Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 101, - "CreatedAt": "2020-09-07T15:19:17.479156345Z", - "UpdatedAt": "2020-09-07T15:19:17.479156345Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 75, - "CreatedAt": "2020-09-07T15:10:40.258061285Z", - "UpdatedAt": "2020-09-07T15:10:40.258061285Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 49, - "CreatedAt": "2020-09-06T23:14:39.859474183Z", - "UpdatedAt": "2020-09-06T23:14:39.859474183Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 23, - "CreatedAt": "2020-08-28T07:55:27.880989189Z", - "UpdatedAt": "2020-08-28T07:55:27.880989189Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 206, - "CreatedAt": "2020-09-08T21:39:26.580579-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580579-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 180, - "CreatedAt": "2020-09-07T15:47:21.349306435Z", - "UpdatedAt": "2020-09-07T15:47:21.349306435Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 154, - "CreatedAt": "2020-09-07T15:38:56.643981692Z", - "UpdatedAt": "2020-09-07T15:38:56.643981692Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 128, - "CreatedAt": "2020-09-07T15:26:07.518286712Z", - "UpdatedAt": "2020-09-07T15:26:07.518286712Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 102, - "CreatedAt": "2020-09-07T15:19:17.479270845Z", - "UpdatedAt": "2020-09-07T15:19:17.479270845Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 76, - "CreatedAt": "2020-09-07T15:10:40.258142985Z", - "UpdatedAt": "2020-09-07T15:10:40.258142985Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 50, - "CreatedAt": "2020-09-06T23:14:39.859534584Z", - "UpdatedAt": "2020-09-06T23:14:39.859534584Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 24, - "CreatedAt": "2020-08-28T07:55:27.881076285Z", - "UpdatedAt": "2020-08-28T07:55:27.881076285Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 207, - "CreatedAt": "2020-09-08T21:39:26.580636-07:00", - "UpdatedAt": "2020-09-08T21:39:26.580636-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 181, - "CreatedAt": "2020-09-07T15:47:21.349410535Z", - "UpdatedAt": "2020-09-07T15:47:21.349410535Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 155, - "CreatedAt": "2020-09-07T15:38:56.644047493Z", - "UpdatedAt": "2020-09-07T15:38:56.644047493Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 129, - "CreatedAt": "2020-09-07T15:26:07.518360714Z", - "UpdatedAt": "2020-09-07T15:26:07.518360714Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 103, - "CreatedAt": "2020-09-07T15:19:17.479342345Z", - "UpdatedAt": "2020-09-07T15:19:17.479342345Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 77, - "CreatedAt": "2020-09-07T15:10:40.258232186Z", - "UpdatedAt": "2020-09-07T15:10:40.258232186Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 51, - "CreatedAt": "2020-09-06T23:14:39.859593786Z", - "UpdatedAt": "2020-09-06T23:14:39.859593786Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 25, - "CreatedAt": "2020-08-28T07:55:27.881149036Z", - "UpdatedAt": "2020-08-28T07:55:27.881149036Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 208, - "CreatedAt": "2020-09-08T21:39:26.5807-07:00", - "UpdatedAt": "2020-09-08T21:39:26.5807-07:00", - "DeletedAt": null, - "smart_id": 48, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 182, - "CreatedAt": "2020-09-07T15:47:21.350041836Z", - "UpdatedAt": "2020-09-07T15:47:21.350041836Z", - "DeletedAt": null, - "smart_id": 42, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 156, - "CreatedAt": "2020-09-07T15:38:56.644111093Z", - "UpdatedAt": "2020-09-07T15:38:56.644111093Z", - "DeletedAt": null, - "smart_id": 36, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 130, - "CreatedAt": "2020-09-07T15:26:07.518435116Z", - "UpdatedAt": "2020-09-07T15:26:07.518435116Z", - "DeletedAt": null, - "smart_id": 30, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 104, - "CreatedAt": "2020-09-07T15:19:17.479407945Z", - "UpdatedAt": "2020-09-07T15:19:17.479407945Z", - "DeletedAt": null, - "smart_id": 24, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 78, - "CreatedAt": "2020-09-07T15:10:40.258301886Z", - "UpdatedAt": "2020-09-07T15:10:40.258301886Z", - "DeletedAt": null, - "smart_id": 18, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 52, - "CreatedAt": "2020-09-06T23:14:39.859652488Z", - "UpdatedAt": "2020-09-06T23:14:39.859652488Z", - "DeletedAt": null, - "smart_id": 12, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 26, - "CreatedAt": "2020-08-28T07:55:27.881226699Z", - "UpdatedAt": "2020-08-28T07:55:27.881226699Z", - "DeletedAt": null, - "smart_id": 6, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "read_total_uncorrected_errors": { + "attribute_id": "read_total_uncorrected_errors", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "scsi_grown_defect_list": { + "attribute_id": "scsi_grown_defect_list", "value": 0, "thresh": 0, - "transformed_value": 0 - }] - }] + "transformed_value": 0, + "status": 0 + }, + "write_correction_algorithm_invocations": { + "attribute_id": "write_correction_algorithm_invocations", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_eccdelayed": { + "attribute_id": "write_errors_corrected_by_eccdelayed", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_eccfast": { + "attribute_id": "write_errors_corrected_by_eccfast", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_errors_corrected_by_rereads_rewrites": { + "attribute_id": "write_errors_corrected_by_rereads_rewrites", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + }, + "write_total_errors_corrected": { + "attribute_id": "write_total_errors_corrected", + "value": 0, + "thresh": -1, + "transformed_value": 0, + "status": 0 + }, + "write_total_uncorrected_errors": { + "attribute_id": "write_total_uncorrected_errors", + "value": 0, + "thresh": 0, + "transformed_value": 0, + "status": 0 + } + }, + "Status": 0 }] - }, "metadata": { - "read.correction_algorithm_invocations": { + }, + "metadata": { + "read_correction_algorithm_invocations": { + "display_name": "Read Correction Algorithm Invocations", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccdelayed": { + "display_name": "Read Errors Corrected by ECC Delayed", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccfast": { + "display_name": "Read Errors Corrected by ECC Fast", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_rereads_rewrites": { + "display_name": "Read Errors Corrected by ReReads/ReWrites", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "read_total_errors_corrected": { + "display_name": "Read Total Errors Corrected", "ideal": "", "critical": false, "description": "", "display_type": "" }, - "read.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_rereads_rewrites": { + "read_total_uncorrected_errors": { + "display_name": "Read Total Uncorrected Errors", "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "read.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "scsi_grown_defect_list": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "write.correction_algorithm_invocations": { + "scsi_grown_defect_list": { + "display_name": "Grown Defect List", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "write_correction_algorithm_invocations": { + "display_name": "Write Correction Algorithm Invocations", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_eccdelayed": { + "display_name": "Write Errors Corrected by ECC Delayed", "ideal": "", "critical": false, "description": "", "display_type": "" }, - "write.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_rereads_rewrites": { + "write_errors_corrected_by_eccfast": { + "display_name": "Write Errors Corrected by ECC Fast", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_rereads_rewrites": { + "display_name": "Write Errors Corrected by ReReads/ReWrites", "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "write.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""} - }, "success": true + "write_total_errors_corrected": { + "display_name": "Write Total Errors Corrected", + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_total_uncorrected_errors": { + "display_name": "Write Total Uncorrected Errors", + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + } + }, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdf.ts b/webapp/frontend/src/app/data/mock/device/details/sdf.ts index cdf96da..15949dd 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdf.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdf.ts @@ -1,1601 +1,29 @@ export const sdf = { "data": { - "CreatedAt": "2020-09-29T03:17:30.813487336Z", - "UpdatedAt": "2020-09-29T03:17:31.04293448Z", - "DeletedAt": null, - "wwn": "0x5000c500c0558f02", - "device_name": "sdc", - "manufacturer": "", - "model_name": "ST8000VN004-2M2101", - "interface_type": "", - "interface_speed": "6.0 Gb/s", - "serial_number": "WKD01Y5S", - "firmware": "SC60", - "rotational_speed": 7200, - "capacity": 8001563222016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "scsi", - "smart_results": [{ - "ID": 1, - "CreatedAt": "2020-09-29T03:17:31.063859162Z", - "UpdatedAt": "2020-09-29T03:17:31.063859162Z", + "device": { + "CreatedAt": "2021-06-24T21:17:31.305246-07:00", + "UpdatedAt": "2021-06-24T21:17:31.305246-07:00", "DeletedAt": null, - "device_wwn": "0x5000c500c0558f02", - "date": "2020-09-29T03:17:30Z", - "smart_status": "passed", - "temp": 39, - "power_on_hours": 9499, - "power_cycle_count": 22, - "ata_attributes": [{ - "ID": 1, - "CreatedAt": "2020-09-29T03:17:31.064174997Z", - "UpdatedAt": "2020-09-29T03:17:31.064174997Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 79, - "worst": 64, - "thresh": 44, - "raw_value": 78022392, - "raw_string": "78022392", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 2, - "CreatedAt": "2020-09-29T03:17:31.064379412Z", - "UpdatedAt": "2020-09-29T03:17:31.064379412Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 95, - "worst": 86, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.11452195377351217 - }, { - "ID": 3, - "CreatedAt": "2020-09-29T03:17:31.064506775Z", - "UpdatedAt": "2020-09-29T03:17:31.064506775Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 20, - "raw_value": 220, - "raw_string": "220", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 4, - "CreatedAt": "2020-09-29T03:17:31.064621265Z", - "UpdatedAt": "2020-09-29T03:17:31.064621265Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 10, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025169175350572493 - }, { - "ID": 5, - "CreatedAt": "2020-09-29T03:17:31.064742769Z", - "UpdatedAt": "2020-09-29T03:17:31.064742769Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 86, - "worst": 60, - "thresh": 45, - "raw_value": 4679507461, - "raw_string": "4679507461", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.08725919610118257 - }, { - "ID": 6, - "CreatedAt": "2020-09-29T03:17:31.064850152Z", - "UpdatedAt": "2020-09-29T03:17:31.064850152Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 90, - "worst": 90, - "thresh": 0, - "raw_value": 9499, - "raw_string": "9499", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 7, - "CreatedAt": "2020-09-29T03:17:31.064970318Z", - "UpdatedAt": "2020-09-29T03:17:31.064970318Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 97, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.05459827163896099 - }, { - "ID": 8, - "CreatedAt": "2020-09-29T03:17:31.065072898Z", - "UpdatedAt": "2020-09-29T03:17:31.065072898Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 20, - "raw_value": 22, - "raw_string": "22", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.038210930067894826 - }, { - "ID": 9, - "CreatedAt": "2020-09-29T03:17:31.065366547Z", - "UpdatedAt": "2020-09-29T03:17:31.065366547Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 18, - "name": "Unknown_Attribute", - "value": 100, - "worst": 100, - "thresh": 50, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 10, - "CreatedAt": "2020-09-29T03:17:31.065539403Z", - "UpdatedAt": "2020-09-29T03:17:31.065539403Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 187, - "name": "Reported Uncorrectable Errors", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028130798308190524 - }, { - "ID": 11, - "CreatedAt": "2020-09-29T03:17:31.065665808Z", - "UpdatedAt": "2020-09-29T03:17:31.065665808Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 188, - "name": "Command Timeout", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.024893587674442153 - }, { - "ID": 12, - "CreatedAt": "2020-09-29T03:17:31.065780779Z", - "UpdatedAt": "2020-09-29T03:17:31.065780779Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 190, - "name": "Temperature Difference", - "value": 61, - "worst": 46, - "thresh": 40, - "raw_value": 740294695, - "raw_string": "39 (Min/Max 32/44)", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 13, - "CreatedAt": "2020-09-29T03:17:31.065931499Z", - "UpdatedAt": "2020-09-29T03:17:31.065931499Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 4, - "raw_string": "4", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.0738571777154862 - }, { - "ID": 14, - "CreatedAt": "2020-09-29T03:17:31.066043189Z", - "UpdatedAt": "2020-09-29T03:17:31.066043189Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1680, - "raw_string": "1680", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 15, - "CreatedAt": "2020-09-29T03:17:31.066162028Z", - "UpdatedAt": "2020-09-29T03:17:31.066162028Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 194, - "name": "Temperature", - "value": 39, - "worst": 54, - "thresh": 0, - "raw_value": 81604378663, - "raw_string": "39 (0 19 0 0 0)", - "when_failed": "", - "transformed_value": 39, - "status": "passed" - }, { - "ID": 16, - "CreatedAt": "2020-09-29T03:17:31.066270283Z", - "UpdatedAt": "2020-09-29T03:17:31.066270283Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 195, - "name": "Hardware ECC Recovered", - "value": 79, - "worst": 64, - "thresh": 0, - "raw_value": 78022392, - "raw_string": "78022392", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 17, - "CreatedAt": "2020-09-29T03:17:31.066381938Z", - "UpdatedAt": "2020-09-29T03:17:31.066381938Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025540791394761345 - }, { - "ID": 18, - "CreatedAt": "2020-09-29T03:17:31.066497143Z", - "UpdatedAt": "2020-09-29T03:17:31.066497143Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028675322159886437 - }, { - "ID": 19, - "CreatedAt": "2020-09-29T03:17:31.066632808Z", - "UpdatedAt": "2020-09-29T03:17:31.066632808Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 20, - "CreatedAt": "2020-09-29T03:17:31.066757646Z", - "UpdatedAt": "2020-09-29T03:17:31.066757646Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 240, - "name": "Head Flying Hours", - "value": 100, - "worst": 253, - "thresh": 0, - "raw_value": 21887153349770, - "raw_string": "9354 (19 232 0)", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 21, - "CreatedAt": "2020-09-29T03:17:31.06687199Z", - "UpdatedAt": "2020-09-29T03:17:31.06687199Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 241, - "name": "Total LBAs Written", - "value": 100, - "worst": 253, - "thresh": 0, - "raw_value": 78115437520, - "raw_string": "78115437520", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }, { - "ID": 22, - "CreatedAt": "2020-09-29T03:17:31.066984948Z", - "UpdatedAt": "2020-09-29T03:17:31.066984948Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 242, - "name": "Total LBAs Read", - "value": 100, - "worst": 253, - "thresh": 0, - "raw_value": 226428055205, - "raw_string": "226428055205", - "when_failed": "", - "transformed_value": 0, - "status": "passed" - }], - "nvme_attributes": [], - "scsi_attributes": [] - }] - }, "metadata": { - "1": { - "ideal": "low", - "critical": false, - "description": "(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 80, - "high": 95, - "annual_failure_rate": 0.8879749768303985, - "error_interval": [0.682344353388663, 1.136105732920724] - }, { - "low": 95, - "high": 110, - "annual_failure_rate": 0.034155719633986996, - "error_interval": [0.030188482024981093, 0.038499386872354435] - }, { - "low": 110, - "high": 125, - "annual_failure_rate": 0.06390002135229157, - "error_interval": [0.05852004676110847, 0.06964160930553712] - }, {"low": 125, "high": 140, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 140, - "high": 155, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 155, "high": 170, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 170, - "high": 185, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 185, - "high": 200, - "annual_failure_rate": 0.044823775021490854, - "error_interval": [0.032022762038723306, 0.06103725943096589] - }], - "display_type": "normalized" - }, - "10": { - "ideal": "low", - "critical": true, - "description": "Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.05459827163896099, - "error_interval": [0.05113785787727033, 0.05823122757702782] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] - }], - "display_type": "raw" - }, - "11": { - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.04658866433672694, - "error_interval": [0.03357701137320878, 0.06297433993055492] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] - }, {"low": 80, "high": 160, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 160, - "high": 240, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 240, "high": 320, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 320, - "high": 400, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 400, "high": 480, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 480, - "high": 560, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }], - "display_type": "raw" - }, - "12": { - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count of full hard disk power on/off cycles.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.019835987118930823, - "error_interval": [0.016560870164523494, 0.023569242386797896] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.038210930067894826, - "error_interval": [0.03353859179329295, 0.0433520775718649] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11053528307302571, - "error_interval": [0.09671061589521368, 0.1257816678419765] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16831189443375036, - "error_interval": [0.1440976510675928, 0.19543066007594895] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.20630344262550107, - "error_interval": [0.1693965932069108, 0.2488633537247856] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1030972634140512, - "error_interval": [0.06734655535304743, 0.15106137807407605] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12354840389522469, - "error_interval": [0.06578432170016109, 0.21127153335749593] - }], - "display_type": "raw" - }, - "13": { - "ideal": "low", - "critical": false, - "description": "Uncorrected read errors reported to the operating system.", - "display_type": "normalized" - }, - "170": {"ideal": "", "critical": false, "description": "See attribute E8.", "display_type": "normalized"}, - "171": { - "ideal": "", - "critical": false, - "description": "(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.", - "display_type": "normalized" - }, - "172": { - "ideal": "", - "critical": false, - "description": "(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.", - "display_type": "normalized" - }, - "173": { - "ideal": "", - "critical": false, - "description": "Counts the maximum worst erase count on any block.", - "display_type": "normalized" - }, - "174": { - "ideal": "", - "critical": false, - "description": "Also known as Power-off Retract Count per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an unclean shutdown is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.", - "display_type": "" - }, - "175": { - "ideal": "", - "critical": false, - "description": "Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \\u003c= result \\u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.", - "display_type": "normalized" - }, - "176": { - "ideal": "", - "critical": false, - "description": "S.M.A.R.T. parameter indicates a number of flash erase command failures.", - "display_type": "normalized" - }, - "177": { - "ideal": "", - "critical": false, - "description": "Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ", - "display_type": "normalized" - }, - "179": { - "ideal": "", - "critical": false, - "description": "Pre-Fail attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "180": { - "ideal": "", - "critical": false, - "description": "Pre-Fail attribute used at least in HP devices. ", - "display_type": "normalized" - }, - "181": { - "ideal": "", - "critical": false, - "description": "Total number of Flash program operation failures since the drive was deployed.", - "display_type": "normalized" - }, - "182": { - "ideal": "", - "critical": false, - "description": "Pre-Fail Attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "183": { - "ideal": "low", - "critical": false, - "description": "Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09084549203210031, - "error_interval": [0.08344373475686712, 0.09872777224842152] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.05756065656498585, - "error_interval": [0.04657000847949464, 0.07036491775108872] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.6193088626208925, - "error_interval": [0.41784508895529787, 0.8841019099092139] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.5533447034299792, - "error_interval": [0.31628430884775033, 0.8985971312402635] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.3882388694727245, - "error_interval": [0.21225380267814295, 0.6513988534774338] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.37116708385481856, - "error_interval": [0.19763084005134446, 0.6347070173754686] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.2561146752205292, - "error_interval": [0.10297138269895259, 0.5276941165819332] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.40299684542586756, - "error_interval": [0.16202563309223209, 0.8303275247667772] - }, {"low": 130, "high": 260, "annual_failure_rate": 0, "error_interval": [0, 0]}], - "display_type": "raw" - }, - "184": { - "ideal": "low", - "critical": true, - "description": "This attribute is a part of Hewlett-Packards SMART IV technology, as well as part of other vendors IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drives cache RAM", - "observed_thresholds": [{ - "low": 93, - "high": 94, - "annual_failure_rate": 1.631212012870933, - "error_interval": [1.055634407303844, 2.407990716767714] - }, {"low": 94, "high": 95, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 95, - "high": 96, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 96, "high": 97, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 97, - "high": 97, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 97, - "high": 98, - "annual_failure_rate": 1.8069306930693072, - "error_interval": [0.04574752432804858, 10.067573453924245] - }, { - "low": 98, - "high": 99, - "annual_failure_rate": 0.8371559633027523, - "error_interval": [0.10138347095016888, 3.0240951820174824] - }, { - "low": 99, - "high": 100, - "annual_failure_rate": 0.09334816849865138, - "error_interval": [0.08689499010435861, 0.10015372448181788] - }], - "display_type": "normalized" - }, - "185": { - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "186": { - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "187": { - "ideal": "low", - "critical": true, - "description": "The count of errors that could not be recovered using hardware ECC (see attribute 195).", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028130798308190524, - "error_interval": [0.024487830609364304, 0.032162944988161336] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.33877621175661743, - "error_interval": [0.22325565823630591, 0.4929016016666955] - }, { - "low": 1, - "high": 3, - "annual_failure_rate": 0.24064820598237213, - "error_interval": [0.14488594021076606, 0.3758019832614595] - }, { - "low": 3, - "high": 6, - "annual_failure_rate": 0.5014425058387142, - "error_interval": [0.3062941096766342, 0.7744372808405151] - }, { - "low": 6, - "high": 11, - "annual_failure_rate": 0.38007108544136836, - "error_interval": [0.2989500188963677, 0.4764223967570595] - }, { - "low": 11, - "high": 20, - "annual_failure_rate": 0.5346094598348444, - "error_interval": [0.40595137663302483, 0.6911066985735377] - }, { - "low": 20, - "high": 35, - "annual_failure_rate": 0.8428063943161636, - "error_interval": [0.6504601819243522, 1.0742259350903411] - }, { - "low": 35, - "high": 65, - "annual_failure_rate": 1.4429071005017484, - "error_interval": [1.1405581860945952, 1.8008133631629157] - }, { - "low": 65, - "high": 120, - "annual_failure_rate": 1.6190935390549661, - "error_interval": [1.0263664163011208, 2.4294352761068576] - }], - "display_type": "raw" - }, - "188": { - "ideal": "low", - "critical": true, - "description": "The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.024893587674442153, - "error_interval": [0.020857343769186413, 0.0294830350167543] - }, { - "low": 0, - "high": 13, - "annual_failure_rate": 0.10044174089362015, - "error_interval": [0.0812633664077498, 0.1227848196758574] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.334030592234279, - "error_interval": [0.2523231196342665, 0.4337665082489293] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.36724705400842445, - "error_interval": [0.30398009356575617, 0.4397986538328568] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.29848155926978354, - "error_interval": [0.2509254838615984, 0.35242890006477073] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.2203079701535098, - "error_interval": [0.18366082845676174, 0.26212468677179274] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.3018169948863018, - "error_interval": [0.23779746376787655, 0.37776897542831006] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.32854928239235887, - "error_interval": [0.2301118782147336, 0.4548506948185028] - }, { - "low": 91, - "high": 104, - "annual_failure_rate": 0.28488916640649387, - "error_interval": [0.1366154288236293, 0.5239213202729072] - }], - "display_type": "raw" - }, - "189": { - "ideal": "low", - "critical": false, - "description": "HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09070551401946862, - "error_interval": [0.08018892683853401, 0.10221801211956287] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.0844336097370013, - "error_interval": [0.07299813695315267, 0.09715235540340669] - }, { - "low": 2, - "high": 5, - "annual_failure_rate": 0.07943219628781906, - "error_interval": [0.06552176680630226, 0.09542233189887633] - }, { - "low": 5, - "high": 13, - "annual_failure_rate": 0.09208847603893404, - "error_interval": [0.07385765060838133, 0.11345557807163456] - }, { - "low": 13, - "high": 30, - "annual_failure_rate": 0.18161161650924224, - "error_interval": [0.13858879602902988, 0.23377015012749933] - }, { - "low": 30, - "high": 70, - "annual_failure_rate": 0.2678117886102384, - "error_interval": [0.19044036194841887, 0.36610753129699186] - }, { - "low": 70, - "high": 150, - "annual_failure_rate": 0.26126480798826107, - "error_interval": [0.15958733218826962, 0.4035023060905559] - }, { - "low": 150, - "high": 350, - "annual_failure_rate": 0.11337164155924832, - "error_interval": [0.030889956621649995, 0.2902764300762812] - }], - "display_type": "raw" - }, - "190": { - "ideal": "", - "critical": false, - "description": "Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.", - "display_type": "normalized" - }, - "191": { - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration. ", - "display_type": "normalized" - }, - "192": { - "ideal": "low", - "critical": false, - "description": "Number of power-off or emergency retract cycles.", - "observed_thresholds": [{ - "low": 1, - "high": 2, - "annual_failure_rate": 0.02861098445412803, - "error_interval": [0.022345416230915037, 0.036088863823297186] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.0738571777154862, - "error_interval": [0.06406927746420421, 0.0847175264009771] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.11970378206823593, - "error_interval": [0.10830059875098269, 0.13198105985656441] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.027266868552620425, - "error_interval": [0.021131448605713823, 0.03462795920968522] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 0.011741682974559688, - "error_interval": [0.00430899071133239, 0.025556700631152028] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 0.012659940134091309, - "error_interval": [0.00607093338127348, 0.023282080653656938] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 0.01634692899031039, - "error_interval": [0.009522688540043157, 0.026173016865409605] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 0.005190074354440066, - "error_interval": [0.0025908664180103293, 0.009286476666453648] - }], - "display_type": "raw" - }, - "193": { - "ideal": "low", - "critical": false, - "description": "Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.", - "display_type": "normalized" - }, - "194": { - "ideal": "low", - "critical": false, - "description": "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", - "transform_value_unit": "°C", - "display_type": "transformed" - }, - "195": { - "ideal": "", - "critical": false, - "description": "(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 12, - "high": 24, - "annual_failure_rate": 0.31472916829975706, - "error_interval": [0.15711166685282174, 0.5631374192486645] - }, { - "low": 24, - "high": 36, - "annual_failure_rate": 0.15250310197260136, - "error_interval": [0.10497611828070175, 0.21417105521823687] - }, { - "low": 36, - "high": 48, - "annual_failure_rate": 0.2193119102723874, - "error_interval": [0.16475385681835103, 0.28615447006525274] - }, { - "low": 48, - "high": 60, - "annual_failure_rate": 0.05672658497265746, - "error_interval": [0.043182904776447234, 0.07317316161437043] - }, {"low": 60, "high": 72, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 72, - "high": 84, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 84, "high": 96, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 96, - "high": 108, - "annual_failure_rate": 0.04074570216566197, - "error_interval": [0.001031591863615295, 0.22702052218047528] - }], - "display_type": "normalized" - }, - "196": { - "ideal": "low", - "critical": true, - "description": "Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.007389855800729792, - "error_interval": [0.005652654139732716, 0.009492578928212054] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.026558331312151347, - "error_interval": [0.005476966404484466, 0.07761471429677293] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.02471894893674658, - "error_interval": [0.0006258296027540169, 0.13772516847438018] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.03200912040691046, - "error_interval": [0.0008104007642081744, 0.17834340416493005] - }, { - "low": 4, - "high": 7, - "annual_failure_rate": 0.043078012510326925, - "error_interval": [0.001090640849081295, 0.24001532369794615] - }, { - "low": 7, - "high": 11, - "annual_failure_rate": 0.033843300880853036, - "error_interval": [0.0008568381932559863, 0.18856280368036135] - }, { - "low": 11, - "high": 17, - "annual_failure_rate": 0.16979376647542252, - "error_interval": [0.035015556653263225, 0.49620943874336304] - }, { - "low": 17, - "high": 27, - "annual_failure_rate": 0.059042381106438044, - "error_interval": [0.0014948236677880642, 0.32896309247698113] - }, { - "low": 27, - "high": 45, - "annual_failure_rate": 0.24701105346266636, - "error_interval": [0.050939617608142244, 0.721871118983972] - }], - "display_type": "raw" - }, - "197": { - "ideal": "low", - "critical": true, - "description": "Count of unstable sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time its written.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025540791394761345, - "error_interval": [0.023161777231213983, 0.02809784482748174] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.34196613799103254, - "error_interval": [0.22723401523750225, 0.4942362818474496] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.6823772508117681, - "error_interval": [0.41083568090070416, 1.0656166047061635] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.6108100007493069, - "error_interval": [0.47336936083368364, 0.7757071095273286] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.9564879341127684, - "error_interval": [0.7701044196378299, 1.174355230793638] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 1.6519989942167461, - "error_interval": [1.328402276482456, 2.0305872327541317] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 2.5137741046831956, - "error_interval": [1.9772427971560862, 3.1510376077891613] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 3.3203378817413904, - "error_interval": [2.5883662702274406, 4.195047163573006] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 3.133047210300429, - "error_interval": [1.1497731080460096, 6.819324775707182] - }], - "display_type": "raw" - }, - "198": { - "ideal": "low", - "critical": true, - "description": "The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028675322159886437, - "error_interval": [0.026159385510707116, 0.03136793218577656] - }, { - "low": 0, - "high": 2, - "annual_failure_rate": 0.8135764944275583, - "error_interval": [0.40613445471964466, 1.4557130815309443] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 1.1173469387755102, - "error_interval": [0.5773494680315332, 1.9517802404552516] - }, { - "low": 4, - "high": 6, - "annual_failure_rate": 1.3558692421991083, - "error_interval": [0.4402470522980859, 3.1641465148237544] - }, { - "low": 6, - "high": 8, - "annual_failure_rate": 0.7324414715719062, - "error_interval": [0.15104704003805655, 2.140504796291604] - }, { - "low": 8, - "high": 10, - "annual_failure_rate": 0.5777213677766163, - "error_interval": [0.43275294849366835, 0.7556737733062419] - }, { - "low": 10, - "high": 12, - "annual_failure_rate": 1.7464114832535886, - "error_interval": [0.47583835092536914, 4.471507017371231] - }, { - "low": 12, - "high": 14, - "annual_failure_rate": 2.6449275362318843, - "error_interval": [0.3203129951758959, 9.554387676519005] - }, { - "low": 14, - "high": 16, - "annual_failure_rate": 0.796943231441048, - "error_interval": [0.5519063550198366, 1.113648286331181] - }], - "display_type": "raw" - }, - "199": { - "ideal": "low", - "critical": false, - "description": "The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).", - "observed_thresholds": [{ - "low": 0, - "high": 1, - "annual_failure_rate": 0.04068379316116366, - "error_interval": [0.037534031558106425, 0.04402730201866553] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.1513481259734218, - "error_interval": [0.12037165605991791, 0.18786293065527596] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.16849758722418978, - "error_interval": [0.12976367397863445, 0.2151676572000481] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.15385127340491614, - "error_interval": [0.10887431782430312, 0.21117289306426648] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.14882894050104387, - "error_interval": [0.09631424312463635, 0.2197008753522735] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.20878219917249793, - "error_interval": [0.14086447304552446, 0.29804957135975] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.13742940270409038, - "error_interval": [0.06860426267470295, 0.24589916335290812] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.22336578581363, - "error_interval": [0.11150339549604707, 0.39966309081252904] - }, { - "low": 130, - "high": 260, - "annual_failure_rate": 0.18277416124186283, - "error_interval": [0.07890890989692058, 0.3601379610272007] - }], - "display_type": "raw" - }, - "2": { - "ideal": "high", - "critical": false, - "description": "Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.", - "display_type": "normalized" - }, - "200": { - "ideal": "low", - "critical": false, - "description": "The count of errors found when writing a sector. The higher the value, the worse the disks mechanical condition is.", - "display_type": "normalized" - }, - "201": { - "ideal": "low", - "critical": true, - "description": "Count indicates the number of uncorrectable software read errors.", - "display_type": "normalized" - }, - "202": { - "ideal": "low", - "critical": false, - "description": "Count of Data Address Mark errors (or vendor-specific).", - "display_type": "normalized" - }, - "203": { - "ideal": "low", - "critical": false, - "description": "The number of errors caused by incorrect checksum during the error correction.", - "display_type": "normalized" - }, - "204": { - "ideal": "low", - "critical": false, - "description": "Count of errors corrected by the internal error correction software.", - "display_type": "" - }, - "205": { - "ideal": "low", - "critical": false, - "description": "Count of errors due to high temperature.", - "display_type": "normalized" - }, - "206": { - "ideal": "", - "critical": false, - "description": "Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.", - "display_type": "normalized" - }, - "207": { - "ideal": "low", - "critical": false, - "description": "Amount of surge current used to spin up the drive.", - "display_type": "normalized" - }, - "208": { - "ideal": "", - "critical": false, - "description": "Count of buzz routines needed to spin up the drive due to insufficient power.", - "display_type": "normalized" - }, - "209": { - "ideal": "", - "critical": false, - "description": "Drives seek performance during its internal tests.", - "display_type": "normalized" - }, - "210": { - "ideal": "", - "critical": false, - "description": "Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.", - "display_type": "normalized" - }, - "211": { - "ideal": "", - "critical": false, - "description": "A recording of a vibration encountered during write operations.", - "display_type": "normalized" - }, - "212": { - "ideal": "", - "critical": false, - "description": "A recording of shock encountered during write operations.", - "display_type": "normalized" - }, - "22": { - "ideal": "high", - "critical": false, - "description": "Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.", - "display_type": "normalized" - }, - "220": { - "ideal": "low", - "critical": false, - "description": "Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.", - "display_type": "normalized" - }, - "221": { - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration.", - "display_type": "normalized" - }, - "222": { - "ideal": "", - "critical": false, - "description": "Time spent operating under data load (movement of magnetic head armature).", - "display_type": "normalized" - }, - "223": { - "ideal": "", - "critical": false, - "description": "Count of times head changes position.", - "display_type": "normalized" - }, - "224": { - "ideal": "low", - "critical": false, - "description": "Resistance caused by friction in mechanical parts while operating.", - "display_type": "normalized" - }, - "225": { - "ideal": "low", - "critical": false, - "description": "Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ", - "display_type": "normalized" - }, - "226": { - "ideal": "", - "critical": false, - "description": "Total time of loading on the magnetic heads actuator (time not spent in parking area).", - "display_type": "normalized" - }, - "227": { - "ideal": "low", - "critical": false, - "description": "Count of attempts to compensate for platter speed variations.[66]", - "display_type": "" - }, - "228": { - "ideal": "low", - "critical": false, - "description": "The number of power-off cycles which are counted whenever there is a retract event and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.", - "display_type": "" - }, - "230": { - "ideal": "", - "critical": false, - "description": "Amplitude of thrashing (repetitive head moving motions between operations).", - "display_type": "normalized" - }, - "231": { - "ideal": "", - "critical": false, - "description": "Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.", - "display_type": "normalized" - }, - "232": { - "ideal": "", - "critical": false, - "description": "Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.", - "display_type": "normalized" - }, - "233": { - "ideal": "", - "critical": false, - "description": "Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.", - "display_type": "normalized" - }, - "234": { - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).", - "display_type": "normalized" - }, - "235": { - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.", - "display_type": "normalized" - }, - "240": { - "ideal": "", - "critical": false, - "description": "Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.", - "display_type": "normalized" - }, - "241": { - "ideal": "", - "critical": false, - "description": "Total count of LBAs written.", - "display_type": "normalized" - }, - "242": { - "ideal": "", - "critical": false, - "description": "Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.", - "display_type": "normalized" - }, - "243": { - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.", - "display_type": "normalized" - }, - "244": { - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.", - "display_type": "normalized" - }, - "249": { - "ideal": "", - "critical": false, - "description": "Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.", - "display_type": "normalized" - }, - "250": { - "ideal": "low", - "critical": false, - "description": "Count of errors while reading from a disk.", - "display_type": "normalized" - }, - "251": { - "ideal": "", - "critical": false, - "description": "The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.", - "display_type": "normalized" - }, - "252": { - "ideal": "", - "critical": false, - "description": "The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.", - "display_type": "normalized" - }, - "254": { - "ideal": "low", - "critical": false, - "description": "Count of Free Fall Events detected.", - "display_type": "normalized" - }, - "3": { - "ideal": "low", - "critical": false, - "description": "Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).", - "observed_thresholds": [{ - "low": 78, - "high": 96, - "annual_failure_rate": 0.11452195377351217, - "error_interval": [0.10591837762295722, 0.12363823501915781] - }, { - "low": 96, - "high": 114, - "annual_failure_rate": 0.040274562840558074, - "error_interval": [0.03465055611002801, 0.046551312468303144] - }, { - "low": 114, - "high": 132, - "annual_failure_rate": 0.009100406705780476, - "error_interval": [0.006530608971356785, 0.012345729280075591] - }, { - "low": 132, - "high": 150, - "annual_failure_rate": 0.008561351734020232, - "error_interval": [0.004273795939256936, 0.015318623141355509] - }, { - "low": 150, - "high": 168, - "annual_failure_rate": 0.015780508262068848, - "error_interval": [0.005123888078524015, 0.03682644215646287] - }, { - "low": 168, - "high": 186, - "annual_failure_rate": 0.05262688124794024, - "error_interval": [0.0325768689524594, 0.08044577830285578] - }, { - "low": 186, - "high": 204, - "annual_failure_rate": 0.01957419424036038, - "error_interval": [0.0023705257325185624, 0.0707087198669825] - }, { - "low": 204, - "high": 222, - "annual_failure_rate": 0.026050959960031404, - "error_interval": [0.0006595532020744994, 0.1451466588889228] - }], - "display_type": "normalized" - }, - "4": { - "ideal": "", - "critical": false, - "description": "A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.01989335424860646, - "error_interval": [0.016596548909440657, 0.023653263230617408] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.03776935438256488, - "error_interval": [0.03310396052098642, 0.04290806173460437] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11022223828187004, - "error_interval": [0.09655110535164119, 0.12528657238811672] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16289995457762474, - "error_interval": [0.13926541653588131, 0.18939614504497515] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.19358212432279714, - "error_interval": [0.15864522253849073, 0.23392418181765526] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1157094940074447, - "error_interval": [0.07861898732346269, 0.16424039052527728] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12262136155304391, - "error_interval": [0.0670382394080032, 0.20573780888032978] - }, {"low": 91, "high": 104, "annual_failure_rate": 0, "error_interval": [0, 0]}], - "display_type": "raw" - }, - "5": { - "ideal": "low", - "critical": true, - "description": "Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025169175350572493, - "error_interval": [0.022768612038746357, 0.027753988579272894] - }, { - "low": 1, - "high": 4, - "annual_failure_rate": 0.027432608477803388, - "error_interval": [0.010067283827589948, 0.05970923963096652] - }, { - "low": 4, - "high": 16, - "annual_failure_rate": 0.07501976284584981, - "error_interval": [0.039944864177334186, 0.12828607921150972] - }, { - "low": 16, - "high": 70, - "annual_failure_rate": 0.23589260654405794, - "error_interval": [0.1643078435800227, 0.32806951196017664] - }, { - "low": 70, - "high": 260, - "annual_failure_rate": 0.36193219378600433, - "error_interval": [0.2608488901774093, 0.4892271827875412] - }, { - "low": 260, - "high": 1100, - "annual_failure_rate": 0.5676621428968173, - "error_interval": [0.4527895568499355, 0.702804359408436] - }, { - "low": 1100, - "high": 4500, - "annual_failure_rate": 1.5028253400346423, - "error_interval": [1.2681757596263297, 1.768305221795894] - }, { - "low": 4500, - "high": 17000, - "annual_failure_rate": 2.0659987547404763, - "error_interval": [1.6809790460512237, 2.512808045182302] - }, { - "low": 17000, - "high": 70000, - "annual_failure_rate": 1.7755385684503124, - "error_interval": [1.2796520259849835, 2.400012341226441] - }], - "display_type": "raw" - }, - "6": { - "ideal": "", - "critical": false, - "description": "Margin of a channel while reading data. The function of this attribute is not specified.", - "display_type": "normalized" - }, - "7": { - "ideal": "", - "critical": false, - "description": "(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 58, - "high": 76, - "annual_failure_rate": 0.2040131025936549, - "error_interval": [0.17032852883286412, 0.2424096283327138] - }, { - "low": 76, - "high": 94, - "annual_failure_rate": 0.08725919610118257, - "error_interval": [0.08077138510999876, 0.09412943212007528] - }, { - "low": 94, - "high": 112, - "annual_failure_rate": 0.01087335627722523, - "error_interval": [0.008732197944943352, 0.013380600544561905] - }, {"low": 112, "high": 130, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 130, - "high": 148, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, {"low": 148, "high": 166, "annual_failure_rate": 0, "error_interval": [0, 0]}, { - "low": 166, - "high": 184, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 184, - "high": 202, - "annual_failure_rate": 0.05316285755900475, - "error_interval": [0.03370069132942804, 0.07977038905848267] - }], - "display_type": "normalized" - }, - "8": { - "ideal": "high", - "critical": false, - "description": "Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.", - "display_type": "normalized" - }, - "9": { - "ideal": "", - "critical": false, - "description": "Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or wrap around (reset to zero periodically).", - "display_type": "normalized" - } - }, "success": true + "wwn": "0x50014ee20b2a72a9", + "device_name": "sdf", + "manufacturer": "ATA", + "model_name": "WDC_WD60EFRX-68MYMN1", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "WD-WXL1HXXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 6001175126016, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart_results": [] + }, + "metadata": null, + "success": true } diff --git a/webapp/frontend/src/app/data/mock/summary/data.ts b/webapp/frontend/src/app/data/mock/summary/data.ts index 7c60702..70acf16 100644 --- a/webapp/frontend/src/app/data/mock/summary/data.ts +++ b/webapp/frontend/src/app/data/mock/summary/data.ts @@ -2,812 +2,597 @@ import * as moment from 'moment'; /* tslint:disable:max-line-length */ export const summary = { - "data": [{ - "CreatedAt": "2020-08-28T07:55:27.751071002Z", - "UpdatedAt": "2020-09-08T21:39:26.571901-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "host_id": "NAS", - "interface_speed": "", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 1024209543168, - "form_factor": "", - "smart_support": false, - "device_protocol": "NVMe", - "device_type": "nvme", - "smart_results": [{ - "ID": 46, - "CreatedAt": "2020-09-08T21:39:26.572596-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572596-07:00", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T05:01:02-07:00", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 40, - "CreatedAt": "2020-09-07T15:47:21.336531606Z", - "UpdatedAt": "2020-09-07T15:47:21.336531606Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 34, - "CreatedAt": "2020-09-07T15:38:56.633173997Z", - "UpdatedAt": "2020-09-07T15:38:56.633173997Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 28, - "CreatedAt": "2020-09-07T15:26:07.504746443Z", - "UpdatedAt": "2020-09-07T15:26:07.504746443Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 22, - "CreatedAt": "2020-09-07T15:19:17.467677684Z", - "UpdatedAt": "2020-09-07T15:19:17.467677684Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 16, - "CreatedAt": "2020-09-07T15:10:40.245856096Z", - "UpdatedAt": "2020-09-07T15:10:40.245856096Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 10, - "CreatedAt": "2020-09-06T23:14:39.848993269Z", - "UpdatedAt": "2020-09-06T23:14:39.848993269Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.833116549Z", - "UpdatedAt": "2020-08-28T07:55:27.833116549Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.755292213Z", - "UpdatedAt": "2020-09-08T21:39:26.56453-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "6.0 Gb/s", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 5400, - "capacity": 14000519643136, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "sat", - "smart_results": [{ - "ID": 44, - "CreatedAt": "2020-09-08T21:39:26.565492-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565492-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 43, - "CreatedAt": "2020-09-08T21:39:26.552765-07:00", - "UpdatedAt": "2020-09-08T21:39:26.552765-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 38, - "CreatedAt": "2020-09-07T15:47:21.319490869Z", - "UpdatedAt": "2020-09-07T15:47:21.319490869Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 37, - "CreatedAt": "2020-09-07T15:47:21.305997039Z", - "UpdatedAt": "2020-09-07T15:47:21.305997039Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 32, - "CreatedAt": "2020-09-07T15:38:56.621396993Z", - "UpdatedAt": "2020-09-07T15:38:56.621396993Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 31, - "CreatedAt": "2020-09-07T15:38:56.608679081Z", - "UpdatedAt": "2020-09-07T15:38:56.608679081Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 26, - "CreatedAt": "2020-09-07T15:26:07.49254641Z", - "UpdatedAt": "2020-09-07T15:26:07.49254641Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 25, - "CreatedAt": "2020-09-07T15:26:07.478522227Z", - "UpdatedAt": "2020-09-07T15:26:07.478522227Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 20, - "CreatedAt": "2020-09-07T15:19:17.454485628Z", - "UpdatedAt": "2020-09-07T15:19:17.454485628Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 19, - "CreatedAt": "2020-09-07T15:19:17.440345175Z", - "UpdatedAt": "2020-09-07T15:19:17.440345175Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 14, - "CreatedAt": "2020-09-07T15:10:40.23412631Z", - "UpdatedAt": "2020-09-07T15:10:40.23412631Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 13, - "CreatedAt": "2020-09-07T15:10:40.221593119Z", - "UpdatedAt": "2020-09-07T15:10:40.221593119Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 8, - "CreatedAt": "2020-09-06T23:14:39.838574957Z", - "UpdatedAt": "2020-09-06T23:14:39.838574957Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 7, - "CreatedAt": "2020-09-06T23:14:39.828127845Z", - "UpdatedAt": "2020-09-06T23:14:39.828127845Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.810831029Z", - "UpdatedAt": "2020-08-28T07:55:27.810831029Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.793332347Z", - "UpdatedAt": "2020-08-28T07:55:27.793332347Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.75951336Z", - "UpdatedAt": "2020-09-08T21:39:26.568442-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "1.5 Gb/s", - "host_id": "NAS", - "serial_number": "9RK4XXXXX", - "firmware": "MS1OA650", - "rotational_speed": 7200, - "capacity": 500107862016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "usbjmicron", - "smart_results": [{ - "ID": 45, - "CreatedAt": "2020-09-08T21:39:26.569345-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569345-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T06:48:23-07:00", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 39, - "CreatedAt": "2020-09-07T15:47:21.330857794Z", - "UpdatedAt": "2020-09-07T15:47:21.330857794Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 33, - "CreatedAt": "2020-09-07T15:38:56.628048752Z", - "UpdatedAt": "2020-09-07T15:38:56.628048752Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 27, - "CreatedAt": "2020-09-07T15:26:07.499431098Z", - "UpdatedAt": "2020-09-07T15:26:07.499431098Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 21, - "CreatedAt": "2020-09-07T15:19:17.461752104Z", - "UpdatedAt": "2020-09-07T15:19:17.461752104Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 15, - "CreatedAt": "2020-09-07T15:10:40.241142961Z", - "UpdatedAt": "2020-09-07T15:10:40.241142961Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 9, - "CreatedAt": "2020-09-06T23:14:39.844036921Z", - "UpdatedAt": "2020-09-06T23:14:39.844036921Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.822428858Z", - "UpdatedAt": "2020-08-28T07:55:27.822428858Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.76380029Z", - "UpdatedAt": "2020-09-08T21:39:26.575283-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 7200, - "capacity": 4000787030016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 47, - "CreatedAt": "2020-09-08T21:39:26.576373-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576373-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T15:27:02-07:00", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 41, - "CreatedAt": "2020-09-07T15:47:21.342459019Z", - "UpdatedAt": "2020-09-07T15:47:21.342459019Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 35, - "CreatedAt": "2020-09-07T15:38:56.637866738Z", - "UpdatedAt": "2020-09-07T15:38:56.637866738Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 29, - "CreatedAt": "2020-09-07T15:26:07.511074415Z", - "UpdatedAt": "2020-09-07T15:26:07.511074415Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 23, - "CreatedAt": "2020-09-07T15:19:17.472358868Z", - "UpdatedAt": "2020-09-07T15:19:17.472358868Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 17, - "CreatedAt": "2020-09-07T15:10:40.251846539Z", - "UpdatedAt": "2020-09-07T15:10:40.251846539Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 11, - "CreatedAt": "2020-09-06T23:14:39.854284927Z", - "UpdatedAt": "2020-09-06T23:14:39.854284927Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.844861303Z", - "UpdatedAt": "2020-08-28T07:55:27.844861303Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.768220079Z", - "UpdatedAt": "2020-09-08T21:39:26.578973-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ebc248", - "device_name": "sde", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK3XXXXX", - "firmware": "", - "rotational_speed": 10500, - "capacity": 1200243695616, - "form_factor": "2.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 48, - "CreatedAt": "2020-09-08T21:39:26.579623-07:00", - "UpdatedAt": "2020-09-08T21:39:26.579623-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T15:09:15-08:00", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 42, - "CreatedAt": "2020-09-07T15:47:21.347776031Z", - "UpdatedAt": "2020-09-07T15:47:21.347776031Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 36, - "CreatedAt": "2020-09-07T15:38:56.643057784Z", - "UpdatedAt": "2020-09-07T15:38:56.643057784Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 30, - "CreatedAt": "2020-09-07T15:26:07.517198383Z", - "UpdatedAt": "2020-09-07T15:26:07.517198383Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 24, - "CreatedAt": "2020-09-07T15:19:17.478179249Z", - "UpdatedAt": "2020-09-07T15:19:17.478179249Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 18, - "CreatedAt": "2020-09-07T15:10:40.257160678Z", - "UpdatedAt": "2020-09-07T15:10:40.257160678Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 12, - "CreatedAt": "2020-09-06T23:14:39.858637958Z", - "UpdatedAt": "2020-09-06T23:14:39.858637958Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.879998203Z", - "UpdatedAt": "2020-08-28T07:55:27.879998203Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.772557223Z", - "UpdatedAt": "2020-08-28T07:55:27.772557223Z", - "DeletedAt": null, - "wwn": "0x50014ee20b2a72a9", - "device_name": "sdf", - "manufacturer": "ATA", - "model_name": "WDC_WD60EFRX-68MYMN1", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "WD-WXL1HXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 6001175126016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "smart_results": [] - }, { - "CreatedAt": "2020-08-28T07:55:27.776820757Z", - "UpdatedAt": "2020-08-28T07:55:27.776820757Z", - "DeletedAt": null, - "wwn": "0x5000c500673e6b5f", - "device_name": "sdg", - "manufacturer": "ATA", - "model_name": "ST6000DX000-1H217Z", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "Z4DXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 6001175126016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "smart_results": [] - }], "success": true -}; + "data": { + "summary": { + "0x5000c500673e6b5f": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.155217-07:00", + "UpdatedAt": "2021-04-30T08:17:13.155217-07:00", + "DeletedAt": null, + "wwn": "0x5000c500673e6b5f", + "device_name": "sdg", + "manufacturer": "ATA", + "model_name": "ST6000DX000-1H217Z", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "Z4DXXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 6001175126016, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + } + }, + "0x5000cca252c859cc": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.152705-07:00", + "UpdatedAt": "2021-05-02T14:22:50.357164-07:00", + "DeletedAt": null, + "wwn": "0x5000cca252c859cc", + "device_name": "sdd", + "manufacturer": "ATA", + "model_name": "WDC_WD80EFAX-68LHPN0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "7SGLXXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 8001563222016, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart": { + "collector_date": "2020-08-21T22:27:02Z", + "temp": 34, + "power_on_hours": 43549 + }, + "temp_history": [{ + "date": "2020-08-21T22:27:02Z", + "temp": 34 + }] + }, + "0x5000cca264eb01d7": { + "device": { + "CreatedAt": "2021-04-28T20:52:49.047154-07:00", + "UpdatedAt": "2021-05-02T14:22:49.86136-07:00", + "DeletedAt": null, + "wwn": "0x5000cca264eb01d7", + "device_name": "sdb", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK1XXXXX", + "firmware": "81.00A81", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart": { + "collector_date": "2020-06-21T00:03:30Z", + "temp": 32, + "power_on_hours": 1730 + }, + "temp_history": [{ + "date": "2020-06-21T00:03:30Z", + "temp": 32 + }] + }, + "0x5000cca264ebc248": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.153782-07:00", + "UpdatedAt": "2021-05-02T14:22:50.385282-07:00", + "DeletedAt": null, + "wwn": "0x5000cca264ebc248", + "device_name": "sde", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK3XXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + } + }, + "0x5000cca264ec3183": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.151906-07:00", + "UpdatedAt": "2021-05-02T14:49:51.645012-07:00", + "DeletedAt": null, + "wwn": "0x5000cca264ec3183", + "device_name": "sdc", + "manufacturer": "ATA", + "model_name": "WDC_WD140EDFZ-11A0VA0", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "9RK4XXXXX", + "firmware": "RVT02B6Q", + "rotational_speed": 0, + "capacity": 14000519643136, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 1 + }, + "smart": { + "collector_date": "2020-09-13T16:29:23Z", + "temp": 36, + "power_on_hours": 14551 + }, + "temp_history": [{ + "date": "2020-07-08T13:48:23Z", + "temp": 25 + }, { + "date": "2020-09-12T19:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T19:29:23Z", + "temp": 37 + }, { + "date": "2020-09-12T19:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T19:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T19:59:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:09:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:29:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T20:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T20:59:23Z", + "temp": 37 + }, { + "date": "2020-09-12T21:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T21:29:23Z", + "temp": 38 + }, { + "date": "2020-09-12T21:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:59:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:19:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:29:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:59:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:19:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:29:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:59:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:09:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:19:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:29:23Z", + "temp": 37 + }, { + "date": "2020-09-13T00:39:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:49:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:59:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:09:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:19:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:29:23Z", + "temp": 37 + }, { + "date": "2020-09-13T01:39:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:49:23Z", + "temp": 37 + }, { + "date": "2020-09-13T01:59:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:09:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:19:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T02:39:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:49:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T05:09:23Z", + "temp": 37 + }, { + "date": "2020-09-13T05:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T05:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T05:39:23Z", + "temp": 41 + }, { + "date": "2020-09-13T05:49:23Z", + "temp": 42 + }, { + "date": "2020-09-13T05:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:09:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:19:23Z", + "temp": 42 + }, { + "date": "2020-09-13T06:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:39:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:49:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T07:09:23Z", + "temp": 40 + }, { + "date": "2020-09-13T07:19:23Z", + "temp": 40 + }, { + "date": "2020-09-13T07:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T07:39:23Z", + "temp": 43 + }, { + "date": "2020-09-13T07:49:23Z", + "temp": 42 + }, { + "date": "2020-09-13T07:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T08:09:23Z", + "temp": 42 + }, { + "date": "2020-09-13T08:19:23Z", + "temp": 42 + }, { + "date": "2020-09-13T08:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T08:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T08:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T08:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T09:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T09:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T11:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:19:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:29:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:39:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T16:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T16:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T16:29:23Z", + "temp": 39 + }] + }, + "0x50014ee20b2a72a9": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.15451-07:00", + "UpdatedAt": "2021-04-30T08:17:13.15451-07:00", + "DeletedAt": null, + "wwn": "0x50014ee20b2a72a9", + "device_name": "sdf", + "manufacturer": "ATA", + "model_name": "WDC_WD60EFRX-68MYMN1", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "WD-WXL1HXXXXX", + "firmware": "", + "rotational_speed": 0, + "capacity": 6001175126016, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + } + }, + "0x5002538e40a22954": { + "device": { + "CreatedAt": "2021-04-30T08:17:13.150792-07:00", + "UpdatedAt": "2021-05-02T14:22:50.330706-07:00", + "DeletedAt": null, + "wwn": "0x5002538e40a22954", + "device_name": "sda", + "manufacturer": "ATA", + "model_name": "Samsung_SSD_860_EVO_500GB", + "interface_type": "SCSI", + "interface_speed": "", + "serial_number": "S3YZNB0KBXXXXXX", + "firmware": "002C", + "rotational_speed": 0, + "capacity": 500107862016, + "form_factor": "", + "smart_support": false, + "device_protocol": "", + "device_type": "", + "label": "", + "host_id": "", + "device_status": 0 + }, + "smart": { + "collector_date": "2020-06-10T12:01:02Z", + "temp": 36, + "power_on_hours": 2401 + }, + "temp_history": [{ + "date": "2020-06-10T12:01:02Z", + "temp": 36 + }] + } + } + }, + "success": true +} diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.component.html b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html index 82a723f..8e321c4 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.component.html +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html @@ -1,4 +1,5 @@ -
+ +
@@ -47,38 +48,36 @@
- -
-
+
-
-
/dev/{{data.data.device_name}}
+
/dev/{{device?.device_name}}
-
-
{{data.data.host_id}}
+
+
+ + + {{device?.device_status == 0 ? 'passed' : 'failed'}} + +
+
Status
+
+ +
+
{{device?.host_id}}
Host ID
-
-
{{data.data.device_type | uppercase}}
+
+
{{device?.device_type | uppercase}}
Device Type
-
-
{{data.data.manufacturer}}
+
+
{{device?.manufacturer}}
Model Family
-
{{data.data.model_name}}
+
{{device?.model_name}}
Device Model
-
{{data.data.serial_number}}
+
{{device?.serial_number}}
Serial Number
-
{{data.data.wwn}}
+
{{device?.wwn}}
LU WWN Device Id
-
{{data.data.firmware}}
+
{{device?.firmware}}
Firmware Version
-
{{data.data.capacity | fileSize}}
+
{{device?.capacity | fileSize}}
Capacity
-
-
{{data.data.rotational_speed}} RPM
+
+
{{device?.rotational_speed}} RPM
Rotation Rate
-
-
{{data.data.device_protocol}}
+
+
{{device?.device_protocol}}
Protocol
-
{{data.data.smart_results[0]?.power_cycle_count}}
+
{{smart_results[0]?.power_cycle_count}}
Power Cycle Count
-
-
{{humanizeDuration(data.data.smart_results[0]?.power_on_hours *60 * 60 * 1000, { round: true, largest: 1, units: ['y', 'd', 'h'] })}}
+
+
{{humanizeDuration(smart_results[0]?.power_on_hours *60 * 60 * 1000, { round: true, largest: 1, units: ['y', 'd', 'h'] })}}
Powered On
-
{{data.data.smart_results[0]?.temp}}°C
+
{{smart_results[0]?.temp}}°C
Temperature
@@ -115,7 +129,7 @@
-
S.M.A.R.T {{data.data.device_protocol}} Attributes
+
S.M.A.R.T {{device?.device_protocol}} Attributes
{{this.smartAttributeDataSource.data.length}} visible, {{getHiddenAttributes()}} hidden
@@ -139,15 +153,15 @@ - {{attribute.status}} + [ngClass]="{'bg-red': getAttributeStatusName(attribute.status) === 'failed', + 'bg-green': getAttributeStatusName(attribute.status) === 'passed', + 'bg-yellow': getAttributeStatusName(attribute.status) === 'warn'}"> + {{getAttributeStatusName(attribute.status)}} @@ -183,7 +197,7 @@ - {{attribute.name}} + {{getAttributeName(attribute)}} diff --git a/webapp/frontend/src/app/modules/detail/detail.component.ts b/webapp/frontend/src/app/modules/detail/detail.component.ts index a4321ec..6f03bb5 100644 --- a/webapp/frontend/src/app/modules/detail/detail.component.ts +++ b/webapp/frontend/src/app/modules/detail/detail.component.ts @@ -19,7 +19,12 @@ import humanizeDuration from 'humanize-duration'; export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { onlyCritical: boolean = true; - data: any; + // data: any; + + metadata: any; + device: any; + smart_results: any[]; + commonSparklineOptions: Partial; smartAttributeDataSource: MatTableDataSource; smartAttributeTableColumns: string[]; @@ -66,10 +71,14 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { .subscribe((data) => { // Store the data - this.data = data; + // this.data = data; + this.device = data.data.device; + this.smart_results = data.data.smart_results + this.metadata = data.metadata; + // Store the table data - this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(data.data.smart_results); + this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.smart_results); // Prepare the chart data this._prepareChartData(); @@ -98,8 +107,28 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // ----------------------------------------------------------------------------------------------------- // @ Private methods // ----------------------------------------------------------------------------------------------------- + getAttributeStatusName(attribute_status){ + if(attribute_status == 0){ + return "passed" + } else if (attribute_status == 1){ + return "warn" + } else if (attribute_status == 2){ + return "failed" + } + return + } + + getAttributeName(attribute_data){ + let attribute_metadata = this.metadata[attribute_data.attribute_id] + if(!attribute_metadata){ + return 'Unknown Attribute Name' + } else { + return attribute_metadata.display_name + } + return + } getAttributeDescription(attribute_data){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return 'Unknown' } else { @@ -110,7 +139,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValue(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.value } else if (attribute_metadata.display_type == "raw") { @@ -128,7 +157,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValueType(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return '' } else { @@ -141,14 +170,14 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeIdeal(attribute_data){ if(this.isAta()){ - return this.data.metadata[attribute_data.attribute_id]?.display_type == "raw" ? this.data.metadata[attribute_data.attribute_id]?.ideal : '' + return this.metadata[attribute_data.attribute_id]?.display_type == "raw" ? this.metadata[attribute_data.attribute_id]?.ideal : '' } else { - return this.data.metadata[attribute_data.attribute_id]?.ideal + return this.metadata[attribute_data.attribute_id]?.ideal } } getAttributeWorst(attribute_data){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.worst } else { @@ -158,7 +187,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeThreshold(attribute_data){ if(this.isAta()){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata || attribute_metadata.display_type == "normalized"){ return attribute_data.thresh } else { @@ -175,29 +204,30 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } getAttributeCritical(attribute_data){ - return this.data.metadata[attribute_data.attribute_id]?.critical + return this.metadata[attribute_data.attribute_id]?.critical } getHiddenAttributes(){ - let attributes_list - if(this.isAta()){ - attributes_list = this.data.data.smart_results[0]?.ata_attributes - } else if(this.isNvme()){ - attributes_list = this.data.data.smart_results[0]?.nvme_attributes - } else { - attributes_list = this.data.data.smart_results[0]?.scsi_attributes + if (!this.smart_results || this.smart_results.length == 0) { + return 0 + } + + let attributes_length = 0 + let attributes = this.smart_results[0]?.attrs + if (attributes) { + attributes_length = Object.keys(attributes).length } - return attributes_list.length - this.smartAttributeDataSource.data.length + return attributes_length - this.smartAttributeDataSource.data.length } isAta(): boolean { - return this.data.data.device_protocol == 'ATA' + return this.device.device_protocol == 'ATA' } isScsi(): boolean { - return this.data.data.device_protocol == 'SCSI' + return this.device.device_protocol == 'SCSI' } isNvme(): boolean { - return this.data.data.device_protocol == 'NVMe' + return this.device.device_protocol == 'NVMe' } private _generateSmartAttributeTableDataSource(smart_results){ @@ -207,35 +237,44 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { return smartAttributeDataSource } var latest_smart_result = smart_results[0]; - let attributes_list = [] + let attributes = {} if(this.isScsi()) { this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'history']; - attributes_list = latest_smart_result.scsi_attributes + attributes = latest_smart_result.attrs } else if(this.isNvme()){ this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'ideal', 'history']; - attributes_list = latest_smart_result.nvme_attributes + attributes = latest_smart_result.attrs } else { //ATA - attributes_list = latest_smart_result.ata_attributes + attributes = latest_smart_result.attrs this.smartAttributeTableColumns = ['status', 'id', 'name', 'value', 'worst', 'thresh','ideal', 'failure', 'history']; } + for(const attrId in attributes){ + var attr = attributes[attrId] - for(let attr of attributes_list){ //chart history data if (!attr.chartData) { - var rawHistory = (attr.history || []).map(hist_attr => this.getAttributeValue(hist_attr)).reverse() - rawHistory.push(this.getAttributeValue(attr)) - attr.chartData = [ + + + var attrHistory = [] + for (let smart_result of smart_results){ + attrHistory.push(this.getAttributeValue(smart_result.attrs[attrId])) + } + + // var rawHistory = (attr.history || []).map(hist_attr => this.getAttributeValue(hist_attr)).reverse() + // rawHistory.push(this.getAttributeValue(attr)) + + attributes[attrId].chartData = [ { name: "chart-line-sparkline", - data: rawHistory + data: attrHistory } ] } //determine when to include the attributes in table. - if(!this.onlyCritical || this.onlyCritical && this.data.metadata[attr.attribute_id]?.critical || attr.value < attr.thresh){ + if(!this.onlyCritical || this.onlyCritical && this.metadata[attr.attribute_id]?.critical || attr.value < attr.thresh){ smartAttributeDataSource.push(attr) } } @@ -297,7 +336,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } toggleOnlyCritical(){ this.onlyCritical = !this.onlyCritical - this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.data.data.smart_results); + this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.smart_results); }