commit f268de21a3018cbc0a89db8fcb79dcd9e5db1f88 Author: Mihajlo Medjedovic Date: Thu Jul 13 13:44:05 2023 +0200 init diff --git a/.git-hooks/commit-msg b/.git-hooks/commit-msg new file mode 100755 index 0000000..d12ec2f --- /dev/null +++ b/.git-hooks/commit-msg @@ -0,0 +1,18 @@ +#!/bin/sh +RED="\033[1;31m" +GREEN="\033[1;32m" + +# Get the commit message (the parameter we're given is just the path to the +# temporary file which holds the message). +commit_message=$(cat "$1") + +if (echo "$commit_message" | grep -Eq "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z0-9 \-]+\))?!?: .+$") then + echo "${GREEN} ✔ Commit message meets Conventional Commit standards" + exit 0 +fi + +echo "${RED}❌ Commit message does not meet the Conventional Commit standard!" +echo "An example of a valid message is:" +echo " feat(login): add the 'remember me' button" +echo "ℹ More details at: https://www.conventionalcommits.org/en/v1.0.0/#summary" +exit 1 \ No newline at end of file diff --git a/.git-hooks/pre-commit b/.git-hooks/pre-commit new file mode 100755 index 0000000..f617074 --- /dev/null +++ b/.git-hooks/pre-commit @@ -0,0 +1,11 @@ +#!/bin/sh + +# Avoid commits to the master branch +BRANCH=`git rev-parse --abbrev-ref HEAD` +REGEX="^(master|development)$" + +if [[ "$BRANCH" =~ $REGEX ]]; then + echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?" + echo "If so, commit with -n to bypass the pre-commit hook." + exit 1 +fi diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..b41796b --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,38 @@ +name: Build +run-name: Building and testing DC +on: [pull_request] + +jobs: + Build-and-ng-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Write .npmrc file + run: echo "$NPMRC" > client/.npmrc + shell: bash + env: + NPMRC: ${{ secrets.NPMRC}} + + - run: apt-get update + - run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - run: apt install -y ./google-chrome*.deb; + - run: export CHROME_BIN=/usr/bin/google-chrome + - run: npm run lint:check + # Install dependencies~ + - run: npm ci --legacy-peer-deps + # Audit should fail and stop the CI if critical vulnerability found + - run: npm audit --audit-level=critical + - run: | + cd ./sas + npm audit --audit-level=critical + - run: | + cd ./client + npm audit --audit-level=critical + npm test -- --no-watch --no-progress --browsers=ChromeHeadlessCI + npm run postinstall + npm run build \ No newline at end of file diff --git a/.gitea/workflows/development-test.yaml b/.gitea/workflows/development-test.yaml new file mode 100644 index 0000000..9c41b17 --- /dev/null +++ b/.gitea/workflows/development-test.yaml @@ -0,0 +1,172 @@ +name: Test +run-name: Building and testing development branch +on: + push: + branches: + - development + +jobs: + Build-and-test-development: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Write .npmrc file + run: echo "$NPMRC" > client/.npmrc + shell: bash + env: + NPMRC: ${{ secrets.NPMRC}} + + - run: apt-get update + - run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - run: apt install -y ./google-chrome*.deb; + - run: export CHROME_BIN=/usr/bin/google-chrome + - run: apt-get update -y + - run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb + - run: apt -y install jq + # - run: 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + # - run: eval $(ssh-agent -s) + # - run: echo "$ssh_key" | tr -d '\r' | ssh-add - + - name: Write cypress credentials + run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json + shell: bash + env: + CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }} + + # - run: mkdir -p ~/.ssh + # - run: chmod 700 ~/.ssh + - run: npm ci --legacy-peer-deps + # Install pm2 and prepare SASJS server + - run: npm i -g pm2 + - run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip + - run: unzip linux.zip + - run: touch .env + - run: echo RUN_TIMES=js >> .env + - run: echo NODE_PATH=node >> .env + - run: echo CORS=enable >> .env + - run: echo WHITELIST=http://localhost:4200 >> .env + # - run: echo "SERVER_URL=$server_url" >> .env + # - run: echo "SERVER_TYPE=$server_type" >> .env + # - run: echo "CLIENT=$client_sasjs" >> .env + # - run: echo "ACCESS_TOKEN=$access_token_sasjs" >> .env + # - run: echo "REFRESH_TOKEN=$refresh_token_sasjs" >> .env + # - run: cat .env + - run: pm2 start api-linux --wait-ready + + - name: Deploy mocked services + run: | + cd ./sas/mocks/sasjs + npm install --legacy-peer-deps -g @sasjs/cli + npm install --legacy-peer-deps -g replace-in-files-cli + sasjs cbd -t server-ci + # sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json + + - name: Prepare frontend + run: | + cd ./client + # mv ./cypress.env.example.json ./cypress.env.json + # replace-in-files --regex='"username".*' --replacement='"username":"'$cypress_username_sasjs'",' ./cypress.env.json + # replace-in-files --regex='"password".*' --replacement='"password":"'$cypress_pwd_sasjs'" ' ./cypress.env.json + cat ./cypress.env.json + npm run postinstall + # Prepare index.html to SASJS local + replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html + replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html + replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html + # Prepare and deploy SASJS version + # replace-in-files --regex='serverurl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./dist/index.html + # replace-in-files --regex='apploc=".*?"' --replacement='appLoc="/30.SASApps/app/devtest"' ./dist/index.html + # replace-in-files --regex='servertype=".*?"' --replacement='serverType="SASJS"' ./dist/index.html + # scp -o stricthostkeychecking=no -r ./dist/* dcgitlab@sas.4gl.io:/var/www/html/dcviya/development/newadapter + replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts + # replace-in-files --regex='"appLocation".*' --replacement='appLocation:"/dcviya/development/newadapter",' ./cypress.config.ts + cat ./cypress.config.ts + # Start frontend and run cypress + npm start & npx wait-on http://localhost:4200 && ./run-cypress-tests.sh + + Build-and-test-development-latest-adapter: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Write .npmrc file + run: echo "$NPMRC" > client/.npmrc + shell: bash + env: + NPMRC: ${{ secrets.NPMRC}} + + - run: apt-get update + - run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - run: apt install -y ./google-chrome*.deb; + - run: export CHROME_BIN=/usr/bin/google-chrome + - run: apt-get update -y + - run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb + - run: apt -y install jq + # - run: 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + # - run: eval $(ssh-agent -s) + # - run: echo "$ssh_key" | tr -d '\r' | ssh-add - + - name: Write cypress credentials + run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json + shell: bash + env: + CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }} + + # - run: mkdir -p ~/.ssh + # - run: chmod 700 ~/.ssh + - run: npm ci --legacy-peer-deps + # Install pm2 and prepare SASJS server + - run: npm i -g pm2 + - run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip + - run: unzip linux.zip + - run: touch .env + - run: echo RUN_TIMES=js >> .env + - run: echo NODE_PATH=node >> .env + - run: echo CORS=enable >> .env + - run: echo WHITELIST=http://localhost:4200 >> .env + # - run: echo "SERVER_URL=$server_url" >> .env + # - run: echo "SERVER_TYPE=$server_type" >> .env + # - run: echo "CLIENT=$client_sasjs" >> .env + # - run: echo "ACCESS_TOKEN=$access_token_sasjs" >> .env + # - run: echo "REFRESH_TOKEN=$refresh_token_sasjs" >> .env + # - run: cat .env + - run: pm2 start api-linux --wait-ready + + - name: Deploy mocked services + run: | + cd ./sas/mocks/sasjs + npm install --legacy-peer-deps -g @sasjs/cli + npm install --legacy-peer-deps -g replace-in-files-cli + sasjs cbd -t server-ci + # sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json + + - name: Prepare frontend + run: | + cd ./client + # mv ./cypress.env.example.json ./cypress.env.json + # replace-in-files --regex='"username".*' --replacement='"username":"'$cypress_username_sasjs'",' ./cypress.env.json + # replace-in-files --regex='"password".*' --replacement='"password":"'$cypress_pwd_sasjs'" ' ./cypress.env.json + cat ./cypress.env.json + npm run postinstall + npm install --legacy-peer-deps @sasjs/adapter@latest + # Prepare index.html to SASJS local + replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html + replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html + replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html + # Prepare and deploy SASJS version + # replace-in-files --regex='serverurl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./dist/index.html + # replace-in-files --regex='apploc=".*?"' --replacement='appLoc="/30.SASApps/app/devtest"' ./dist/index.html + # replace-in-files --regex='servertype=".*?"' --replacement='serverType="SASJS"' ./dist/index.html + # scp -o stricthostkeychecking=no -r ./dist/* dcgitlab@sas.4gl.io:/var/www/html/dcviya/development/newadapter + replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts + # replace-in-files --regex='"appLocation".*' --replacement='appLocation:"/dcviya/development/newadapter",' ./cypress.config.ts + cat ./cypress.config.ts + # Start frontend and run cypress + npm start & npx wait-on http://localhost:4200 && ./run-cypress-tests.sh \ No newline at end of file diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..23bc211 --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,50 @@ +name: Release +run-name: Releasing DC +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Write .npmrc file + run: | + echo "$NPMRC" > client/.npmrc + echo "legacy-peer-deps=true" >> client/.npmrc + shell: bash + env: + NPMRC: ${{ secrets.NPMRC}} + + - name: Install ZIP + run: | + apt-get update + apt-get install zip + + - name: release-build + run: | + cd client + npm ci + npm run build + zip -r dist.zip ./dist + + - name: Install Semantic Release and plugins + run: | + npm i + npm i -g semantic-release + + - name: Release + run: | + GITEA_TOKEN=${{ secrets.RELEASE_TOKEN }} GITEA_URL=https://git.datacontroller.io semantic-release + + - name: Release Typedoc + run: | + cd client + npm run typedoc + # deploy docs \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603ea0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +coverage/ +dist/ +node_modules/ +client/.angular/cache/ +**/*npm-debug.log.* +**/*yarn-error.log.* +.idea/ +.DS_Store +client/src/environments/version.ts +client/cypress/screenshots +client/cypress/results +client/cypress/videos +cypress.env.json +sasjsbuild +sasjsresults +.env* +.sasjsrc +client/.npmrc +*~ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..51df798 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=false diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..7f43c70 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ + +{ + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "endOfLine": "auto" +} \ No newline at end of file diff --git a/.releaserc b/.releaserc new file mode 100644 index 0000000..53177bd --- /dev/null +++ b/.releaserc @@ -0,0 +1,22 @@ +{ + "branches": ["main"], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/changelog", + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md" + ] + } + ], + ["@saithodev/semantic-release-gitea", { + "giteaUrl": "https://git.datacontroller.io", + "assets": [ + {"path": "client/dist.zip"} + ] + }] + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d8e7655 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "cSpell.words": [ + "SYSERRORTEXT", + "SYSWARNINGTEXT" + ], + "editor.rulers": [ + 80 + ], + "files.trimTrailingWhitespace": true, + "[markdown]": { + "files.trimTrailingWhitespace": false + }, + "workbench.colorCustomizations": { + "titleBar.activeForeground": "#ebe8e8", + "titleBar.activeBackground": "#95ff0053", + }, + "terminal.integrated.wordSeparators": " ()[]{}',\"`─‘’" +} \ No newline at end of file diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..de5aeef --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,9 @@ +pipeline: + build: + image: debian + commands: + - echo "This is the build step" + a-test-step: + image: debian + commands: + - echo "Testing.." \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c49fad8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1965 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. + +## [6.0.0](https://gitlab.com/macropeople/datacontroller/compare/v5.3.0...v6.0.0) (2023-06-27) + + +### ⚠ BREAKING CHANGES + +* The updated model and behaviour of FORMATS is the breaking change in this release! (but not this commit) + +* removed gitpod.yml and moved CONTRIBUTING.md to root directory ([eb3e1be](https://gitlab.com/macropeople/datacontroller/commit/eb3e1be2e4697a90faa01155c53f2e664c63c3c6)) + + +### Features + +* adding isadmin to startupservice. Relates to [#460](https://gitlab.com/macropeople/datacontroller/issues/460) ([70a755c](https://gitlab.com/macropeople/datacontroller/commit/70a755ccace68d0d2eb4baf25f091300e7f49b75)) +* admin page ([642b7d0](https://gitlab.com/macropeople/datacontroller/commit/642b7d042a34fc83f7871fd84e254490cea81232)) +* angular 16 ([9805c09](https://gitlab.com/macropeople/datacontroller/commit/9805c094290f9d8f7012bb0316ef924865e6ac29)) +* autocomplete load more ([f3df479](https://gitlab.com/macropeople/datacontroller/commit/f3df4790c8160c2f51c643419a24992e4171e5b7)) +* autocomplete load more ([3160be4](https://gitlab.com/macropeople/datacontroller/commit/3160be4fe1f3f4196cf0fa418dee75acfe6a64f3)) +* custom dropdown load more ([0a576fd](https://gitlab.com/macropeople/datacontroller/commit/0a576fddb9525ca41db4a31b7ad4aec6db420ca4)) +* handsontable 12.4.0 ([17d1c23](https://gitlab.com/macropeople/datacontroller/commit/17d1c231b45e667442236f5475cb5d68a67ce7d3)) +* history paging (load more) ([d4381da](https://gitlab.com/macropeople/datacontroller/commit/d4381da4776814419133b11b4c99f57faca62172)) +* licence in a file ([2cc59ff](https://gitlab.com/macropeople/datacontroller/commit/2cc59ff1b392985b342b8491147bea1bf895d7e2)) +* licensing refactor - free tier version ([a418cd6](https://gitlab.com/macropeople/datacontroller/commit/a418cd6085c16d62a2be7fc7f9a9943f9452f3a9)) +* new licence service with encoded features ([fa8722f](https://gitlab.com/macropeople/datacontroller/commit/fa8722f4c5ba8e7334d478560a82d24d5cb7f79e)) +* showing PK in VIEW menu for format catalogs ([fc64832](https://gitlab.com/macropeople/datacontroller/commit/fc6483229a63afbe2f3044e242079798110aef41)) +* support for INFORMATS - also multilabel and notsorted formats ([34af333](https://gitlab.com/macropeople/datacontroller/commit/34af333e414ad965d94b875065fa2d6a7492ed8e)) +* viya api explorer ([4c69487](https://gitlab.com/macropeople/datacontroller/commit/4c69487552612a35e010d5c8de34337b5f43c8ee)) + + +### Bug Fixes + +* adapter bump ([72843c2](https://gitlab.com/macropeople/datacontroller/commit/72843c27ed6638f5fca84c0f8d1b865121655876)) +* adapter bump ([30da29f](https://gitlab.com/macropeople/datacontroller/commit/30da29ffa7a57f723d85ed653de41e158a9743d1)) +* added component to add link to support email ([234a43d](https://gitlab.com/macropeople/datacontroller/commit/234a43dc3537506096fbb16b225c755e9581fd9c)) +* added copy without headers ([32d5a4f](https://gitlab.com/macropeople/datacontroller/commit/32d5a4f6ec293b610e917c10c9719bb6a0334d1b)) +* adding lock check on mpe_audit before dataload ([6ad5d61](https://gitlab.com/macropeople/datacontroller/commit/6ad5d615dfa0ad23f0eda2c986f0d600fb1bc3aa)) +* adding nobs to gethistory ([2c15abb](https://gitlab.com/macropeople/datacontroller/commit/2c15abb22a2fcd31aefb20b15a200a271a42ef2b)) +* angular bump 15.2.9 ([c7e21b9](https://gitlab.com/macropeople/datacontroller/commit/c7e21b97daaec85337459f43856eb8f8a446cd13)) +* angular-eslint bump 15.2.1 ([305de83](https://gitlab.com/macropeople/datacontroller/commit/305de8368bd98486b280208ea95fe3538a1f792b)) +* **approve:** bumping core to prevent unlocks when tables are not locked (issue [#339](https://gitlab.com/macropeople/datacontroller/issues/339) in core library) ([afc0517](https://gitlab.com/macropeople/datacontroller/commit/afc0517a7a152be46072d740e0c893d30b7bfa09)) +* **approve:** When uploading ONLY deletes, ensure that records are added to the mpe_audit table ([2d404c0](https://gitlab.com/macropeople/datacontroller/commit/2d404c0992cc8c611bede64aa71b5d378a5e3032)) +* backend for getcolvals extra rows ([4f50654](https://gitlab.com/macropeople/datacontroller/commit/4f50654c17018103b1b30ea08ae7b01c5afca419)) +* bitemporal load support in audit table ([a63f7de](https://gitlab.com/macropeople/datacontroller/commit/a63f7de32eeb8a67296713271df40c83125b61f8)) +* bump typescript 4.9.5 ([b0e0dfa](https://gitlab.com/macropeople/datacontroller/commit/b0e0dfac6430b476f69966695075cc77cbcf5ea8)) +* d3 graphviz updated to fix vulnerabilities ([28b27ce](https://gitlab.com/macropeople/datacontroller/commit/28b27ce2aca7d2319ba8bc1c4bd4f42e0a976f90)) +* default hot licence, editor rows limit notice on the bottom, showed only when more then limit submitted ([0db976a](https://gitlab.com/macropeople/datacontroller/commit/0db976a5b7c9f167d103461fb65297eb091e2b87)) +* display special missings in VIEW mode ([8d1bfb5](https://gitlab.com/macropeople/datacontroller/commit/8d1bfb5a5d336f094aaa955a87c23bd6986d72f1)) +* enabling configurable history at backend in approvers/gethistory. Addresses [#257](https://gitlab.com/macropeople/datacontroller/issues/257) and ([055a7ff](https://gitlab.com/macropeople/datacontroller/commit/055a7ff5615dc1a074b7aa327cfedb99cd35e572)), closes [#477](https://gitlab.com/macropeople/datacontroller/issues/477) +* enabling refresh of single library when invalid libraries are present ([9545ac7](https://gitlab.com/macropeople/datacontroller/commit/9545ac7a6b44d31a3d5a45bb9dd2168b39a97997)) +* filter on download in history removed, rows and cols number on viewer and editor ([bab3dfa](https://gitlab.com/macropeople/datacontroller/commit/bab3dfa908422708e31b4441f90133873b23be52)) +* firefox dropdown not sticking, load more is note present if nothing to load ([9c78d67](https://gitlab.com/macropeople/datacontroller/commit/9c78d678ef10809392ccc83bfbf1353701b059e2)) +* index html inline style, sas9 metadata type ([8226413](https://gitlab.com/macropeople/datacontroller/commit/8226413c734dfc1f6ce453647f2fb3dc349cda5e)) +* inserting row above/below was scrolling to the bottom ([c30e361](https://gitlab.com/macropeople/datacontroller/commit/c30e36160c4ab42b45a8ec4c13a6f58ff7d3b90f)) +* licence expiration blocks the app (it is now reverted to free tier version) ([389a05b](https://gitlab.com/macropeople/datacontroller/commit/389a05b52ad93d36395b8061f51d07166efa347a)) +* licence expired blocking app (in progress) ([4601683](https://gitlab.com/macropeople/datacontroller/commit/4601683eab34feb5e5701b1efc90e1f678071bdf)) +* licence expired error, added expiry date ([2c20c8d](https://gitlab.com/macropeople/datacontroller/commit/2c20c8dfe0b0ea37f59fcf73e7f803e5023bba87)) +* load more in history to appear only when paging available ([8851ba7](https://gitlab.com/macropeople/datacontroller/commit/8851ba7ded6f2eefbc3598d048729f4b80e6f878)) +* making HIST configurable with MPE_CONFIG ([215fa87](https://gitlab.com/macropeople/datacontroller/commit/215fa87bfd0ee39c4ce499a4bffe3d4e8aa05035)) +* missing licence should not show error ([5a653ae](https://gitlab.com/macropeople/datacontroller/commit/5a653aef288d48f444924255a6328f7172c8fc58)) +* new cypress config, added cypress reporter in results after test run ([8ea3ab8](https://gitlab.com/macropeople/datacontroller/commit/8ea3ab8b89344a2c148e9a97c991c7ccbc678a15)) +* removed ngx-markdown ([cda97fc](https://gitlab.com/macropeople/datacontroller/commit/cda97fcaf7d727cf41093aa272087e21c266a4aa)) +* removed ngx-markdown, added `marked` package, used raw ([43cd643](https://gitlab.com/macropeople/datacontroller/commit/43cd643f6aec475e53f0c798d064a57035f11fa9)) +* submit table request error handling ([b8395be](https://gitlab.com/macropeople/datacontroller/commit/b8395be93382e7187cfb1a1909231ea3f89032c6)) +* submitted page linking ([c18519e](https://gitlab.com/macropeople/datacontroller/commit/c18519e287ffa9eb62d43b7bd414cb1c41b2471a)) +* submitted_dttm type fix and distinct for non admin gethistory ([ef3fa67](https://gitlab.com/macropeople/datacontroller/commit/ef3fa67b950cd626f955bfd79bbfec4a4f1b9bd3)) +* supporting additional date formats. Closes [#484](https://gitlab.com/macropeople/datacontroller/issues/484) ([38d8e10](https://gitlab.com/macropeople/datacontroller/commit/38d8e10dc299be4c7939603b1a7e84d573bde3bf)) +* typo in DDL for MPE_SUBMIT ([f6ca05d](https://gitlab.com/macropeople/datacontroller/commit/f6ca05d733ed05167f15858eaf1e6cfee5aea182)) +* unlocking audit table ([2a6884d](https://gitlab.com/macropeople/datacontroller/commit/2a6884dffcffce22607f7d221e7743135bf32f6e)) +* upcase issue ([ccd9c4e](https://gitlab.com/macropeople/datacontroller/commit/ccd9c4eaf3f45306199dc831cb691401bf5077e8)) +* update to angular v15 ([90a143f](https://gitlab.com/macropeople/datacontroller/commit/90a143fd1ab2b60fe7f48a0c1c582d2727c17757)) +* updated [@angular-eslint](https://gitlab.com/angular-eslint) ([080b281](https://gitlab.com/macropeople/datacontroller/commit/080b281df048b6577ac32577b19c46d74fe92ea6)) +* users allowed with demo key ([6a0fce8](https://gitlab.com/macropeople/datacontroller/commit/6a0fce880e7d3d30b37133bcb1c8e42dee3467fb)) +* viewer rows limit notice position ([5ac227b](https://gitlab.com/macropeople/datacontroller/commit/5ac227b950b0ee4a88d243c0df24d3e5f5e2a6a6)) +* viya profile picture url was broken when client at different domain ([a42cfc0](https://gitlab.com/macropeople/datacontroller/commit/a42cfc077a4a5922e019086ca41365d4779e7205)) + +## [5.3.0](https://github.com/datacontroller/datacontroller/compare/v5.2.0...v5.3.0) (2023-02-23) + + +### Features + +* added file drop and file select directives ([3d29908](https://github.com/datacontroller/datacontroller/commit/3d299087971eea6b0e52886e3b0980bedcb209ca)) +* column ordering stored to URL ([63f7354](https://github.com/datacontroller/datacontroller/commit/63f7354976ca6c5966dadae659065f98524609ba)) +* config in sasjs html tag ([4c0f6ed](https://github.com/datacontroller/datacontroller/commit/4c0f6ed91df48a4bb733f3a6343b95b387499487)) +* editor - viewboxes added ([860a7e9](https://github.com/datacontroller/datacontroller/commit/860a7e9659cd28326a2a0eba3d908ff0fde880a9)) +* **viewboxes:** edit table in new tab ([8321263](https://github.com/datacontroller/datacontroller/commit/8321263b3c3076f317aff5b0228ca8423cc5b89b)) +* **viewboxes:** full table search table ([e86b53a](https://github.com/datacontroller/datacontroller/commit/e86b53a2855bd18eaf91fad0ae8ce84ac4ea360e)) +* **viewboxes:** integration with viewer, modularization ([507f4ae](https://github.com/datacontroller/datacontroller/commit/507f4aef1cab4e6bab9ed310458b8e0fb4f75a8a)) +* **viewboxes:** snap to grid ([940634a](https://github.com/datacontroller/datacontroller/commit/940634a560de8caa08222d9d4f95e3bba8da7d1b)) +* **viewboxes:** table filtering (in progress) ([2029a85](https://github.com/datacontroller/datacontroller/commit/2029a85d6cb3a0ee1f4ba22bd9061cc7a172bd04)) + + +### Bug Fixes + +* abort issue on SAS with ms_webout etc ([05d79cb](https://github.com/datacontroller/datacontroller/commit/05d79cb096adfdaa1dd831b12cb379636e726ebd)) +* adapter config in index.html can be ommited now ([0058eb8](https://github.com/datacontroller/datacontroller/commit/0058eb8ffe481b76130d21837b55dbfb0c24dce2)) +* adapter execute script breaking change ([fd98a2e](https://github.com/datacontroller/datacontroller/commit/fd98a2e68870e797ad40e2fb683e362b63bcccfa)) +* adapter updated ([414bf8d](https://github.com/datacontroller/datacontroller/commit/414bf8d606640091a41c7c91ce1ef77d4c29e522)) +* approve details too many changes JS error ([2efb49e](https://github.com/datacontroller/datacontroller/commit/2efb49ebfdd751c06fd542c9c0f7be08398e391c)) +* bump prettier ([0ab0e84](https://github.com/datacontroller/datacontroller/commit/0ab0e844508a6afbc06d393ca82c44cdc864f04d)) +* bumping core & cli ([c7ce70d](https://github.com/datacontroller/datacontroller/commit/c7ce70d72a1cef1d5249f09a758df56af50f0aa6)) +* col lineage errors (not respecting max_depth) ([2fdc462](https://github.com/datacontroller/datacontroller/commit/2fdc462af270935e35cbc8f933ae753316676377)) +* col lineage hanging issue ([da6536e](https://github.com/datacontroller/datacontroller/commit/da6536e5e508c81b69d4d3aa92df90e5bbd80aac)) +* dynamic mocks for licencing tests ([f967058](https://github.com/datacontroller/datacontroller/commit/f9670583461115caa0dcad1c93bee19f2120c91b)) +* filtering and licence testing, dynamic mocks ([e309029](https://github.com/datacontroller/datacontroller/commit/e30902947fc25ff27366ff77c23d5e9bed3757d3)) +* improved changed rows notice position ([8c521c8](https://github.com/datacontroller/datacontroller/commit/8c521c8aa29c902ea85b7adcabcfdd132ba7d462)) +* remove ng2-file-uploader ([4170546](https://github.com/datacontroller/datacontroller/commit/41705466f1ffc1a28be7b5de250299aafcf9e79b)) +* rename label (dot depth) ([57fa379](https://github.com/datacontroller/datacontroller/commit/57fa37931be42edb7cbe724740a3b486296c072f)) +* update handsontable to 12.2.0 ([a438671](https://github.com/datacontroller/datacontroller/commit/a4386717e8c0f38974297953a6cf805b012cb246)) +* viewbox libraries paging ([4039973](https://github.com/datacontroller/datacontroller/commit/4039973af861146250893da4588de9d9be79a9e4)) +* **viewboxes:** independent filter caching ([7f78ef0](https://github.com/datacontroller/datacontroller/commit/7f78ef0cd2a6967f0fe69a2d55fdd808b4b14211)) +* **viewboxes:** main table filtering title, z index ([0801b5c](https://github.com/datacontroller/datacontroller/commit/0801b5c1fac147dc6ea21e0eeb3b64f514e7c6c1)) +* **viewboxes:** url and keyboard selecting in tree double select ([80942cb](https://github.com/datacontroller/datacontroller/commit/80942cb1f68c6cadf2c026e761c331cb0d1660ac)) + +## [5.2.0](https://github.com/datacontroller/datacontroller/compare/v5.1.0...v5.2.0) (2022-11-15) + + +### Features + +* limit lineage depth button ([cc901f1](https://github.com/datacontroller/datacontroller/commit/cc901f14d499452a19a666c032f72b44b810a4d4)) + + +### Bug Fixes + +* deps update ([8c9a14f](https://github.com/datacontroller/datacontroller/commit/8c9a14f2c7e6004ec62186e096c80f60002f8acd)) +* dummy js file to force admin folder in demo.datacontroller.io ([07f3194](https://github.com/datacontroller/datacontroller/commit/07f319454ab776372e707e763eea34f423ff12bf)) +* editor and viewer responsiveness, logo smaller ([e44ff33](https://github.com/datacontroller/datacontroller/commit/e44ff3389077642359e2fc33f1285d666cbf2c52)) +* enable ampersands in library & table lineage ([078acf3](https://github.com/datacontroller/datacontroller/commit/078acf30e2ac4d8aebaff4a783b9800bf0f4af50)) +* libinfo alignment ([c508f83](https://github.com/datacontroller/datacontroller/commit/c508f83ab25aaba406dfd03f866206909a588d80)) +* licensing error details ([99bb81a](https://github.com/datacontroller/datacontroller/commit/99bb81a01ad021dbfbdfefdb2189eb568125c956)) +* licensing error params ([9c4e1e6](https://github.com/datacontroller/datacontroller/commit/9c4e1e686e9f89380af79d2064abb1db9e14538a)) +* lineage missmatch info not breaking error ([029fa9f](https://github.com/datacontroller/datacontroller/commit/029fa9f045a1a8f3529fd4b0ddf701275f42e779)) +* lineage sidebar matching and error handling ([e26fb0c](https://github.com/datacontroller/datacontroller/commit/e26fb0cede2e05128395599a319bfe4aab2292d0)) +* lineage table 'nolib' fix ([b74f0e0](https://github.com/datacontroller/datacontroller/commit/b74f0e0b9c1cdee17a98daba74ef9b0045765c62)) +* max_depth not working on large lineage graphs ([1e066f1](https://github.com/datacontroller/datacontroller/commit/1e066f17cf9249bf25408ab8e2290c3aea5c6449)) +* missing PK fields in dictionary table ([d40835b](https://github.com/datacontroller/datacontroller/commit/d40835b9da4d9d2750421e9b2232d0a9cea75921)) +* viewer lib info styling on smaller screens ([c2c4424](https://github.com/datacontroller/datacontroller/commit/c2c44241a27aeccf8f3923fdc0dad2e8cbb6da23)) + +## [5.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v5.0.0...v5.1.0) (2022-09-02) + + +### Features + +* adding dsmeta info from mp_dsmeta macro ([2ac6659](https://gitlab.com/macropeople/dcfrontend/commit/2ac66592a27d2581fdbe31ea46f067f0ad42379f)) +* adding sasdoc generation for all SAS Platforms ([56662ce](https://gitlab.com/macropeople/dcfrontend/commit/56662ce7b0bfdacda89621b759bb1df1e8ae83d4)) +* dsmeta added to view and edit ([24e35dd](https://gitlab.com/macropeople/dcfrontend/commit/24e35dda6584a99734520152bce21b22cb90e6f6)) +* edit record - forward backwards changing records ([b28b8f8](https://gitlab.com/macropeople/dcfrontend/commit/b28b8f87859da93105e15471ae7e1c1e6b3846fd)) +* initial contents for https://code.datacontroller.io ([fdf8808](https://gitlab.com/macropeople/dcfrontend/commit/fdf88084384ef9fe4b4d90f8aa431f898114d5e5)) +* library linking ([fa4aba8](https://gitlab.com/macropeople/dcfrontend/commit/fa4aba8bae442c2167611d96da83da8716ca18fa)) +* new libinfo backend service ([0618e63](https://gitlab.com/macropeople/dcfrontend/commit/0618e6397e3d5c31bd2bd75d7346e2bed352b74e)) +* refreshlib feature (and tests) backend ([3980774](https://gitlab.com/macropeople/dcfrontend/commit/39807741bc192d5fb24430598082d88aa45e040e)) +* viewer library info page ([01b1148](https://gitlab.com/macropeople/dcfrontend/commit/01b114842fac6aa8ed4697778e5f4369bcb60e96)) + + +### Bug Fixes + +* adding libinfo in response from refreshlibinfo ([8810b2e](https://gitlab.com/macropeople/dcfrontend/commit/8810b2e459137fa796b8d7d99fa25a1b85a78cab)) +* angular configuration fix ([a67e12e](https://gitlab.com/macropeople/dcfrontend/commit/a67e12e46b30ba6359969a591cf4a7336baf017d)) +* avoid warning for empty library in viewtables ([abed1a9](https://gitlab.com/macropeople/dcfrontend/commit/abed1a97f23634ebe2d3f48228fb4ad678efe1bb)) +* bump core to fix formats with incorrect length ([211f5dc](https://gitlab.com/macropeople/dcfrontend/commit/211f5dc83a4d7b3eca6358ebded4064cc8aa859b)) +* bumping core ([6cb3216](https://gitlab.com/macropeople/dcfrontend/commit/6cb321694112afd54913ebd55f166ddfae57a6d7)) +* cleanup, editor modularized, angualr 14 update ([558ea94](https://gitlab.com/macropeople/dcfrontend/commit/558ea94eb52133381bd92da68e0223a888b04ea9)) +* css issues ([e0f6f33](https://gitlab.com/macropeople/dcfrontend/commit/e0f6f33986d8764839ccb53aba4be914947dc652)) +* current row start from 1 ([05267e3](https://gitlab.com/macropeople/dcfrontend/commit/05267e3fefca6c80e6b364d4f0ccdc77980c48c2)) +* custom autocomplete input component, fixed qutes around date and time in filtering ([985c45b](https://gitlab.com/macropeople/dcfrontend/commit/985c45bf76278959929cf0351ed2ea0f31686dd9)) +* date time filtering with quotes ([78babd3](https://gitlab.com/macropeople/dcfrontend/commit/78babd3121c127095dd5f4711b54fa0e7efb1897)) +* demo limits ([97ee3f7](https://gitlab.com/macropeople/dcfrontend/commit/97ee3f7384014ba0e1377b0ea70b8dd1dbe51071)) +* dynamic cell validation suppress ABORT modals ([951a0d5](https://gitlab.com/macropeople/dcfrontend/commit/951a0d5cb90946e9ebf08644d1e55a0a60e24c03)) +* dynamically obtaining serverContext when running makedata on SAS 9 ([22dec2d](https://gitlab.com/macropeople/dcfrontend/commit/22dec2d570e212804c49e7ee920dde8c8aaa5b1e)) +* edit record separate component, modulization routihng ([0e2a57b](https://gitlab.com/macropeople/dcfrontend/commit/0e2a57b53c7124abe5d50476e80e1b3a833b56ea)) +* editor multiple filterings ([20bb5cd](https://gitlab.com/macropeople/dcfrontend/commit/20bb5cdd7bae1813dfe29aa1aa3658aaf746aae8)) +* empty library no tables, approve details screen break dots ([54ca1ef](https://gitlab.com/macropeople/dcfrontend/commit/54ca1efe3216526b6adc2b7e869ebc316ada3bfa)) +* enabling consistent formats in the generated DIFF screen ([80ec246](https://gitlab.com/macropeople/dcfrontend/commit/80ec24667d8fa74b090bf95ed8bc00ae0d66843b)) +* filtering IN did not append quotes ([62256a6](https://gitlab.com/macropeople/dcfrontend/commit/62256a6b11e2e7494d2f3b29870382a6f922d4a4)) +* filtering Input typing, editor filtering quotes, update licence key placing ([1f2a516](https://gitlab.com/macropeople/dcfrontend/commit/1f2a516742119157b634e0c3cbd84d1abc721adf)) +* filtering logic operator undefined ([5c8e951](https://gitlab.com/macropeople/dcfrontend/commit/5c8e951c89a1c73f166c856ae8fa3d3f977e1fa1)) +* filtering OR not working ([98c43a5](https://gitlab.com/macropeople/dcfrontend/commit/98c43a518566043649fb06e39588f6d36d913d3c)) +* going to libinfo from table view ([13c4add](https://gitlab.com/macropeople/dcfrontend/commit/13c4addeded5eb5bd678bcb3348c9590b052fe7b)) +* half way fixed inline styles ([2f85090](https://gitlab.com/macropeople/dcfrontend/commit/2f8509062981330070b0817bca5dca30ee87b5c8)) +* hardselect_hook on numeric was not strict ([abdea54](https://gitlab.com/macropeople/dcfrontend/commit/abdea5496d6f6a5fb7d364e716761e742d4d09fd)) +* images in dist/images folder ([d187c5d](https://gitlab.com/macropeople/dcfrontend/commit/d187c5d1fa2050250926ebdc58056bee69478ce6)) +* incorrect validation on format catalog load type ([b095926](https://gitlab.com/macropeople/dcfrontend/commit/b095926dd72c5b5182b978fe2b3b462d8176381c)) +* libraries not refreshing on SAS 9 ([77e33df](https://gitlab.com/macropeople/dcfrontend/commit/77e33df9bce37f77f802b8e32a22dd3448c23cc6)) +* licence note ([39d04bd](https://gitlab.com/macropeople/dcfrontend/commit/39d04bdc42102e3b3a9ceef528379e312f3db32a)) +* mp_lockanytable error in rejecction ([195a350](https://gitlab.com/macropeople/dcfrontend/commit/195a3501d6d338bd270ba97f1224c6dbbff148c2)) +* number of changed rows limit ([55ab7cf](https://gitlab.com/macropeople/dcfrontend/commit/55ab7cf9c5c0e3892c5cd89034cbb11d3dc0fb28)) +* pasting NaN issue ([0b1ad3a](https://gitlab.com/macropeople/dcfrontend/commit/0b1ad3a1a81bc2927b89ed5fe45d994d25dbfa02)) +* performance improvements with latest mp_jsonout ([5251f24](https://gitlab.com/macropeople/dcfrontend/commit/5251f2494946867111706758102875926168879e)) +* requests modal ux, filtering reset kept old values ([dc866aa](https://gitlab.com/macropeople/dcfrontend/commit/dc866aacbe944ef1affddaaa7d3c671eebb860c4)) +* softselect dropdown sticking ([b51afbb](https://gitlab.com/macropeople/dcfrontend/commit/b51afbb484dd9ab7ea9641dd185f70a256367ee4)) +* typing in filtering `variable` call only on select from dropdown ([cfe9bf6](https://gitlab.com/macropeople/dcfrontend/commit/cfe9bf6c4ac48d4e5ea7e0f8fa3d4fbd8c949d69)) +* validations failing in MPE_TABLES for column values due to initialisation of CLS_XX variables ([d65b609](https://gitlab.com/macropeople/dcfrontend/commit/d65b6092b4b39cc4b3043f24a2e89de2839343a9)) +* **validations:** ensure LOADTYPE on MPE_TABLES has correct values ([536b176](https://gitlab.com/macropeople/dcfrontend/commit/536b17654d64eff57fe417ad1d830b55e10b046f)) +* viya 4 compatibility ([9bb4b88](https://gitlab.com/macropeople/dcfrontend/commit/9bb4b886d08d81284e9fa60f1809184a0a22d2e2)) +* when library info refreshed it was not stored ([ea50b31](https://gitlab.com/macropeople/dcfrontend/commit/ea50b31e72655d3f2cf7dd2579b753e3786d7fb4)) +* when paste and edit record confirmation type conversion and special missing handling ([a352608](https://gitlab.com/macropeople/dcfrontend/commit/a35260861aaaa6f820c16c7d9c3664564426aad2)) +* when pasting into grid types gets lost ([5e75a39](https://gitlab.com/macropeople/dcfrontend/commit/5e75a39f6b06eec3ce1704e0748fec298aebb733)) + +## [5.0.0](https://gitlab.com/macropeople/dcfrontend/compare/v4.2.2...v5.0.0) (2022-07-11) + + +### ⚠ BREAKING CHANGES + +* mpe_approvals is now dropped and replaced by MPE_SUBMIT, which is unique on table_id. + +### Features + +* added demo config ([ea9cef0](https://gitlab.com/macropeople/dcfrontend/commit/ea9cef0995e36f7663d8979e5335c5b3f0f99cc8)) +* additional tables added to export process. Fixed a bug when staged data contains only deletions. Also added CLS rules to COLS table in getdata response. ([66749f1](https://gitlab.com/macropeople/dcfrontend/commit/66749f16665f9c04b802a6ed4b0899f470866f3c)) +* backend users (to be continued) ([ba487ba](https://gitlab.com/macropeople/dcfrontend/commit/ba487baa9c5d99ac33c59ed8decf3534de8c267a)) +* Column Level Security ([7651fb8](https://gitlab.com/macropeople/dcfrontend/commit/7651fb8ece2a4b29b1e18ac8a447f034bae292a7)) +* Column level securty EDITOR ([fdfe333](https://gitlab.com/macropeople/dcfrontend/commit/fdfe33371c83addd4da327ecd2f5b6f1d4602561)) +* configurable audit (plus test fixes) ([8673d37](https://gitlab.com/macropeople/dcfrontend/commit/8673d37b7356c5efaa3f9ef5efc3f59f9a7ec671)) +* demo max rows ([1b97255](https://gitlab.com/macropeople/dcfrontend/commit/1b97255978acaa8e72a336a65c72357ad371083c)) +* dynamic validation features in edit record modal ([6740a5b](https://gitlab.com/macropeople/dcfrontend/commit/6740a5bf70d929e53d886132584f40d03cf43ecf)) +* enabling backend primary key columns on VIEW tables ([1db832c](https://gitlab.com/macropeople/dcfrontend/commit/1db832cbc56a2d1d0622b5bd21dd02fb9602728d)) +* enabling download as markdown feature ([9032cd1](https://gitlab.com/macropeople/dcfrontend/commit/9032cd18a491339060080c57e4134002cfa95a63)) +* getgroups ([6247d6e](https://gitlab.com/macropeople/dcfrontend/commit/6247d6eb2bf35939a9a6b4caa04d2575bdbfe9c3)) +* hardselect in record modal - numeric ([b88e622](https://gitlab.com/macropeople/dcfrontend/commit/b88e622a72569f75613700bdf7698146a49fe259)) +* new deploy process for SAS 9 ([15e4936](https://gitlab.com/macropeople/dcfrontend/commit/15e4936ef577c199ee33d4ea1622ed8ab0c7cf0f)) +* no key demo mode ([f76a0e7](https://gitlab.com/macropeople/dcfrontend/commit/f76a0e76193a8500081087e0305e755b24489df9)) +* record modal dynamic cell validation started ([e537958](https://gitlab.com/macropeople/dcfrontend/commit/e5379585aa511b7e5764ec8410efe914d8406086)) +* refactored DB for submit & approve ([a58151f](https://gitlab.com/macropeople/dcfrontend/commit/a58151f145dcc81eb7d0772e7b2a170ce861d899)) +* restrict EDIT RECORD ([0e30649](https://gitlab.com/macropeople/dcfrontend/commit/0e306498dc4d57b0e02e33e75f25308dcd35c3bd)) +* restrict editrecord ([5c8f013](https://gitlab.com/macropeople/dcfrontend/commit/5c8f013e2181e298419f963ac1e3aa5b5a87da64)) +* sas9 configurator init ([40b70ab](https://gitlab.com/macropeople/dcfrontend/commit/40b70aba511cf0d815ddf0802344d34e7f3d208a)) +* sasjs configurator ([f823276](https://gitlab.com/macropeople/dcfrontend/commit/f823276487524d60c8bec59793ae1cf261951f7c)) +* sasjs configurator - on deploy page ([6511c19](https://gitlab.com/macropeople/dcfrontend/commit/6511c198a027226a27fc6d8e91c4c915807373c3)) +* sasjs server - redirect to configurator if exits ([eb054cd](https://gitlab.com/macropeople/dcfrontend/commit/eb054cd33e772510cc96a1bfa35cced6497f7531)) +* sasjs/server appstream compatibility - see server target ([cf17c90](https://gitlab.com/macropeople/dcfrontend/commit/cf17c9024171a19f2ccadec6c6616f472f6827da)) +* show abort modal separate then show info modal ([033be9a](https://gitlab.com/macropeople/dcfrontend/commit/033be9a9ba919aa7bec7ce5de1af26941464b5ed)) +* unlocking password protected excel ([ea93601](https://gitlab.com/macropeople/dcfrontend/commit/ea93601192dad275cd32f4647007cc7a2e85d578)) + + +### Bug Fixes + +* abort modal download log butto ([ca4631e](https://gitlab.com/macropeople/dcfrontend/commit/ca4631e34a2a0913c561e34cf71d15efa210fc69)) +* adapter bump and viya usernav rename ([e98ae0e](https://gitlab.com/macropeople/dcfrontend/commit/e98ae0ee76a8a082b2c6cd13f0696bfcf1fd88f8)) +* added open requests modal on sasjs abort ([ea78672](https://gitlab.com/macropeople/dcfrontend/commit/ea786721042e4f5c85e13f3a2886b6f031fe0ea3)) +* adding makedataserver.json file ([0fa8680](https://gitlab.com/macropeople/dcfrontend/commit/0fa86801ef6cf5baea08c39e98d17d0c8f014908)) +* adding missing statement for CSV uploads ([a8dc48f](https://gitlab.com/macropeople/dcfrontend/commit/a8dc48fc697f71ea8276fee28bafbac15e223b07)) +* adding mp_init back ([dba9d7c](https://gitlab.com/macropeople/dcfrontend/commit/dba9d7c776f8f5ee28a7ab4c2cfa5b2f906f97ca)) +* adding submit reason to approve pages ([cd903e3](https://gitlab.com/macropeople/dcfrontend/commit/cd903e3cbb5b939a6c2955d1983bc8a0e5bcc21a)) +* ading dc-admin as default admin group ([fe5866c](https://gitlab.com/macropeople/dcfrontend/commit/fe5866c22e1144788a8a4c53e285d3018bf6de24)) +* alias ([797e137](https://gitlab.com/macropeople/dcfrontend/commit/797e1370f15382c0926abd67363e8df210785792)) +* approve details - formatted default on ([16e675c](https://gitlab.com/macropeople/dcfrontend/commit/16e675c4a223a7f759582a80e4a2e99194fcdda8)) +* assets fix, logo ([667246f](https://gitlab.com/macropeople/dcfrontend/commit/667246f2d35fd9c64794a336fba5a1249e00a69c)) +* avoiding error in mpe_filtermaster (read/write same dest) ([2f6a33e](https://gitlab.com/macropeople/dcfrontend/commit/2f6a33e8b47ddf3d8aeb8078580c7d77a06b607a)) +* badly placed comma ([182a6b0](https://gitlab.com/macropeople/dcfrontend/commit/182a6b0ffabd50c3c5be46d68329a68c53cf1bde)) +* bum core ([aa29837](https://gitlab.com/macropeople/dcfrontend/commit/aa298372e8b0b8b1bb8f08ea027637eddeae47a4)) +* bump core and avoid mpe_groups warning ([bec7149](https://gitlab.com/macropeople/dcfrontend/commit/bec71497b7dca49c451267c581e17f061bcd0e6b)) +* bump core, test setup ([d0efc3c](https://gitlab.com/macropeople/dcfrontend/commit/d0efc3c4b94e54967bf913ed6f149c6c6a7a6f69)) +* bumping core ([5c0b7a9](https://gitlab.com/macropeople/dcfrontend/commit/5c0b7a90536109394522d8b4937b61d4c9b8f1b2)) +* bumping core ([3c28c41](https://gitlab.com/macropeople/dcfrontend/commit/3c28c41237190d711fd4cad979d2e692f17b335b)) +* bumping core and improving makedata response on SAS 9 ([79ab3b8](https://gitlab.com/macropeople/dcfrontend/commit/79ab3b8ce4905fdc636839d04b0f8401b5a65196)) +* bumping core, missing comma in deploy ddl ([2114708](https://gitlab.com/macropeople/dcfrontend/commit/21147086e64cfb87b0328ad540528e7840551731)) +* bumping core, removing licence key ([0a3e381](https://gitlab.com/macropeople/dcfrontend/commit/0a3e381c2fc6d0cba259dbd59583b230d6d37d1f)) +* case when statement ([14304a0](https://gitlab.com/macropeople/dcfrontend/commit/14304a0736e68de97ba63673b5067b0694f06a64)) +* char limit ([d9af43a](https://gitlab.com/macropeople/dcfrontend/commit/d9af43ab59a658b6e0b74674b8852589cd0ce259)) +* checking makedata ([5f64079](https://gitlab.com/macropeople/dcfrontend/commit/5f64079ddd6dcfd021e8b889539eaf1a9b65c26b)) +* clarity csp issues ([2ee3ee7](https://gitlab.com/macropeople/dcfrontend/commit/2ee3ee7272d7af0837dc3d42cddb106cc73492f2)) +* cls issues revisit ([35b5fce](https://gitlab.com/macropeople/dcfrontend/commit/35b5fce8a68b37a04a8c99ef28311eea587b25b9)) +* config ([1797964](https://gitlab.com/macropeople/dcfrontend/commit/1797964ecb1eb7f2bca79a6df2785f9468ed3a4d)) +* configurator added group description and progress bar ([b72d27a](https://gitlab.com/macropeople/dcfrontend/commit/b72d27a927bac79cc1e075bed4103ba82aaf0a7c)) +* configurator fixing ([10b3b60](https://gitlab.com/macropeople/dcfrontend/commit/10b3b60593a6435282ccf1a98ea27832123217c3)) +* configurator groups dropdown, making json request viya specific ([8b1c2c9](https://gitlab.com/macropeople/dcfrontend/commit/8b1c2c915a92010175354301302b5f1e7596e23a)) +* configurator html styling ([9d17ea7](https://gitlab.com/macropeople/dcfrontend/commit/9d17ea7778bc9bb0de5c97808f560be6f2f847dd)) +* configurator redirect - using new api endpoint (list folder content) ([e32edbf](https://gitlab.com/macropeople/dcfrontend/commit/e32edbf2e47c1b212cfc4e07914bd0cfa2a1e1df)) +* core bump ([3a29271](https://gitlab.com/macropeople/dcfrontend/commit/3a29271116cbb7610e9e5ab6ce4710724d85de0d)) +* csp issues cwb, /deploy page force, bump up deps ([f8b8ceb](https://gitlab.com/macropeople/dcfrontend/commit/f8b8ceb9e2117acb02bf56841d27555277a78d96)) +* CSV upload issue ([69f65de](https://gitlab.com/macropeople/dcfrontend/commit/69f65de59642d269fcfda80449f5cc539faced1d)) +* cypress testing ([3f29f9b](https://gitlab.com/macropeople/dcfrontend/commit/3f29f9b429f9cc9101ef2fab237da8f31475b095)) +* dc_dttmfmt macro usage (thanks to compatibility issue on M3 proc sql ([65aa595](https://gitlab.com/macropeople/dcfrontend/commit/65aa595fac58e6309814bf8f2bfd954b36a91b20)) +* default appLoc ([5507841](https://gitlab.com/macropeople/dcfrontend/commit/550784102374e8e5c99c830fc51fc587ea03d648)) +* demo limitations and file upload drop area ([bc4fb1b](https://gitlab.com/macropeople/dcfrontend/commit/bc4fb1b8f4a5209710aaa57e1935c1c4249d0469)) +* demo limits refactored - improved ([b80817c](https://gitlab.com/macropeople/dcfrontend/commit/b80817c23ec1e18b9e81e62a8a7cc9fe1ec4d1fa)) +* demoConfig rows allowed handling ([5254a6e](https://gitlab.com/macropeople/dcfrontend/commit/5254a6ec7ab67e232ef0698f5d07899b9c7c4dcc)) +* deploy component refactor ([2d28d5d](https://gitlab.com/macropeople/dcfrontend/commit/2d28d5d49c93b80f3392fac71373cef4f6935bcf)) +* deploy page autodeploy button to upload custom json file ([bee9274](https://gitlab.com/macropeople/dcfrontend/commit/bee9274153107f4e65989b7c3a9d5a6a730b99d0)) +* deploy sas9 auto redirect to configurator ([f6598d2](https://gitlab.com/macropeople/dcfrontend/commit/f6598d273befde2982fcdea409f01130d12546b6)) +* deprecated images as base64 - since csp can block them ([6c54100](https://gitlab.com/macropeople/dcfrontend/commit/6c54100220dd9be5ac9fe77164514802551cd573)) +* doc updates ([aa36de3](https://gitlab.com/macropeople/dcfrontend/commit/aa36de3c5eeebe941c82e385947f5ef60d392c1b)) +* drag n drop file fullscreen ([90f98c2](https://gitlab.com/macropeople/dcfrontend/commit/90f98c23f232f26d3b1e8a373b6abc6718aad110)) +* EDIT record ([9987e72](https://gitlab.com/macropeople/dcfrontend/commit/9987e72f4a07999784bb94c2eec8c02a6a89d455)) +* empty tables on SAS 9 ([4259866](https://gitlab.com/macropeople/dcfrontend/commit/42598669c67841337116621df96880340a1b1055)) +* enabling deletes ([e5bbaa8](https://gitlab.com/macropeople/dcfrontend/commit/e5bbaa88558c1ec9195730121b4af39bb91174f3)) +* excel upload NAN ([7c0dfda](https://gitlab.com/macropeople/dcfrontend/commit/7c0dfdafa992a6758d590297200eef5015ade512)) +* explicit cols ([6e28174](https://gitlab.com/macropeople/dcfrontend/commit/6e281745de773895e8fafcd47a99c44d45ad1b36)) +* filter values changed 200 limt to 2k ([ae64bb3](https://gitlab.com/macropeople/dcfrontend/commit/ae64bb3508f06319a3e7a8a77f6e4d78d4beb420)) +* filtering added clear button ([981456b](https://gitlab.com/macropeople/dcfrontend/commit/981456b791e45da89bbe33204f1c4c5348101a71)) +* filtering dropdowns showing formatted values and inputting unformatted ([beec1a2](https://gitlab.com/macropeople/dcfrontend/commit/beec1a2e3903792ee597a94a4b78e4dad81e3475)) +* filtering selecting special missing from dropdown ([d8fde39](https://gitlab.com/macropeople/dcfrontend/commit/d8fde39c92c29f8f486c7f167eeb89dac3061cca)) +* finishing up mpe_review + mpe_submit table refactor ([276669c](https://gitlab.com/macropeople/dcfrontend/commit/276669cc98077d019886c412d0d4bcb888190b5e)) +* fixing specs ([829a42c](https://gitlab.com/macropeople/dcfrontend/commit/829a42ce34b12be5eb46fe201b8e24d5f628edc7)) +* frontend ([3694f16](https://gitlab.com/macropeople/dcfrontend/commit/3694f16ddec5df0e3a295f3b35f4ac49d81951f9)) +* frontend fix for startup service, and backend libref ([6dc06b8](https://gitlab.com/macropeople/dcfrontend/commit/6dc06b8dd9fa3e18e9ec142e5de8dfc0e64ffa1b)) +* generic macro for hooks ([0fe00fd](https://gitlab.com/macropeople/dcfrontend/commit/0fe00fd2466ece1f7c3f6371c0834d5d8315e967)) +* group rename ([514146e](https://gitlab.com/macropeople/dcfrontend/commit/514146eb88a550bc5693a00f27405ffb45769edb)) +* hide in edit mode ([fc55fa9](https://gitlab.com/macropeople/dcfrontend/commit/fc55fa97884aa7d79f291a6edc89d4a8b0b4aef4)) +* history tab with submit reason ([592078f](https://gitlab.com/macropeople/dcfrontend/commit/592078fb6c94161f0f991660bd2df41df9d3e4ae)) +* hook scripts and desktop groups ([271987a](https://gitlab.com/macropeople/dcfrontend/commit/271987a02aac90cf7223d03454dee99730f2855c)) +* hotTable height when add record button missing ([1df4bac](https://gitlab.com/macropeople/dcfrontend/commit/1df4bac6ac898c39d61ff923117818746e49a3c6)) +* images to base64 ([1e1114b](https://gitlab.com/macropeople/dcfrontend/commit/1e1114b428c95a6e7a6e6f49c10d390d38f4c9b2)) +* issue with isSpecialMissing function, sufficient spec files removed ([39412df](https://gitlab.com/macropeople/dcfrontend/commit/39412df367558ed4c06593f42ad40709e5587840)) +* legacy peer deps in .npmrc ([14d5f2f](https://gitlab.com/macropeople/dcfrontend/commit/14d5f2f50b8ba683bfce677a68b7c7f7bf7ab8b9)) +* length in meta lineage ([f1a262c](https://gitlab.com/macropeople/dcfrontend/commit/f1a262cdb8dfb1b5ffa2f0db81e951eba01676c6)) +* lengths ([606611e](https://gitlab.com/macropeople/dcfrontend/commit/606611e11f729d2e862e93d26e72672cfb54546d)) +* lineage bug ([be64516](https://gitlab.com/macropeople/dcfrontend/commit/be645166e74f322d69dd29ed55a5a1d73e849355)) +* link and mpeinit ([e4b06c2](https://gitlab.com/macropeople/dcfrontend/commit/e4b06c2dd48188649e72f2b708aec74a252d1663)) +* lint ([af15f94](https://gitlab.com/macropeople/dcfrontend/commit/af15f94031dc221f1022da6971b939a93430c0a4)) +* lint and more approve group removal ([4079f57](https://gitlab.com/macropeople/dcfrontend/commit/4079f5790b0084e10c3289f14f94a453e3ed7ea7)) +* lint and naming of sasjs adapter ([740d720](https://gitlab.com/macropeople/dcfrontend/commit/740d720e5295d4a073127c4dceac32b3344d2ccf)) +* logout in configurator, filtering IN special missing ([43dc4d4](https://gitlab.com/macropeople/dcfrontend/commit/43dc4d4dde309d6e8d82a2165104f6ad25deca69)) +* makedata on viya ([b4c7970](https://gitlab.com/macropeople/dcfrontend/commit/b4c79709bd54e57ffe542dd1d30b046c162a932e)) +* making tests work ([5bcb955](https://gitlab.com/macropeople/dcfrontend/commit/5bcb955f753577b42dd6d7aed124a65227272b7c)) +* making time format configurable ([202d45e](https://gitlab.com/macropeople/dcfrontend/commit/202d45ea0b17e8bbcfb2bac0c5def0d9a885216d)) +* merge development ([5d0057d](https://gitlab.com/macropeople/dcfrontend/commit/5d0057d1eb21deca0bd6506a20c272676b0324c7)) +* merge development ([434943c](https://gitlab.com/macropeople/dcfrontend/commit/434943cce4496c8fcc7aab0cc872773c030ec4ce)) +* merging changes ([fbe5e14](https://gitlab.com/macropeople/dcfrontend/commit/fbe5e140e8560c7d81d5ce9af40c2d411da7801f)) +* merging spec and cols ([7d6bb90](https://gitlab.com/macropeople/dcfrontend/commit/7d6bb90a3c44a106e3ae180e3bca42a15729bb50)) +* model updates ([31cf930](https://gitlab.com/macropeople/dcfrontend/commit/31cf9305b6129edb8827d82cef8e7a8434d97ff0)) +* more fixes | ([ddf94d5](https://gitlab.com/macropeople/dcfrontend/commit/ddf94d5b604c011eb7acd620706b14f7eb9350d3)) +* mp_include ([d518367](https://gitlab.com/macropeople/dcfrontend/commit/d518367aca4a105bd8d210035ea810f548e393fb)) +* mpe_tables hook script ([2ba8a37](https://gitlab.com/macropeople/dcfrontend/commit/2ba8a37532addca762c08bfe32eb05f53da7cbfe)) +* newline ([285f017](https://gitlab.com/macropeople/dcfrontend/commit/285f017a412fce4accf50b9563d5d79007178d4f)) +* no data rows excel upload ([a624f4e](https://gitlab.com/macropeople/dcfrontend/commit/a624f4e67e4be6b32b158f2c00edf9a81a1dcb16)) +* nonote2err switch ([904bcdb](https://gitlab.com/macropeople/dcfrontend/commit/904bcdba6d0d435465b50c2dcaa123c5e6066131)) +* optional userid as input ([33a6925](https://gitlab.com/macropeople/dcfrontend/commit/33a692569a7a0ecc0048c6363ef4643efa265f67)) +* performance boost ([4abec25](https://gitlab.com/macropeople/dcfrontend/commit/4abec2567af55e0deeddd17b292bde5faf78e02d)) +* prettier ([f3868f0](https://gitlab.com/macropeople/dcfrontend/commit/f3868f05b799d2fed8606599966b2f08323b6a55)) +* preventing CLS being applied to admin users ([a414492](https://gitlab.com/macropeople/dcfrontend/commit/a414492210b4532ee344263594b58f6b1ef0571b)) +* primary key always only readonly when cls active ([33ab65b](https://gitlab.com/macropeople/dcfrontend/commit/33ab65b33c95f8633ffc2f144322a0ac20669ddd)) +* quoting ([7ca2f97](https://gitlab.com/macropeople/dcfrontend/commit/7ca2f975b89a0705dd79add7f46f69130de00e79)) +* redirect streaming app ([9e795d0](https://gitlab.com/macropeople/dcfrontend/commit/9e795d0b828270594be8653de6f436afd455c241)) +* reduce row limit in VIEW for performance (to 250 from 1000) ([9a28d6f](https://gitlab.com/macropeople/dcfrontend/commit/9a28d6fd5781352e23ea97df41adaf06899381d5)) +* refactoring deploy component ([4f7a495](https://gitlab.com/macropeople/dcfrontend/commit/4f7a495466cb223f3114c6f221fc312123ffcd77)) +* reload issue - first time loading screen was stuck ([80c5af8](https://gitlab.com/macropeople/dcfrontend/commit/80c5af8322d6dff1b999256d49f14f6af151d2ac)) +* removed inline script, sasjsConfig as html attributes ([fc6fb22](https://gitlab.com/macropeople/dcfrontend/commit/fc6fb22634447a544785b25e622d1323cd958fdc)) +* removed sasjs sufficient elements from usernav ([1176655](https://gitlab.com/macropeople/dcfrontend/commit/1176655c917d36e2cd3360bb84c4a04db3d03a04)) +* requests modal fixes ([6c720a8](https://gitlab.com/macropeople/dcfrontend/commit/6c720a85f8c986bbde8d531dba07099e2e10a84c)) +* requests modal undefined handling ([aca8bfb](https://gitlab.com/macropeople/dcfrontend/commit/aca8bfbd330287557514291cee38f199fe55fdd1)) +* sajs server mode - login ([5f589e5](https://gitlab.com/macropeople/dcfrontend/commit/5f589e5375b36355eb7eff514f25dee304708c4e)) +* sas9 and user fixes: ([b42b47f](https://gitlab.com/macropeople/dcfrontend/commit/b42b47fefb7cb525780d1f887bb8e68b6c609d27)) +* sas9 configurator fixes ([4c83a34](https://gitlab.com/macropeople/dcfrontend/commit/4c83a342b72c126bcdde9bf464171a5c3a122d27)) +* sasjs configurator finish - get groups request ([51df692](https://gitlab.com/macropeople/dcfrontend/commit/51df692a6b9c80da0230e41eb9670a6171e411d4)) +* sasjs server fixes ([dd1fe5f](https://gitlab.com/macropeople/dcfrontend/commit/dd1fe5f4e36152d5714bbeb7e09fbc8a320184a1)) +* sasjs server fixes and sasjsconfig update ([b43e5e5](https://gitlab.com/macropeople/dcfrontend/commit/b43e5e5a01a7f3575b528f9f410f9a2c2192de3d)) +* sasjs server url for downloads ([083bca1](https://gitlab.com/macropeople/dcfrontend/commit/083bca10246d4c0ce66ea661c24da49d8faa5e0b)) +* sasjs serverType - usernav ([aeca2a6](https://gitlab.com/macropeople/dcfrontend/commit/aeca2a6a26bfbca7adbe2d7fe3fa4f38bab55bc3)) +* save password prompt ([49f05b2](https://gitlab.com/macropeople/dcfrontend/commit/49f05b2b748fc8760bf416dacd14952240d5e9ad)) +* sending favicon as base64 ([b6a34ed](https://gitlab.com/macropeople/dcfrontend/commit/b6a34edfdb0dc8c6bf55c90d73ed9fb9e13f29b9)) +* server favicon ([5afd806](https://gitlab.com/macropeople/dcfrontend/commit/5afd8061e22145ee8f8d6fda1c363fa25df97b87)) +* test for OS at backend ([c062b00](https://gitlab.com/macropeople/dcfrontend/commit/c062b00a94d60c2d3a0537f0596fbd12ec9594a8)) +* testing updates ([8b16282](https://gitlab.com/macropeople/dcfrontend/commit/8b16282a4973453f94229edc9c0657bdd1da3507)) +* tests and bumping core ([336f54a](https://gitlab.com/macropeople/dcfrontend/commit/336f54aa22fdf1bece991652c601cf519b8ec95b)) +* timestamping issues ([082f0cd](https://gitlab.com/macropeople/dcfrontend/commit/082f0cd05c480e78f7c5e01e06885702f3800ff2)) +* tree navigation search UX ([a17f253](https://gitlab.com/macropeople/dcfrontend/commit/a17f253c87ff9002c5e4ecd9f1e60ee6d4dd681c)) +* update to improve user experience with sorted data ([8cb1b5b](https://gitlab.com/macropeople/dcfrontend/commit/8cb1b5b29412ef0d6c061d37b39a81d2aebc76bd)) +* updating licence key and filter clause ([c87c3d8](https://gitlab.com/macropeople/dcfrontend/commit/c87c3d8e98f6ec2fc31217b57e4e4850f3cf4f78)) +* usergroups updates ([83cd292](https://gitlab.com/macropeople/dcfrontend/commit/83cd292f8cf24533cda5dcbc509d0da84e22434f)) +* username / group updates ([229886d](https://gitlab.com/macropeople/dcfrontend/commit/229886d565ddf8d626ce9a1ef27bdd35ec33e8b4)) +* usernav linking and group name ([02c8f60](https://gitlab.com/macropeople/dcfrontend/commit/02c8f608bffc9a37122dfad417f5130358969c7d)) +* users & groups on sasjs ([8886905](https://gitlab.com/macropeople/dcfrontend/commit/888690536d06e1bcca9071d5cdbcdd29b1dc2ad5)) +* using conditional logic on mpe_refreshtables ([f71f18f](https://gitlab.com/macropeople/dcfrontend/commit/f71f18f29dfe312cc733fd3b6755fbbd3b49d0bd)) +* using mf_fmtdttm() ([34ad201](https://gitlab.com/macropeople/dcfrontend/commit/34ad201baebf8003fdb6cc235436d6e47893727d)) +* using usernav instead of viya_users ([3d50bbd](https://gitlab.com/macropeople/dcfrontend/commit/3d50bbda18251f3625163bf452f37ca96e0f40d3)) +* UX improvements, cols, spec cleanup, dropdown empty record issue ([9a7c3e9](https://gitlab.com/macropeople/dcfrontend/commit/9a7c3e95dce762e50d126b2d9ceab53ca55c9c4a)) +* viewdata for just meta only definition ([65ae495](https://gitlab.com/macropeople/dcfrontend/commit/65ae4950ca206698b7c0a2e3d890e445a60048d2)) +* viewer error handling ([3c54689](https://gitlab.com/macropeople/dcfrontend/commit/3c546890d98df730273ffad6b0a4cdfb2ff3214e)) +* viewer PK coloring, search missing when no data ([f10b8c7](https://gitlab.com/macropeople/dcfrontend/commit/f10b8c71a893a3339deac0129e270f486acb86be)) +* viewer reset filter ([0ac5972](https://gitlab.com/macropeople/dcfrontend/commit/0ac5972b7103b593aa5d8736591a8bcbf915dc41)) +* when file upload error (csv) file is discarded ([7653fff](https://gitlab.com/macropeople/dcfrontend/commit/7653fffb3a697897e51d5c70a2855dfebc2078dd)) +* wps compatibilities ([79c5223](https://gitlab.com/macropeople/dcfrontend/commit/79c52231cd063de2c87b1c351761c85786d7381e)) +* wps fix for mpeterm() ([2473364](https://gitlab.com/macropeople/dcfrontend/commit/2473364356d611e54378caad76d02e0beb1566e5)) +* wps updates ([4c85101](https://gitlab.com/macropeople/dcfrontend/commit/4c85101bd910ece6829727cb1d7212999b3fac77)) + +### [4.2.2](https://gitlab.com/macropeople/dcfrontend/compare/v4.2.0...v4.2.2) (2022-03-21) + + +### Bug Fixes + +* friendly labels on sas 9 invalid view libs (and other ci/cid updates) ([9014f28](https://gitlab.com/macropeople/dcfrontend/commit/9014f28193ad118c28667c1f606b61f8fd61cc68)) +* sajs server ([0353ba1](https://gitlab.com/macropeople/dcfrontend/commit/0353ba1ed93efb74fd22c601115079154cfde104)) + +### [4.2.1](https://gitlab.com/macropeople/dcfrontend/compare/v4.2.0...v4.2.1) (2022-03-21) + + +### Bug Fixes + +* friendly labels on sas 9 invalid view libs (and other ci/cid updates) ([9014f28](https://gitlab.com/macropeople/dcfrontend/commit/9014f28193ad118c28667c1f606b61f8fd61cc68)) +* sajs server ([0353ba1](https://gitlab.com/macropeople/dcfrontend/commit/0353ba1ed93efb74fd22c601115079154cfde104)) + +## [4.2.0](https://gitlab.com/macropeople/dcfrontend/compare/v4.1.0...v4.2.0) (2022-03-17) + + +### Features + +* requests modal dowanlod logs ([bd9e759](https://gitlab.com/macropeople/dcfrontend/commit/bd9e75917f7e1f2a8459488b9030886dba0e69d0)) + + +### Bug Fixes + +* bump core ([a664573](https://gitlab.com/macropeople/dcfrontend/commit/a664573634046d2e27ab8f321d1e5f9153362805)) +* config ([fecdaee](https://gitlab.com/macropeople/dcfrontend/commit/fecdaeea2d9ba818f7df7c227cac669729f60de4)) +* filtering pickers checkbox ([8327421](https://gitlab.com/macropeople/dcfrontend/commit/83274213d32c46e28c88b8ddfb38c1a2a5eabfa0)) +* getting sas 9 tests to work ([d83b22d](https://gitlab.com/macropeople/dcfrontend/commit/d83b22d1664ce7266d443ea25f10ba139a5ac394)) +* missmatch fix ([b33b520](https://gitlab.com/macropeople/dcfrontend/commit/b33b52026b0bb3d51964f998c32047c8c757d370)) +* scss ([443c3d7](https://gitlab.com/macropeople/dcfrontend/commit/443c3d785c93d1e93d18a691161e1b57398a58a1)) +* validator length, abort modal MAC ([c6b3d1f](https://gitlab.com/macropeople/dcfrontend/commit/c6b3d1faa8ec70fbdb17ac00000a02b0c3073e5e)) + +## [4.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v4.0.1...v4.1.0) (2022-03-15) + + +### Features + +* server configurator ([df6cc6c](https://gitlab.com/macropeople/dcfrontend/commit/df6cc6cb8c575be4c83c321f7757719a124dd7ac)) + + +### Bug Fixes + +* audit service issues ([c6e1452](https://gitlab.com/macropeople/dcfrontend/commit/c6e14524aa43dd797d410ce072b989c15a8fe91d)) +* bump core and sasjs/server makedata update ([590710b](https://gitlab.com/macropeople/dcfrontend/commit/590710bffc95f047da06eff5a33cfe40bc8196e6)) +* refactor sas 9 deploy ([4458385](https://gitlab.com/macropeople/dcfrontend/commit/445838535f3d5fbed11bea3d5d0e92c8577d531a)) +* sas and app services timing ([7828d04](https://gitlab.com/macropeople/dcfrontend/commit/7828d04f49667f26a229a2c58e0b03e96a6bccdc)) +* sasjs server ([c999716](https://gitlab.com/macropeople/dcfrontend/commit/c999716a5fe494c882bc017b474208447d906738)) +* sasjs/server updates ([2cd0135](https://gitlab.com/macropeople/dcfrontend/commit/2cd0135d0da32da546990659a60650944509d04e)) +* update db for constraint support ([cc1e171](https://gitlab.com/macropeople/dcfrontend/commit/cc1e1711afd246cca285aa4850f339051f7637bb)) +* updates to deploy process ([f22556c](https://gitlab.com/macropeople/dcfrontend/commit/f22556c4cb1d4568779004bbd34113c688fd2845)) + +### [4.0.1](https://gitlab.com/macropeople/dcfrontend/compare/v4.0.0...v4.0.1) (2022-03-10) + + +### Bug Fixes + +* approve details UI ([4e058e9](https://gitlab.com/macropeople/dcfrontend/commit/4e058e90476a3130d877f56475dc52bd7be6d1a0)) +* bumping core ([70b5359](https://gitlab.com/macropeople/dcfrontend/commit/70b53591b1fed91f02bb7aa7a106259231488c8f)) +* missings validation ([0745486](https://gitlab.com/macropeople/dcfrontend/commit/074548695ff2865ab32fdb7f9e3d5291d96cdc47)) +* sas tests ([30b4b48](https://gitlab.com/macropeople/dcfrontend/commit/30b4b4832ab0cb24cc57c6e05858f49088b7b978)) +* special missing period prepend validation, replacing period in numeric with null ([9de4197](https://gitlab.com/macropeople/dcfrontend/commit/9de4197d92bcb8c01ff7caa59543f2480497dc9e)) +* testing issues and ability to upload excel for formats ([0e84e75](https://gitlab.com/macropeople/dcfrontend/commit/0e84e75086e2f438892f014ed363a967846aaa1d)) +* tests etc ([435452b](https://gitlab.com/macropeople/dcfrontend/commit/435452b0c7acd2fe14900388567821cf4c64f22c)) +* validation for numeric length ([0f9614b](https://gitlab.com/macropeople/dcfrontend/commit/0f9614bf9f9165dad5475c9262f6c9c76c27dba2)) + +## [4.0.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.13.3...v4.0.0) (2022-03-03) + + +### ⚠ BREAKING CHANGES + +* The filter_text variable is now dropped from mpe_filteranytable + +### Features + +* adding mp_init to ensure strict compatibilities. Also removing the word 'error' for better log scanning. ([f539474](https://gitlab.com/macropeople/dcfrontend/commit/f539474557f17d984e82e79f119d7c05b5bc0dba)) +* approve details - formatted values ([2d53b46](https://gitlab.com/macropeople/dcfrontend/commit/2d53b464a2d533e6ceb12883908b40c4bfc8bb1e)) +* col info in header menu dropdown, added sheetjs pro tarball backup ([6ed88f8](https://gitlab.com/macropeople/dcfrontend/commit/6ed88f8283647f8c890233bf59ee12c8d0f935db)) +* dc-validator module | shared components refactor ([271cc25](https://gitlab.com/macropeople/dcfrontend/commit/271cc256bb86e109f9dc03882081e55c696d78b1)) +* excel upload delete column apply ([d908126](https://gitlab.com/macropeople/dcfrontend/commit/d90812633949c8ba8bd6727cdbee28972809c06b)) +* format mods! ([6c6f3c5](https://gitlab.com/macropeople/dcfrontend/commit/6c6f3c5ca3b3547fdf32e3e8ef1686c176e48622)) +* formats catalogs ([5e233cf](https://gitlab.com/macropeople/dcfrontend/commit/5e233cff2511b5bd4bd207e65c4a6b7e3197d0c8)) +* formatted values for GET_DIFFS (backend). Relates to [#398](https://gitlab.com/macropeople/dcfrontend/issues/398) ([585ddb7](https://gitlab.com/macropeople/dcfrontend/commit/585ddb749da8eb48cbf1a1565fba738e07097baf)) +* mpe_audit table now updated with every load ([b48a762](https://gitlab.com/macropeople/dcfrontend/commit/b48a7620a6406c321f70c53a3d8d86f98854a0de)) +* primary key headers different color ([f7aa07c](https://gitlab.com/macropeople/dcfrontend/commit/f7aa07cf8aff6334cb8ff26941577fcb3a5a9a90)) +* sasjs/server support ([63c9dd4](https://gitlab.com/macropeople/dcfrontend/commit/63c9dd45f497817d982b94f7f1ea2712fa820dd3)) +* uploading excel with _delete_ column ([4b273e5](https://gitlab.com/macropeople/dcfrontend/commit/4b273e578141f4e5d63b6f7136a9dc23cbed43ee)) +* viewer - column context details ([0bf4c48](https://gitlab.com/macropeople/dcfrontend/commit/0bf4c48d356c5caea161d869afcd7d7613d0de4d)) + + +### Bug Fixes + +* abort modal refactor ([82a29a3](https://gitlab.com/macropeople/dcfrontend/commit/82a29a345f2b6e4e48094f1bac1f69e7380f416b)) +* adding .SSS to datetime and time formats ([af453e8](https://gitlab.com/macropeople/dcfrontend/commit/af453e87b7e21e253b0d89d0dc36e4d9fdb5c7f3)) +* adding catalog support for validatefilter and corresponding test ([8104fd9](https://gitlab.com/macropeople/dcfrontend/commit/8104fd9675e06454f5170c368af452189e1bd711)) +* addressing comments ([111473f](https://gitlab.com/macropeople/dcfrontend/commit/111473f870ff7a081df34c26270385590e8ad15a)) +* addressing yurys comments ([8a84fe7](https://gitlab.com/macropeople/dcfrontend/commit/8a84fe7e5ef947f43d5fbbdc5c8f626858fcb36e)) +* angular build ([f6c850c](https://gitlab.com/macropeople/dcfrontend/commit/f6c850c8c534655008b036800322e69501ebdd8e)) +* angular new config structure, fixing ts lint errors ([997e8b8](https://gitlab.com/macropeople/dcfrontend/commit/997e8b8ed8258f7cceb024d46ba3da217f99ed74)) +* approve details abort modal refactor ([8aec836](https://gitlab.com/macropeople/dcfrontend/commit/8aec83692a62b95a284c26ce18a735ddb5f49176)) +* approve details screen more compact ([05bfa52](https://gitlab.com/macropeople/dcfrontend/commit/05bfa52fd9fac93b60cc398ffcf15e55db750646)) +* changelog ([14b369a](https://gitlab.com/macropeople/dcfrontend/commit/14b369aa2e7ac3aee5d8b23e9721d434b287e54b)) +* conflicts: ([5622d01](https://gitlab.com/macropeople/dcfrontend/commit/5622d018d93ba358dc01f12e2ae387c9f105a075)) +* dropdown filtering UX optimization ([bf75a4a](https://gitlab.com/macropeople/dcfrontend/commit/bf75a4a2b9f8c7a50ff968b07eb96fd4cf874e6e)) +* dwp issues - bolt icon on viewer, routing user back to viewer issue ([53e8b64](https://gitlab.com/macropeople/dcfrontend/commit/53e8b647594301def750b88437a93719bd80958d)) +* enabling formats on getdata ([d1ae3df](https://gitlab.com/macropeople/dcfrontend/commit/d1ae3df2813cb28ff474906175974c548d96e161)) +* excel file `delete` column parsing ([1d1635d](https://gitlab.com/macropeople/dcfrontend/commit/1d1635d675599e30493e36c7f8be9c1d1409fa72)) +* executeValidator generic function, fixed tests ([1bd76a1](https://gitlab.com/macropeople/dcfrontend/commit/1bd76a1efeba60441fb8dca34e5bf4081426fd0f)) +* filtering datetime decimals cut, getcolvals types ([bf8d059](https://gitlab.com/macropeople/dcfrontend/commit/bf8d05942955a3743da81459f9000f60481ea825)) +* finally getting decimals to work both for time and timestamp to 5dp ([6062444](https://gitlab.com/macropeople/dcfrontend/commit/60624442b1fbf877de229709b1c9b67cf08e41b9)) +* format support for getddl service ([5f5a224](https://gitlab.com/macropeople/dcfrontend/commit/5f5a22402a38798e3ef80a00a86e629fd7044ef4)) +* format support in getrawdata service ([993e208](https://gitlab.com/macropeople/dcfrontend/commit/993e2084c0537d94b481be3b79f57d6040221546)) +* format-cat entry ([2c0ebf5](https://gitlab.com/macropeople/dcfrontend/commit/2c0ebf575cd18c2467e5a3944877974b51255e7e)) +* **formats:** adding formats to viewdata service (and fixing test issues) ([d3ea3f0](https://gitlab.com/macropeople/dcfrontend/commit/d3ea3f0cc0aa80d299eb1f9a8487e67242782340)) +* hot assert error appearing (blocking the app) ([c03b5fc](https://gitlab.com/macropeople/dcfrontend/commit/c03b5fc0cfcacbf4593954b73103a005a92a2b9a)) +* hot dynamic validation adding source requires adding cell editor of autocomplete ([263fe95](https://gitlab.com/macropeople/dcfrontend/commit/263fe95ecefb29010d0b6725af59de544abff226)) +* hot freeze issue (assertion error) ([c91aa0c](https://gitlab.com/macropeople/dcfrontend/commit/c91aa0c15fec121fc4dacbd8ad677dead10d0194)) +* hot height ([6c81769](https://gitlab.com/macropeople/dcfrontend/commit/6c81769d6af5886b2dd07379b188e545e4416e78)) +* hot, deploy abort modal refactor ([536e489](https://gitlab.com/macropeople/dcfrontend/commit/536e48905c4167e33afc561b1dc39c6c454b173b)) +* include decimal part for datetime and time variables ([9ff05ce](https://gitlab.com/macropeople/dcfrontend/commit/9ff05cecf5ad0d148b8cdf3cb6e4eb084b373917)) +* initialised variables fixes ([ad35a49](https://gitlab.com/macropeople/dcfrontend/commit/ad35a49029100626a087703d2f5892797903b000)) +* leading char support (and test) ([306bc42](https://gitlab.com/macropeople/dcfrontend/commit/306bc421643426fc5fdbe2faf1011084ca623241)) +* licensing abort modal refactor ([cd127d7](https://gitlab.com/macropeople/dcfrontend/commit/cd127d750b43695b9977f90e9ee0a10c33c46ca3)) +* licensing with multiple syssite ids ([cb31af0](https://gitlab.com/macropeople/dcfrontend/commit/cb31af0063074e968717ac337bef29102283f8f5)) +* macvar in buildinit and getting delete-folder script to work from local ([3280d8b](https://gitlab.com/macropeople/dcfrontend/commit/3280d8b0906ac7bb731fbb47769ad8405b08681c)) +* make Lato font bundled ([4f20403](https://gitlab.com/macropeople/dcfrontend/commit/4f20403f691cf3e79cbab30b74bb378d233cb0a5)) +* moving the checklock macros to the core library ([f332bd5](https://gitlab.com/macropeople/dcfrontend/commit/f332bd556ee6aa1e996e79507aab81ff275e78b0)) +* NodeJS issue ([5e282e8](https://gitlab.com/macropeople/dcfrontend/commit/5e282e86e3f771659f01793c527b259bbc133c55)) +* numeric validation length in bytes ([cd833e9](https://gitlab.com/macropeople/dcfrontend/commit/cd833e9ddf0dc355c34d99da509d66ac86841e55)) +* paths ([eb06998](https://gitlab.com/macropeople/dcfrontend/commit/eb0699829363085bf6f91f90d7e2412a9723e180)) +* postdata ([8d9d141](https://gitlab.com/macropeople/dcfrontend/commit/8d9d14171ba587111e9e8a37b16f21ef963d480b)) +* record modal: dc validator refactor implementation ([5e25805](https://gitlab.com/macropeople/dcfrontend/commit/5e25805ce05062ec9648af4594d1d40ff3899805)) +* refactoring retained key generation, migrating core component to sasjs/core library ([8a74311](https://gitlab.com/macropeople/dcfrontend/commit/8a74311aa22800e85e5c6aca9c8157aa3d073d80)) +* remove processed_dttm from result ([2117727](https://gitlab.com/macropeople/dcfrontend/commit/2117727ac9a8d3a7fc4b437047da6f7c090d9c62)) +* removing processed_dttm from validatefilter ([e848c3b](https://gitlab.com/macropeople/dcfrontend/commit/e848c3bf98ed6a3762bcce8153baa68d0c2488ff)) +* removing unnecessary colvals col, fixing unfiltered rawdata download, showing batch code on parallel approve abort ([b736861](https://gitlab.com/macropeople/dcfrontend/commit/b7368615b06beb9a29d25a10a9823bb48e07b3d8)) +* renaming hot into editor component ([43178e6](https://gitlab.com/macropeople/dcfrontend/commit/43178e66a7c09762b47c24f7a525308bf39f1499)) +* replacing Macro People with 4GL Apps ([c43225b](https://gitlab.com/macropeople/dcfrontend/commit/c43225b3f85d1993c106a601db8f06a8ec76f91e)) +* sas9 deploy work ([b822a14](https://gitlab.com/macropeople/dcfrontend/commit/b822a1458113fb59a2be4783f3b458875c1cad95)) +* sasjs bumps ([0194cca](https://gitlab.com/macropeople/dcfrontend/commit/0194cca61f35ad8aff534e73c709cb707e657581)) +* sasjsAbort refactor: viewer component ([290a5d0](https://gitlab.com/macropeople/dcfrontend/commit/290a5d0715cc15ff9990ba81bcb09c8a5f196560)) +* servertype SASJS ([60f733c](https://gitlab.com/macropeople/dcfrontend/commit/60f733cd7cd54bed17959222ed6f6343ab915b1f)) +* special missing support ([4e739ee](https://gitlab.com/macropeople/dcfrontend/commit/4e739ee2d72778689e842a0b931f35bff52a378a)) +* strict mode enablement ([f226fc2](https://gitlab.com/macropeople/dcfrontend/commit/f226fc23e884ca7e9dd80ca9d283de1098f7813a)) +* supporting fmt catalog in getcolvals ([92d6e8a](https://gitlab.com/macropeople/dcfrontend/commit/92d6e8afc7c12e6535b3372558ff72a05e40dfcb)) +* surrounded data with all empty cells ([e2b3a76](https://gitlab.com/macropeople/dcfrontend/commit/e2b3a76c3128d870e6858c1e475c0a1a7fd373a6)) +* terms abort modal refactor ([b7ae9f8](https://gitlab.com/macropeople/dcfrontend/commit/b7ae9f865a38c928471bfc5317a0599f4d879048)) +* test fixed, dc validator utils ([f163d75](https://gitlab.com/macropeople/dcfrontend/commit/f163d75864cde7baa91065ea013abf5c7e996470)) +* test setup for viewtables with format catalog ([4080459](https://gitlab.com/macropeople/dcfrontend/commit/4080459d707e8f7ca2503755e2d3839ae6137d65)) +* types fixing ([3cfcb2e](https://gitlab.com/macropeople/dcfrontend/commit/3cfcb2ecb07c21a077e1ff9d191235cf04771e82)) +* uninitialised variable ([65c1f51](https://gitlab.com/macropeople/dcfrontend/commit/65c1f51268be0cdaf593f1a0c429b8fc2333571c)) +* updates following strict mode ([94fa05d](https://gitlab.com/macropeople/dcfrontend/commit/94fa05d1b4dc8f8b0045035acb4b42d5456fca98)) +* updating analytium email addresses to data controller ([a2f2783](https://gitlab.com/macropeople/dcfrontend/commit/a2f27832f7d0369b0fa4de307988c2393634c87b)) +* updating tests, bumping core, new postedit process to check MPE_VALIDATIONS ([a7d49b8](https://gitlab.com/macropeople/dcfrontend/commit/a7d49b8996603af226873f475d33902ab9e047d9)) +* upgrading the filter process to work with mp_filtestore.sas ([354ecfa](https://gitlab.com/macropeople/dcfrontend/commit/354ecfa53e54d3ac1aaf0a10b0f221afad5c44fe)) +* validation hook append to cell source if any ([d2a22b6](https://gitlab.com/macropeople/dcfrontend/commit/d2a22b65b501ce222526e830a5279ecaca68ac53)) +* validations, undefined,null ([6fe5f73](https://gitlab.com/macropeople/dcfrontend/commit/6fe5f73889703829fa675be4ef52570cccda36ce)) +* validator - editor implementation ([782e6d0](https://gitlab.com/macropeople/dcfrontend/commit/782e6d0b4c9cde390d907d6318a11fe6d982a0b1)) +* validator check ([3fe5b32](https://gitlab.com/macropeople/dcfrontend/commit/3fe5b3269cab99e2d84827b0e1450bfb6a55b7cd)) +* **validator:** yury's suggestions ([eae158d](https://gitlab.com/macropeople/dcfrontend/commit/eae158d052255eaa683ceaee71969da9f8b27722)) +* versioning structure, moved to root ([e9da745](https://gitlab.com/macropeople/dcfrontend/commit/e9da745c9f32f4308230488e547343288c64949b)) +* viewer errors ([dd8b115](https://gitlab.com/macropeople/dcfrontend/commit/dd8b1151209dbf650b4c0eb38f307d4e5e41e67a)) +* viewer hot error in console ([e5775cf](https://gitlab.com/macropeople/dcfrontend/commit/e5775cfb37711a2684c267f660e5c96c8c71aff5)) +* wording ([caa372f](https://gitlab.com/macropeople/dcfrontend/commit/caa372f56763d76918b3d4e8153cffeb73dd14aa)) + +## [3.14.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.13.3...v3.14.0) (2021-12-08) + + +### Features + +* sasjs/server support ([63c9dd4](https://gitlab.com/macropeople/dcfrontend/commit/63c9dd45f497817d982b94f7f1ea2712fa820dd3)) + + +### Bug Fixes + +* changelog ([14b369a](https://gitlab.com/macropeople/dcfrontend/commit/14b369aa2e7ac3aee5d8b23e9721d434b287e54b)) +* licensing with multiple syssite ids ([cb31af0](https://gitlab.com/macropeople/dcfrontend/commit/cb31af0063074e968717ac337bef29102283f8f5)) +* moving the checklock macros to the core library ([f332bd5](https://gitlab.com/macropeople/dcfrontend/commit/f332bd556ee6aa1e996e79507aab81ff275e78b0)) +* paths ([eb06998](https://gitlab.com/macropeople/dcfrontend/commit/eb0699829363085bf6f91f90d7e2412a9723e180)) +* sas9 deploy work ([b822a14](https://gitlab.com/macropeople/dcfrontend/commit/b822a1458113fb59a2be4783f3b458875c1cad95)) +* servertype SASJS ([60f733c](https://gitlab.com/macropeople/dcfrontend/commit/60f733cd7cd54bed17959222ed6f6343ab915b1f)) +* versioning structure, moved to root ([e9da745](https://gitlab.com/macropeople/dcfrontend/commit/e9da745c9f32f4308230488e547343288c64949b)) + +### [3.13.3](https://gitlab.com/macropeople/dcfrontend/commit/compare/v3.13.2...v3.13.3) (2021-11-10) + +### Bug Fixes + +* adapter login error in console ([06b8842](https://gitlab.com/macropeople/dcfrontend/commit/06b884250953dccfec007a6ba2066a6d73685168)) +* adding comments in index.html, ensuring hard stop on table lock ([bebd9d5](https://gitlab.com/macropeople/dcfrontend/commit/bebd9d51c61afc4a34ef91cd1d980a81ea9dee01)) +* cell validation - arrows not appearing on render ([7e879b9](https://gitlab.com/macropeople/dcfrontend/commit/7e879b9e39de5a7f899dc2495a5da2d6471574ad)) +* cell validation - empty cell triggers forced values ([540297d](https://gitlab.com/macropeople/dcfrontend/commit/540297d16fd7f176a86112ef058d0cfbe6ec143a)) +* cell validation - force values are set on all rows ([1b0c31c](https://gitlab.com/macropeople/dcfrontend/commit/1b0c31ce08ae0427f65d6f646729a2a8de0c6048)) +* closes [#373](https://gitlab.analytium.co.uk//undefined/issues/373) ([209130d](https://gitlab.com/macropeople/dcfrontend/commit/209130db4c4330152ba6176fc79d562a4075b9d6)) +* display modal with sheet name where the data is found when doing excel upload ([351d511](https://gitlab.com/macropeople/dcfrontend/commit/351d5118d0d94680b39e0411bfa6390af7f52591)) +* duplicate *ALL* values removal ([fdc5b6f](https://gitlab.com/macropeople/dcfrontend/commit/fdc5b6f1a520fd3366ab38d6903b30cd9130f52d)) +* excel fail with missing first row ([e508a54](https://gitlab.com/macropeople/dcfrontend/commit/e508a543ea6ba0e76b7603e4a9b3358596ad8a19)) +* rejection reason not appearing in the email ([0476090](https://gitlab.com/macropeople/dcfrontend/commit/04760903836e87892d79caee3628c911ba787b86)) +* upload excel faster validation ([316551b](https://gitlab.com/macropeople/dcfrontend/commit/316551b2f800d1fbdd3f418d40ce2330ff1742eb)) +* upload validation speed up ([4277fef](https://gitlab.com/macropeople/dcfrontend/commit/4277fefeb4695ee7cbf5c588ceac654d5d32c9dc)) + +### [3.13.2](https://gitlab.com/macropeople/dcfrontend/compare/v3.13.1...v3.13.2) (2021-09-27) + + +### Features + +* licencing - multiple site_id values support ([8e98dd5](https://gitlab.com/macropeople/dcfrontend/commit/8e98dd58cdaa10fd6e11b499f16b80c4627c183b)) + + +### Bug Fixes + +* better UX when doing quick reject ([0e35427](https://gitlab.com/macropeople/dcfrontend/commit/0e35427a5f66de4aa98128470c1c0e28db4b0e9e)) +* deprecating mpe-getroot() ([a6bc6e7](https://gitlab.com/macropeople/dcfrontend/commit/a6bc6e7423d10b62a7512b787c3d3dcf7e3e580b)) +* excel empty numerics parsed incorectly ([0d0e3eb](https://gitlab.com/macropeople/dcfrontend/commit/0d0e3ebff6f88faaef502b881ae0176e3dc7b6d6)) +* invalid casting ([e086fb3](https://gitlab.com/macropeople/dcfrontend/commit/e086fb317ca4a094223402b46806a5d7ae418372)) +* switching to sasjs/core version of mp_getcols ([616fc80](https://gitlab.com/macropeople/dcfrontend/commit/616fc80c4dbd1c89efd0d48cce027edd53019ef3)) +* viewer - handsontable onDestroy of undefined error ([7832e0e](https://gitlab.com/macropeople/dcfrontend/commit/7832e0eb664c85df66b2580982a49d4c4aeec060)) + +### [3.13.1](https://gitlab.com/macropeople/dcfrontend/compare/v3.13.0...v3.13.1) (2021-09-06) + + +### Features + +* dynamic cell validation force value flag ([016377f](https://gitlab.com/macropeople/dcfrontend/commit/016377f4f2e34c3ad45850b0aee982b2c49ccd36)) +* enabling force flag at backend ([1d9ab78](https://gitlab.com/macropeople/dcfrontend/commit/1d9ab783ec30eaa815b5cf752463fbb6d3d814b3)) +* hot.batch() improvement, loading spinner on error stop and presenting exclamation mark ([66d6c6b](https://gitlab.com/macropeople/dcfrontend/commit/66d6c6bd6c92bbe49acc8d88dc2f222f3f4b9be3)) + + +### Bug Fixes + +* adding test trigger ([9391796](https://gitlab.com/macropeople/dcfrontend/commit/93917961412d1d9a81647ccf4745df6acd1c2f99)) +* enabling mp_include for error handling, and adding force flag on mpe_tables validation ([f1163e1](https://gitlab.com/macropeople/dcfrontend/commit/f1163e1fa7f34d94587c55dc306c86bc5039d0bc)) +* enabling native PG for key_seq incrementer ([f81505f](https://gitlab.com/macropeople/dcfrontend/commit/f81505faf934b125e4d46c493ee66af0d9183b83)) +* excel with additional columns issue ([b7d017d](https://gitlab.com/macropeople/dcfrontend/commit/b7d017dff02921abfb9e774652abf7bb0163225c)) +* filter message should be removed when excel is uploaded ([3350da9](https://gitlab.com/macropeople/dcfrontend/commit/3350da96b60216493c32eac84228145cc6f3239b)) +* filter RK bug ([b61c93d](https://gitlab.com/macropeople/dcfrontend/commit/b61c93d893fad5acc8b1f104dd2184a880e7a767)) +* handsontable instance warnings, improved singleton when calling hot ([faccc11](https://gitlab.com/macropeople/dcfrontend/commit/faccc11eb452cc1b5c2497e1ad6c274889cb9755)) +* more PG tests ([48836a0](https://gitlab.com/macropeople/dcfrontend/commit/48836a01ce3128131f1a01ff927cc021eb3669a4)) +* pg direct - working branch ([0d46dd9](https://gitlab.com/macropeople/dcfrontend/commit/0d46dd98387baada4347a5c0d698079524e97f16)) +* PG updates ([f41eefd](https://gitlab.com/macropeople/dcfrontend/commit/f41eefd8ea2615ad73510fa577274b22e4377e24)) +* timestamps for PG compatibility ([aa321c2](https://gitlab.com/macropeople/dcfrontend/commit/aa321c295f05c881ec75dc6c40413ceb208778d5)) +* using db compatible date system ([95a564c](https://gitlab.com/macropeople/dcfrontend/commit/95a564ce106142480f82321f201c6ae628e7fc1e)) +* when no changes on approval screen state as such ([55a24db](https://gitlab.com/macropeople/dcfrontend/commit/55a24dbf322f110d567792b1cd24e7c612d7f493)) + +## [3.13.0](https://gitlab.com/macropeople/dcfrontend/commit/compare/v3.12.0...v3.13.0) (2021-08-25) + + +### Features + +* backend for dynamic extended values, docs updated and tests written. Available on MPE_TABLES.DSN column ([10fe4ba](https://gitlab.com/macropeople/dcfrontend/commit/10fe4bae537adf76e524b228d466c9bbe9d8ed81)) +* date picker dropdown with values ([2be1ad7](https://gitlab.com/macropeople/dcfrontend/commit/2be1ad777254d69966b8b54b9b3abc719227a9c6)) +* dynamic cell validation loading spinner ([e415476](https://gitlab.com/macropeople/dcfrontend/commit/e4154762b0d75f25be4727b566e012c860fb61a9)) +* excel upload stater ([6aa35e1](https://gitlab.com/macropeople/dcfrontend/commit/6aa35e184e90b2d821031aea686f40e592e92f84)) +* logger service, displaying console log when debug is on ([35992e0](https://gitlab.com/macropeople/dcfrontend/commit/35992e08d9b2db1b2133d2c1e23ce08686a62cd1)) +* upload excel states and remaining time calculation ([7529d40](https://gitlab.com/macropeople/dcfrontend/commit/7529d408f0851318d099c5c438b02c76259713e7)) +* **in progress:** extended values cell validation ([e44dc9a](https://gitlab.com/macropeople/dcfrontend/commit/e44dc9a065dbaa534a38f4edf5f6e097c5cd9413)) +* row headers added ([55d5b24](https://gitlab.com/macropeople/dcfrontend/commit/55d5b24acb31c402c9d47499acff046c0605ba0f)) +* **k8s:** dockerized frontend app ([5c9176c](https://gitlab.com/macropeople/dcfrontend/commit/5c9176c137041a862986217711304ecb3a67b793)) +* **k8s:** set up k8s node with dcfront image ([b234b28](https://gitlab.com/macropeople/dcfrontend/commit/b234b283eeca353adb41aba2837539e3b1f75aa7)) +* **server:** enabled typeScript ([2ac724e](https://gitlab.com/macropeople/dcfrontend/commit/2ac724e3e57700b9e5f291ff934097fa6fb6bbb2)) +* **server:** initial commit ([8f2a0a5](https://gitlab.com/macropeople/dcfrontend/commit/8f2a0a5020b28866d2c35b3a8b22842dd3e89785)) +* added test case to test the validity of uploaded values in xls extension ([7f7909b](https://gitlab.com/macropeople/dcfrontend/commit/7f7909bb62213cfd58eed047d15a91552723e4c2)) +* adding datalist dropdown to time and date picker ([caaf5f9](https://gitlab.com/macropeople/dcfrontend/commit/caaf5f915228cd387b9711a0e9f2cd71d13c01ac)) + + +### Bug Fixes + +* adding demo key and fixing build process ([9298ef0](https://gitlab.com/macropeople/dcfrontend/commit/9298ef07f7ad038dcb9a0ed7d78dc8fe8a7a39bf)) +* agree checkbox flow, open table from tree stability, library to open in cypress json ([1a3dcf2](https://gitlab.com/macropeople/dcfrontend/commit/1a3dcf229861fa9252d58196a93f61d572fe441a)) +* backend updates ([1b3a61a](https://gitlab.com/macropeople/dcfrontend/commit/1b3a61ae1160b95044e8c3ccca1dcb5cbfab0f86)) +* batch script updates, adding mpe_users to mpe_tables ([b5659d4](https://gitlab.com/macropeople/dcfrontend/commit/b5659d47e22f62483921ba460a7b59a44d98cc07)) +* bumping core ([6034d12](https://gitlab.com/macropeople/dcfrontend/commit/6034d12a0c7d630015e3de34080cce07aea188b4)) +* buttons focus outline remove ([c0348e3](https://gitlab.com/macropeople/dcfrontend/commit/c0348e3c56abf4476e3683f3cf91900ddab4a10e)) +* created and implemented sheetInfo interface ([7408ad7](https://gitlab.com/macropeople/dcfrontend/commit/7408ad746cd83256ba20f496751f44d6fbe591db)) +* date picker datalist arrow overlap with calendar. On loading screen abort modal not visible ([f426536](https://gitlab.com/macropeople/dcfrontend/commit/f4265365dc9fbe8548fb28a1f1d648e6aba16106)) +* decoding licence key on http faling with invalid base64 ([5220cdb](https://gitlab.com/macropeople/dcfrontend/commit/5220cdb6d4d9ac86143454920b1d6eecb4d1a333)) +* der touristik issue with error on table due to DQ check ([641a15c](https://gitlab.com/macropeople/dcfrontend/commit/641a15c0f723bb19937e38dbe278de5f708c1dc1)) +* displaying the error message that comes in response from adapter ([43e5e31](https://gitlab.com/macropeople/dcfrontend/commit/43e5e31fdafa1c4cbb0af60c467407c147d5f1f5)) +* dynamic cell validation on numeric cells, numeric dropdown with sofselect issues ([4c8a68a](https://gitlab.com/macropeople/dcfrontend/commit/4c8a68aa5ede968435d47031b6d3f6e5c0731f52)) +* empty sheets triggering error (update range function) ([2caa513](https://gitlab.com/macropeople/dcfrontend/commit/2caa51354a8018d03297a4bb455ab1a5ff4bac6a)) +* enable support for backend rls checks ([0422c39](https://gitlab.com/macropeople/dcfrontend/commit/0422c39c1450b65c2c678d2305647165acf93db8)) +* enabling hook when submitting RLS and adding query object to VIEWdata response ([6023e8b](https://gitlab.com/macropeople/dcfrontend/commit/6023e8bf4e54feae68ad9c0312dd5ec43aea5084)) +* enabling post edit hook for mpe_validations to check each table query seperately ([3906316](https://gitlab.com/macropeople/dcfrontend/commit/3906316f805758d5daee38c356447c3a67fd4263)) +* excel finding data in file issue ([7d17685](https://gitlab.com/macropeople/dcfrontend/commit/7d17685e5c1eee35458d35e9979968778f072aa9)) +* excel tests fixing ([a27066e](https://gitlab.com/macropeople/dcfrontend/commit/a27066e2b0ac9ebde3bff7c57240b9885dd47b72)) +* excel upload with missing, duplicate and blank columns ([038b32f](https://gitlab.com/macropeople/dcfrontend/commit/038b32f6517cc5595a94fa664afffbaedd7ac340)) +* excel with missingg first row upload fail ([839f34a](https://gitlab.com/macropeople/dcfrontend/commit/839f34a70481f6b35e172392a52d3d43ef9addc6)) +* handle the string which contains apostrophe ([fdde83f](https://gitlab.com/macropeople/dcfrontend/commit/fdde83f51468bafce73d10203f2f19b00fc952ba)) +* hardselect_hook prevent invalid submit ([127ff70](https://gitlab.com/macropeople/dcfrontend/commit/127ff7056f92a4bac1117f319e79b1331b55a3f3)) +* history download context passed ([7fc3637](https://gitlab.com/macropeople/dcfrontend/commit/7fc36377d236537eb2aaa729cc3e39c5bda7da6c)) +* immediately remove approve list item after clicking on reject button ([5004988](https://gitlab.com/macropeople/dcfrontend/commit/5004988132b03b29403e1b56b65423a016c226c0)) +* incorrect group logic ([0be9e18](https://gitlab.com/macropeople/dcfrontend/commit/0be9e18b3395d8f6df1351d07e5167d90e7234f3)) +* issue with filters in different tables being combined ([51d3c98](https://gitlab.com/macropeople/dcfrontend/commit/51d3c98ca8dc065e16bfa4e645f54f28a3701fae)) +* lineage double request ([5a78a30](https://gitlab.com/macropeople/dcfrontend/commit/5a78a30dc8830ea81dc33ee90d3115513c13926c)) +* made some attributes optional ([9879633](https://gitlab.com/macropeople/dcfrontend/commit/9879633d67f84ab9c4943efa564453aeffb18580)) +* merge conflict ([957f4f6](https://gitlab.com/macropeople/dcfrontend/commit/957f4f635d5ef2de1980006987939c45f3835939)) +* message typo ([b231651](https://gitlab.com/macropeople/dcfrontend/commit/b23165171a728eec59c0c18c1225e1f17a7f1a57)) +* metadata aligment and loading spinner alignment ([385da0e](https://gitlab.com/macropeople/dcfrontend/commit/385da0e2df3964d2e51ab1a4beb711d1f697ec2e)) +* metadata object not sending request ([a616a42](https://gitlab.com/macropeople/dcfrontend/commit/a616a42e1dc3dc2e337c2db27e11ad7468e5a779)) +* metanav search issue ([e6a727a](https://gitlab.com/macropeople/dcfrontend/commit/e6a727a32e56fa7e08d9559b5bbf230f1713b4b9)) +* new clarity styling issues ([50c9a23](https://gitlab.com/macropeople/dcfrontend/commit/50c9a23e6464d381382b197fabae5d1830af088c)) +* nobs value incorrect in filtered view on VIEW table ([23fa2ce](https://gitlab.com/macropeople/dcfrontend/commit/23fa2ceaab050eb6e6a5503cc72d94d7762c9225)) +* non picker input dropdown not visible ([4de8726](https://gitlab.com/macropeople/dcfrontend/commit/4de8726c5f660b4763dee4f03f7dc471c40848b9)) +* not null validations not applied ([eccc28e](https://gitlab.com/macropeople/dcfrontend/commit/eccc28ee877d9c57294cb5d72a315fdfbfe51541)) +* numeric column freeze when put char value ([d2cebc5](https://gitlab.com/macropeople/dcfrontend/commit/d2cebc50b3ccbd04f0a609c9299b874f0f334a14)) +* pass debug parameter in upload file request when deug mode is enabled ([ab8ab28](https://gitlab.com/macropeople/dcfrontend/commit/ab8ab2844e2fc390bfdd2e35803627724cb3ed0e)) +* postgres compatibility ([700fa74](https://gitlab.com/macropeople/dcfrontend/commit/700fa74fe223b08de627569c8739406e92d7b6c2)) +* Primary key value lost when uploading excel file fixed ([0672a55](https://gitlab.com/macropeople/dcfrontend/commit/0672a556d59a9593b5109def961cae516dd1c2d8)) +* reproduce filter for viewer component ([6edb0aa](https://gitlab.com/macropeople/dcfrontend/commit/6edb0aa410aadc1fc067f7b49c58fa93df283e8f)) +* RLS lib assign ([6b274eb](https://gitlab.com/macropeople/dcfrontend/commit/6b274eb1f75c226ad8619bccd30ddb9cf4adb4d0)) +* sas fixes ([0f4a1bb](https://gitlab.com/macropeople/dcfrontend/commit/0f4a1bbbd99afd4fe769b796d0428c066801166e)) +* updates for PG compatibility and to improve logging in case of hard exit ([6f43756](https://gitlab.com/macropeople/dcfrontend/commit/6f437563b5f814e15f93b56ddf3d9d41b54640c5)) +* updating test and config to use correct context, also updating tests so that they actually run with the designated context ([96aadb1](https://gitlab.com/macropeople/dcfrontend/commit/96aadb1b056b44bbc3dcc0b82a0504a6b90840de)) +* validatefilter not handling sasjsAbort ([ee444bb](https://gitlab.com/macropeople/dcfrontend/commit/ee444bb11a566f9b3dee1ff91bb97017856d4a39)) +* restructured repository ([b0accc5](https://gitlab.com/macropeople/dcfrontend/commit/b0accc5509f8dd3946763c8b4fddbf3691c98fff)) +* restructured repository ([64530a6](https://gitlab.com/macropeople/dcfrontend/commit/64530a664780264b4b9264897d4c70d2efc54237)) +* **ci:** fixed merge request CI step ([687785c](https://gitlab.com/macropeople/dcfrontend/commit/687785cb09bc8c271705b4fc9daae90f5ec052f6)) +* **CI:** fixed gitlab-ci ([84bc6ba](https://gitlab.com/macropeople/dcfrontend/commit/84bc6ba9fa9508324ab5fc7eba2ad4fdf445c861)) +* **k8s:** fixed ingress service ([6a71df7](https://gitlab.com/macropeople/dcfrontend/commit/6a71df7c8a1602ff8972ebad905886707c552779)) +* timeout set globally ([79c0250](https://gitlab.com/macropeople/dcfrontend/commit/79c0250f06ab5fc2dfb3f290456cd266dc517729)) +* validation for numeric cells ([6b9dba5](https://gitlab.com/macropeople/dcfrontend/commit/6b9dba542d2ce2e94c4368cce665b351e26a332f)) +* when user open filter url show him filter clauses in filter dialog box ([b800672](https://gitlab.com/macropeople/dcfrontend/commit/b800672ad51a5443eca76cf86d468c5c0443be6a)) + +## [3.12.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.11.0...v3.12.0) (2021-05-11) + + +### Features + +* adding dynamic filter query to public/getcolvals service along with corresponding tests (and updates to test config) ([df86c39](https://gitlab.com/macropeople/dcfrontend/commit/df86c39aabf264236580c283a56e378a106dc6d6)) +* backend logic for formula validation ([7d17aca](https://gitlab.com/macropeople/dcfrontend/commit/7d17aca7b982749f42303d51ecdd9cb549e73e9b)) +* check for invalid clauses when adding new group clause ([085ede6](https://gitlab.com/macropeople/dcfrontend/commit/085ede69cb4056e598460150a0b5443398dedb94)) +* checkbox values moved in modal. fix: selecting IN operator before getValues is finished did not populate values. ([831f6b7](https://gitlab.com/macropeople/dcfrontend/commit/831f6b794e8f3477ff2c3e1b49845540dba8425c)) +* creating dynamic where clause string and passing ([2724383](https://gitlab.com/macropeople/dcfrontend/commit/272438366702a2ac7d333b0e6e9ae0a97c1f8e2a)) +* getdynamiccolvals service (and test) ([c5a8df8](https://gitlab.com/macropeople/dcfrontend/commit/c5a8df870a83d460840f220ce3a33c1fb55a22f4)) +* getdynamiccolvals v0 ([44be1de](https://gitlab.com/macropeople/dcfrontend/commit/44be1de57ceec597d14acc6e8e0a86c1f8d2f42f)) +* lineage depth level pick ([46e4601](https://gitlab.com/macropeople/dcfrontend/commit/46e4601a1c9eaaa907c60adf16cccb7a02bb30bd)) +* max depth lineage limit ([569a560](https://gitlab.com/macropeople/dcfrontend/commit/569a5606d8d743a1ba9ac19e388a960b0f320409)) +* mpe_filtermaster macro to handle all filter generation (and corresponding tests) ([ddf88f0](https://gitlab.com/macropeople/dcfrontend/commit/ddf88f027bf23d64857628b040fb1419ba9e8c19)) +* new validatefilter service (replaces whereclausevalidator) ([909ba02](https://gitlab.com/macropeople/dcfrontend/commit/909ba02b4288e2d4c3c266389ba6432fd3f85aac)) +* reset filter button, improved datalist elements ([bd42094](https://gitlab.com/macropeople/dcfrontend/commit/bd42094919550752c53927d95f5c855d851e131a)) +* Row Level Security (and test) ([5e0fe2f](https://gitlab.com/macropeople/dcfrontend/commit/5e0fe2f80223966a65e5878dbc250eefa61d995b)) +* where clause check on adding new ([82410d2](https://gitlab.com/macropeople/dcfrontend/commit/82410d2cd4e011406e3d866571f703fb01bf708c)) +* while uploding EXCEL parse formulas and formatted values ([5008010](https://gitlab.com/macropeople/dcfrontend/commit/500801042103480e034cd489d3a64d196a780432)) + + +### Bug Fixes + +* 0 rows on filter, no changes modal improved ([0318d86](https://gitlab.com/macropeople/dcfrontend/commit/0318d864459e1c46b3e2be919c48d7602cb77872)) +* add record edits newly added row ([91328ea](https://gitlab.com/macropeople/dcfrontend/commit/91328eab83e5000b8d2a7038de230b0cb16e3472)) +* adding default hook for mpe_security ([d282fd2](https://gitlab.com/macropeople/dcfrontend/commit/d282fd27a602b8576f5c7d63b6781c350a50d058)) +* adding header to getdynamiccolvals ([c8f054a](https://gitlab.com/macropeople/dcfrontend/commit/c8f054af26cdc90afdd3737b3ef2fe6470d23ee7)) +* adding outds so can send back to frontend ([6151391](https://gitlab.com/macropeople/dcfrontend/commit/6151391443293242c320e3b94181d5a107ed0934)) +* adding stub for service ([0a32bfe](https://gitlab.com/macropeople/dcfrontend/commit/0a32bfe6d380c392759412fb2b57b1c99b71abe9)) +* adding tests and new macro for fetching test response ([0fd4e35](https://gitlab.com/macropeople/dcfrontend/commit/0fd4e358f0323b0137e3f3ed36819b432992fa84)) +* app break on lineage error when debug off ([f4f1fae](https://gitlab.com/macropeople/dcfrontend/commit/f4f1faea56742f8236d3d4837ac09d185072054b)) +* appLoc check support for old adapter ([4d6fc29](https://gitlab.com/macropeople/dcfrontend/commit/4d6fc29a61cee1282286f40ce1874dcf6fd05da0)) +* appLoc check, with adapter function ([2fa0de9](https://gitlab.com/macropeople/dcfrontend/commit/2fa0de946cce7ba4288a1ab645cfb80ea1839d35)) +* approver list for *ALL* listings ([54a4fdf](https://gitlab.com/macropeople/dcfrontend/commit/54a4fdf388cebbe51e95ea2c60d8c605b3507145)) +* auto deploy close modal button ([3657ae1](https://gitlab.com/macropeople/dcfrontend/commit/3657ae1448ae954145cd6ee8a9bf08fb5d463454)) +* bumping adapter and closing [#305](https://gitlab.com/macropeople/dcfrontend/issues/305) ([2f3d49c](https://gitlab.com/macropeople/dcfrontend/commit/2f3d49cb529ca95a71bd4a58115edb586a98bb0b)) +* bumping sasjs/core ([3b0896d](https://gitlab.com/macropeople/dcfrontend/commit/3b0896d7be0ba403a8701a96bc6e662fa1f09947)) +* changes required by axios-adapter ([eac1bb5](https://gitlab.com/macropeople/dcfrontend/commit/eac1bb566d9927782ae372af51dd400657d347b0)) +* check to ensure table exists. Closes [#223](https://gitlab.com/macropeople/dcfrontend/issues/223) ([ee5b21a](https://gitlab.com/macropeople/dcfrontend/commit/ee5b21a2bd4ce1743ed550011577c06ac9041953)) +* conflicts: ([92d6b4d](https://gitlab.com/macropeople/dcfrontend/commit/92d6b4d0c772f1dda7e548fb69a4e58624542fbc)) +* datalist improving UX (show all values on click) ([99f298d](https://gitlab.com/macropeople/dcfrontend/commit/99f298d5abd3243c6b0070f8bb3c1ba95f52eb48)) +* dependencies ([42f23d4](https://gitlab.com/macropeople/dcfrontend/commit/42f23d43691fa7e41f64e9d87dd50695934d8256)) +* deploy page ([0c1c312](https://gitlab.com/macropeople/dcfrontend/commit/0c1c312ce7c205d468909d736bea0a1cb49842e2)) +* double click opens empty dropdown ([c751295](https://gitlab.com/macropeople/dcfrontend/commit/c75129559fb26f94dc4f86b5f5781844f335f50f)) +* download audit file error ([8a92657](https://gitlab.com/macropeople/dcfrontend/commit/8a9265779481a8955185e564c57297243366c8e7)) +* dynamic filtering is true by default ([47d6c37](https://gitlab.com/macropeople/dcfrontend/commit/47d6c37127439bd21def7415073893bb0a98eabc)) +* dynamic where clause was sending null values ([aad3d94](https://gitlab.com/macropeople/dcfrontend/commit/aad3d948895d89905e80d1d8a3751d8f551a70fb)) +* editor breaks if submit service fails ([eef29ba](https://gitlab.com/macropeople/dcfrontend/commit/eef29ba679cfe0b67f5a58216f6d6fb2fc38a97c)) +* editor reset filter not working ([9b2e5a9](https://gitlab.com/macropeople/dcfrontend/commit/9b2e5a9b4f7c44b9fc04a96d5376fc22c896f9fe)) +* enabling excel export for non PC files sites, also updating tests ([35a36e7](https://gitlab.com/macropeople/dcfrontend/commit/35a36e705c17b5978884c53912d4a673400bf670)) +* enabling filtering for getdata service, plus a test, plus fixes to make the test work ([69c6dde](https://gitlab.com/macropeople/dcfrontend/commit/69c6dde4322e096c12cc312a3e3a1e4d5bb889ca)) +* enabling uploads in excel for non admins with *ALL* security settings ([46a083a](https://gitlab.com/macropeople/dcfrontend/commit/46a083a9e6453873933e57118fe6e3bfc66ee3b6)) +* ensuring selectbox order is honoured. closes [#283](https://gitlab.com/macropeople/dcfrontend/issues/283) ([124c1d3](https://gitlab.com/macropeople/dcfrontend/commit/124c1d3d9372dc37f7fcae0e375577eedd77f942)) +* error on compilation ([574d1ca](https://gitlab.com/macropeople/dcfrontend/commit/574d1ca615458f8447ee0d9c76c63f145f7def6c)) +* extending viz memory, added rendering spinner, added download png and svg buttons in the modal ([d6f674f](https://gitlab.com/macropeople/dcfrontend/commit/d6f674f56e1342c7069194b40a22a2df6261f9bc)) +* filter text removeal ([08bcc4a](https://gitlab.com/macropeople/dcfrontend/commit/08bcc4a858dff402dd49ee8714f1f1b0bf341a73)) +* filter_pk numeric ([e5a7728](https://gitlab.com/macropeople/dcfrontend/commit/e5a77288be0077355449d7dd520a7c4aea42d2d3)) +* filter_pk numeric ([f0a1d7b](https://gitlab.com/macropeople/dcfrontend/commit/f0a1d7bec28f9b2847640d129a770eca4362ffa2)) +* filtering datetime wrong time on some months ([00c2d4e](https://gitlab.com/macropeople/dcfrontend/commit/00c2d4ea92afadb9ab47cf1d2c9de82827fed0b8)) +* filterquery for numeric and string ([29d4967](https://gitlab.com/macropeople/dcfrontend/commit/29d49679b668d1d41968a9d1fc3fdc172112415f)) +* filterTable params fixed for getColVal request ([f6b43e2](https://gitlab.com/macropeople/dcfrontend/commit/f6b43e20b1b2792968d4c661a35be2018f25e151)) +* fixing dates on fronted. REquires an adapter update. ([544124b](https://gitlab.com/macropeople/dcfrontend/commit/544124b3914939b603ddab97b709adb8c187ce45)) +* getcolvals breaking filtering ([086cd64](https://gitlab.com/macropeople/dcfrontend/commit/086cd64bdb8b985317ae5c40cdfa95d2161c7e59)) +* getting tests to (finally) work ([caeea9a](https://gitlab.com/macropeople/dcfrontend/commit/caeea9a72e7400d8a6ae6ce4b6bbb0666f968193)) +* getting viewdata to work ([d78cfa5](https://gitlab.com/macropeople/dcfrontend/commit/d78cfa56cbcc363eb1ba35c6bfd38080d3141126)) +* http key support ([a166665](https://gitlab.com/macropeople/dcfrontend/commit/a1666658ceabe5c2094f1b33f86034ca445ebafc)) +* I ran npm run format:fix ([7c5814f](https://gitlab.com/macropeople/dcfrontend/commit/7c5814fd729f04acc78d77c217e06611832552e8)) +* improved progress bar, passing dynamic clause object to server ([c0a37a4](https://gitlab.com/macropeople/dcfrontend/commit/c0a37a4b8941fc5253d2462766c8be053febd6b0)) +* large lineage handling improved UX ([316af47](https://gitlab.com/macropeople/dcfrontend/commit/316af476580a774538615bdb318a30310efec187)) +* last minute fixes ([4399118](https://gitlab.com/macropeople/dcfrontend/commit/4399118d92941baf92de32c852c3a8ec6ab1e54c)) +* last minute updates ([d58dc0a](https://gitlab.com/macropeople/dcfrontend/commit/d58dc0a3fe061be53163cd4a521a4d72ee8ebe8d)) +* line length ([15e596a](https://gitlab.com/macropeople/dcfrontend/commit/15e596a1cd009d807d82ab9890bd7e7e506555b0)) +* lineage not rendering issue ([ba932f4](https://gitlab.com/macropeople/dcfrontend/commit/ba932f4c43fd6c3762e773143e2060eda6b4e867)) +* lint fixes ([fa6fbcc](https://gitlab.com/macropeople/dcfrontend/commit/fa6fbcc3bd45b504f8242a3b8924d5d32f7f456e)) +* max_depth ([b90efe0](https://gitlab.com/macropeople/dcfrontend/commit/b90efe01b5ffa5d5761d01a1f5839f9cabd0cdfd)) +* merge ([3f4db37](https://gitlab.com/macropeople/dcfrontend/commit/3f4db379b5c3ada8a29a8221ea810e56f2299cc7)) +* merged cells excel upload fails ([df5e6d7](https://gitlab.com/macropeople/dcfrontend/commit/df5e6d7848e1864554bdc98daf6d9215f2caa40d)) +* migration DDL ([63b7dd9](https://gitlab.com/macropeople/dcfrontend/commit/63b7dd988a61467b359eb285ce4e9976a5c2c2e5)) +* minval validation broken ([ce1db82](https://gitlab.com/macropeople/dcfrontend/commit/ce1db828662185e2c58410d3c5f45eae84f9a154)) +* missing changes and improvements ([d463d32](https://gitlab.com/macropeople/dcfrontend/commit/d463d32e18da4093e55ed64c4fedba40eca02b9e)) +* more debugging, closes [#282](https://gitlab.com/macropeople/dcfrontend/issues/282) ([eb26f89](https://gitlab.com/macropeople/dcfrontend/commit/eb26f89e045d676dca5c1868dc491685e0289b4a)) +* moving meta_mapper into designated folder, so it can now be overridden by the end user ([595f08d](https://gitlab.com/macropeople/dcfrontend/commit/595f08dc9490d5424c60e2d2ae053d523cc8265d)) +* moving tests into same folders as services ([19ada72](https://gitlab.com/macropeople/dcfrontend/commit/19ada72845725722266827beff872e1c24aed62e)) +* mpe_config issues ([315ed39](https://gitlab.com/macropeople/dcfrontend/commit/315ed39fb7d751c800ecc8436d079bd34a0e99ae)) +* mpeinit ([b541f58](https://gitlab.com/macropeople/dcfrontend/commit/b541f58788925c772be79f5888e0caff0070c26a)) +* mpeinit failure on sas 9 configurator ([9ace8e1](https://gitlab.com/macropeople/dcfrontend/commit/9ace8e172ff8059cf3ec0e64a8b3233276e21c96)) +* one clause in group subgroup logic is undefined ([7cca83b](https://gitlab.com/macropeople/dcfrontend/commit/7cca83b2d0c02231aa4c22721592f061b5a1f6d4)) +* ran npm run format:fix ([eda5785](https://gitlab.com/macropeople/dcfrontend/commit/eda578585fa174c529a8c866e8e112126478b22b)) +* reducing rowcount to 100 for performance, also updating sasjs doc ([a612d33](https://gitlab.com/macropeople/dcfrontend/commit/a612d33c31c022dac6b8e9b1e334fe9b77313e47)) +* removed services from appLoc ([4d390df](https://gitlab.com/macropeople/dcfrontend/commit/4d390df35a2b771acc7c7fc5b8b3d1276e8d421f)) +* removing FILTER_JSON ([4e7b549](https://gitlab.com/macropeople/dcfrontend/commit/4e7b549b3a9f45b52eb7e0da911da8e35fdf44c1)) +* removing nested macro ([2641e41](https://gitlab.com/macropeople/dcfrontend/commit/2641e415eab27ac1c1cd33004aea856538021ba2)) +* removing nested macros ([70f25d2](https://gitlab.com/macropeople/dcfrontend/commit/70f25d217ca3dcb12b4f4422284451e7127d8086)) +* replaced NOT EQUAL with NE ([696348a](https://gitlab.com/macropeople/dcfrontend/commit/696348aadd5e48d1bf08aeee2a5cbe9d9aba2e54)) +* RLS hook, max-depth, mor eRLS values ([d2e9fa3](https://gitlab.com/macropeople/dcfrontend/commit/d2e9fa3552e409fb2cc48401a6f4eb013c5e3d4a)) +* sanitising inputs ([04855b9](https://gitlab.com/macropeople/dcfrontend/commit/04855b925ce64c2c84e6434b05be5a22a741b378)) +* sasjs/core bump ([2b57031](https://gitlab.com/macropeople/dcfrontend/commit/2b570317f00573e24ec679d54e2b2d21bb37db0d)) +* shortening token ([49f17e7](https://gitlab.com/macropeople/dcfrontend/commit/49f17e755c32ed01531f9953ad73d9c2c2e15d12)) +* small performance tweak in filtering ([672d51c](https://gitlab.com/macropeople/dcfrontend/commit/672d51c3da0db809b5712e7fb67b41e718ed181b)) +* soft select in edit modal is working now ([98fa2d9](https://gitlab.com/macropeople/dcfrontend/commit/98fa2d9b84fc1e844a1521fdc8cb348f51eeaef8)) +* sql update for history ([e1a3511](https://gitlab.com/macropeople/dcfrontend/commit/e1a3511a8768195f666254225e23965f1984a5af)) +* styling issues ([720adb2](https://gitlab.com/macropeople/dcfrontend/commit/720adb222cdcf07cedb640d97bb534d2252b1a89)) +* table max depth ([352e2c0](https://gitlab.com/macropeople/dcfrontend/commit/352e2c0ac8635cbc52fedd3ac3aa954ed766c95f)) +* table on click scroll into view ([87f72be](https://gitlab.com/macropeople/dcfrontend/commit/87f72beba9d345c1635769695c466af1a209e363)) +* test (and fix) for etlsource, upcasing returned cols & tables ([77ddff5](https://gitlab.com/macropeople/dcfrontend/commit/77ddff51cd07bed962d39de9748728401933e7aa)) +* tests ([8c0eb1b](https://gitlab.com/macropeople/dcfrontend/commit/8c0eb1b1c6f1f2464c4f4cca3b9d18cae80ef917)) +* tests and extra validations routines ([3dbfad8](https://gitlab.com/macropeople/dcfrontend/commit/3dbfad84a9b249b536d2041b4ee1863a412f8c9e)) +* tidy up sasjsconfig.json ([4ed469b](https://gitlab.com/macropeople/dcfrontend/commit/4ed469b3ea9edadf04ca2b70eaf29b5ddf0dfeae)) +* tree on generating graph scrolls to top ([ccaac6f](https://gitlab.com/macropeople/dcfrontend/commit/ccaac6f8a60b8968d5c05396b823b5af6deb3b1a)) +* typo and fixes ([b258426](https://gitlab.com/macropeople/dcfrontend/commit/b2584266de6eb2b96a8cc61b4927e1811c64a75c)) +* uknown error to SAS Service Error ([564e893](https://gitlab.com/macropeople/dcfrontend/commit/564e8934388ba135acc89417a7a1ac31798dd852)) +* updated upload excel with formula test to check parsed values ([db58aa0](https://gitlab.com/macropeople/dcfrontend/commit/db58aa085dee3a616f4e1015868fbb5bf9a9be3c)) +* updates for viya testing ([637c1e1](https://gitlab.com/macropeople/dcfrontend/commit/637c1e16390e8c72bce9bd6d907e70b7e8366f02)) +* updates to make sasjs lint work ([fc5fe54](https://gitlab.com/macropeople/dcfrontend/commit/fc5fe54a9ac8c4716d4a4ceb58dd583918ae47ac)) +* updating dc tests for SAS 9 with macro ([f42012f](https://gitlab.com/macropeople/dcfrontend/commit/f42012f4d368b8043e227ca25fdcb3032bc58887)) +* url issues in deployment ([f6f933d](https://gitlab.com/macropeople/dcfrontend/commit/f6f933dbc6e465963474accbcc49cadfd83ce70f)) +* viya users limit ([d6961f4](https://gitlab.com/macropeople/dcfrontend/commit/d6961f415b0826be75dd77999459583da320419e)) +* warning on large dot files, hot dropdown style fix ([eb17798](https://gitlab.com/macropeople/dcfrontend/commit/eb177984387368af1d2454f20b73a6720e3cc040)) + +## [3.11.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.10.0...v3.11.0) (2021-02-14) + + +### Features + +* Adding DC_LOCALE option - will override locale when set to anything other than SYSTEM. Closes [#237](https://gitlab.com/macropeople/dcfrontend/issues/237) ([419f022](https://gitlab.com/macropeople/dcfrontend/commit/419f022fd13e466058d2de017e85a8a9205400e1)) +* dragging file over table opens drop dialog ([9d8ecc8](https://gitlab.com/macropeople/dcfrontend/commit/9d8ecc8a87ed5367c1cabc28b3d7c1e5a5ed66f7)) +* enabling column level lineage to 'pass through' proc transpose ([66c911e](https://gitlab.com/macropeople/dcfrontend/commit/66c911ea96e97f573d2834bdb2a65755e65a145c)) +* enabling native REDSHIFT access with incremental loads ([1532305](https://gitlab.com/macropeople/dcfrontend/commit/15323052086b13b2a57dd4e0b43bfe76ac47ff03)) +* extra validations for MPE_TABLES cols (upcase for VAR_TXFROM, VAR_TXTO, VAR_BUSFROM, VAR_BUSTO and VAR_PROCESSED) ([5cd3434](https://gitlab.com/macropeople/dcfrontend/commit/5cd34345ecc992ea3401d1f590837b3fa9c9ec46)) +* rows number thousand separator (space) ([3644f35](https://gitlab.com/macropeople/dcfrontend/commit/3644f3502f92b87d91fc0b1f3b4c1a3758247ff9)) +* **licensing:** 2 more tests added for no of users reached/exceeded ([d615eea](https://gitlab.com/macropeople/dcfrontend/commit/d615eea5f2683b6384537cc164d33c9fda941197)) +* **licensing:** activation logic added, refactor of terms agreement, license events interconnected ([89f20ae](https://gitlab.com/macropeople/dcfrontend/commit/89f20ae9bc115f721d92828e0d386dc162a8d6bc)) +* **licensing:** added site_id check, added more error handling for decrypt function ([c54074c](https://gitlab.com/macropeople/dcfrontend/commit/c54074c5330e6fe720b68ddb21db2c0296857792)) +* **licensing:** fixes ([acbc326](https://gitlab.com/macropeople/dcfrontend/commit/acbc3269aa9b3f4554c22509f1d6e0a69ec9f366)) +* **licensing:** fixes ([eea2c96](https://gitlab.com/macropeople/dcfrontend/commit/eea2c96204a6232581eba6d44ff3da1987b3ea9a)) +* **licensing:** licensing/update path to update the license key, when app is activated ([7145150](https://gitlab.com/macropeople/dcfrontend/commit/71451505f7d8509e9cd174fd6168621bb726b944)) +* **licensing:** register key function ([ccf8e50](https://gitlab.com/macropeople/dcfrontend/commit/ccf8e50ba169851e15e1aef3527ebff27b97b6cc)) +* added colored logs in console for matching errors with tests ([2e55a59](https://gitlab.com/macropeople/dcfrontend/commit/2e55a59dde805c5b8eb173af052dc0d20d7e33d2)) +* admin/registerkey service. Expects an input table called keyupload, with 2 variables - activation_key and licence_key ([3bad92f](https://gitlab.com/macropeople/dcfrontend/commit/3bad92fdf7a5dca3111ca77a701ccfdb5a3c0319)) +* auto deploy improvements ([d290a96](https://gitlab.com/macropeople/dcfrontend/commit/d290a962cd03c70d1efbd69a5dbf5fb2a03aebe3)) +* backend service registration code@ ([e1c7ac8](https://gitlab.com/macropeople/dcfrontend/commit/e1c7ac86165080da4097ea40fffebdb0c3910518)) +* creating context for auto deploy ([6811828](https://gitlab.com/macropeople/dcfrontend/commit/6811828e9b12af2923a79822d701184e142ac8a4)) +* cypress UI testing, started ([8ef54c4](https://gitlab.com/macropeople/dcfrontend/commit/8ef54c43e570bea355c4f84bbc346dc328826ebb)) +* deploying services as part of CI ([e981ec0](https://gitlab.com/macropeople/dcfrontend/commit/e981ec04aaa4ac998eb1c207da5e20e9ff3dcbb5)) +* excel file discard button and UX fixes ([91f4dc3](https://gitlab.com/macropeople/dcfrontend/commit/91f4dc3c2551e35b73342ab685c2b14dafb0681d)) +* handling the service not found error ([402e4ec](https://gitlab.com/macropeople/dcfrontend/commit/402e4ec1bc950f795a1c8251c973b85d07461580)) +* licensing and user registration ([0f9e114](https://gitlab.com/macropeople/dcfrontend/commit/0f9e114080e4f5e09487f4144f24cbafc05df1b3)) +* licensing proof of concept ([80a7ebe](https://gitlab.com/macropeople/dcfrontend/commit/80a7ebe3acc9241b53c42fd3c640585b1061abe5)) +* push on dfevelopment deploy SAS services ([6815ab8](https://gitlab.com/macropeople/dcfrontend/commit/6815ab8961615ef5263ebbc200d84b354433f856)) +* regular excel upload test ([a07c739](https://gitlab.com/macropeople/dcfrontend/commit/a07c7395e2aded774632dd55f0f8a3c40e88b488)) +* requests modal on autodeploy ([62bc1bd](https://gitlab.com/macropeople/dcfrontend/commit/62bc1bd9d8304e74d3bc9cf03f747cbbab907082)) +* updating context with makedata response ([cf9109a](https://gitlab.com/macropeople/dcfrontend/commit/cf9109a0a3f2e6062f28aa858f4ac8b6f3873d67)) +* user registartion. Fixed demo expiry on production issue. Added evaluation agreement. ([a42fcc1](https://gitlab.com/macropeople/dcfrontend/commit/a42fcc15035f74861fa777603734e0ccdca40be7)) + + +### Bug Fixes + +* `trim` error when chaning values in filter while variable not set ([a8019ce](https://gitlab.com/macropeople/dcfrontend/commit/a8019cee5f957573b54932c5d926af6f8006ab5c)) +* abortModal not working, hashing disabled (it was bloating the server), testing fixes ([9f7aa8f](https://gitlab.com/macropeople/dcfrontend/commit/9f7aa8fb84fba86be174df62f5140257bf03a648)) +* activation key in startup service ([4fe5d53](https://gitlab.com/macropeople/dcfrontend/commit/4fe5d53ac8e821657fdb0efd1c757c9480eec3e6)) +* add dependency@ ([5127159](https://gitlab.com/macropeople/dcfrontend/commit/51271596bb9de8fe449091647533607982e4d031)) +* added contextname to viewer download ([f1d9c35](https://gitlab.com/macropeople/dcfrontend/commit/f1d9c35925c30b3bec773df19a1161b670c21fcf)) +* adding editors to history, closes ([c464ee8](https://gitlab.com/macropeople/dcfrontend/commit/c464ee86d0581ada4ae0f11a85ff413dacef9d04)), closes [#233](https://gitlab.com/macropeople/dcfrontend/issues/233) +* adding engine ([0309dfa](https://gitlab.com/macropeople/dcfrontend/commit/0309dfa63c377d8f9e7602f1dcbb83a4424df70f)) +* adding licencekey to startupservice ([83b21c9](https://gitlab.com/macropeople/dcfrontend/commit/83b21c93d7fdcf44966c4f67364a5994bd678e7d)) +* adding reason message to emails ([48dfb43](https://gitlab.com/macropeople/dcfrontend/commit/48dfb4370dfdbbab3dfd9e903cf99d8b4b7cea0c)) +* alignemnt button not applying changes ([af7cbda](https://gitlab.com/macropeople/dcfrontend/commit/af7cbda41bff4e9564c466a5b73478dbd6e8a38d)) +* app crashes if activationkey is invalid string ([e1dacd8](https://gitlab.com/macropeople/dcfrontend/commit/e1dacd81d3ac4edbe8d1c796bb8165654cc54dd2)) +* appLoc check before running startupservice ([802b178](https://gitlab.com/macropeople/dcfrontend/commit/802b17893e36e228210199d9229b8b65a9f25884)) +* approver name ([8b79eee](https://gitlab.com/macropeople/dcfrontend/commit/8b79eeee1c235cdf93cb6dbc1eeb65eaada1c2e6)) +* bitemporal loader error (causing lock to be left behind) ([8a53226](https://gitlab.com/macropeople/dcfrontend/commit/8a53226dadd273b7ba9620ac2f03c00c76f1264c)) +* bump sasjs/core ([4d76965](https://gitlab.com/macropeople/dcfrontend/commit/4d76965ea0126d5701fe6a5d5afd3ce8940d4cc6)) +* cannot change column width while filtering ([7672561](https://gitlab.com/macropeople/dcfrontend/commit/767256128d3e7c2441741d749d401956459e2b11)) +* catchphrase fixed ([c5af7a5](https://gitlab.com/macropeople/dcfrontend/commit/c5af7a505331c65128a4b98f87372f9c3039f357)) +* checks for approval, closes [#234](https://gitlab.com/macropeople/dcfrontend/issues/234) ([4f995ff](https://gitlab.com/macropeople/dcfrontend/commit/4f995ffcfc9700add88ac9ac787b37eb9ed1d702)) +* CI script updated to work with newest CLI ([f336ee6](https://gitlab.com/macropeople/dcfrontend/commit/f336ee6c22a93930c509c9c0bb829d1282f9870e)) +* cli v2 ci script, refresh viewer table, autofocus tree search for libraries, apply keys redirection wrong ([049e872](https://gitlab.com/macropeople/dcfrontend/commit/049e87214beb559c5deadb25669fc34ca7237922)) +* col names, debugging, and ddl file ([5876d22](https://gitlab.com/macropeople/dcfrontend/commit/5876d22348b1b8ff3d3e344b85f25aee9c3dd811)) +* config ([08d6be5](https://gitlab.com/macropeople/dcfrontend/commit/08d6be53ac7d900b2ae08bc084b75c2bbf393a2e)) +* config update ([b2e5e01](https://gitlab.com/macropeople/dcfrontend/commit/b2e5e01eabc898056d659eb683fa2820b940eda5)) +* converting uploaded data to correct types ([ce7b6d7](https://gitlab.com/macropeople/dcfrontend/commit/ce7b6d7cd2c3e67c70d772f1e69891f7961fd992)) +* copying primary key field with dragging ([7105a7a](https://gitlab.com/macropeople/dcfrontend/commit/7105a7a0b4b86072466696a50f7f5e3f3d9b4a1d)) +* cypress new clarity and angular elements getter fix ([15540db](https://gitlab.com/macropeople/dcfrontend/commit/15540dbba1c8059c483857722c66fd11517945b1)) +* ddtype field for [#231](https://gitlab.com/macropeople/dcfrontend/issues/231) ([90ae7f5](https://gitlab.com/macropeople/dcfrontend/commit/90ae7f5c4abaae55f90257d7f14698fcdea114f9)) +* ddtype, [#231](https://gitlab.com/macropeople/dcfrontend/issues/231) ([c4d32b8](https://gitlab.com/macropeople/dcfrontend/commit/c4d32b8059abe89c8f35815fc90d1aa6c12ab8df)) +* delete this record ordering ([cacbf46](https://gitlab.com/macropeople/dcfrontend/commit/cacbf4612908bf06d490adc05d971f3bb2fcaf5e)) +* deploy db recreate checkbox and UI fixes ([fd6a13a](https://gitlab.com/macropeople/dcfrontend/commit/fd6a13a6e837315beed789155322a0451806a881)) +* deploy error handling improved ([e681d9a](https://gitlab.com/macropeople/dcfrontend/commit/e681d9a82b138fcfd8ad2478955ebcf8266ae3c0)) +* deploy makedata use original web approach ([dff12bd](https://gitlab.com/macropeople/dcfrontend/commit/dff12bda82ddd37a331245600c978c0605445d6c)) +* deploy testing and key generator ([9a0ce35](https://gitlab.com/macropeople/dcfrontend/commit/9a0ce355edc6b2a50f8e39a84f01d78977f81efb)) +* disable accept/reject buttons if user is not approver ([8971999](https://gitlab.com/macropeople/dcfrontend/commit/8971999f5c9a788b588a65b606c216385f213127)) +* disable deploy button if json file not present ([a93736a](https://gitlab.com/macropeople/dcfrontend/commit/a93736a15cca6507a7a0f726ebc51e3e4e8f536c)) +* duplicate keys, removing duplicated indexes ([3c2dccf](https://gitlab.com/macropeople/dcfrontend/commit/3c2dccf4d9283bb19bb83845f003a7b5f5e53e98)) +* duplicate primary keys modal improvements ([a68e2d6](https://gitlab.com/macropeople/dcfrontend/commit/a68e2d6334657367c2d75c9e9de18c7a3bfb3226)) +* empty object error ([ec90456](https://gitlab.com/macropeople/dcfrontend/commit/ec90456859ce432e775eb83bab2acdc6eb4bae38)) +* empty table in EDIT menu not shown ([b2ca2c6](https://gitlab.com/macropeople/dcfrontend/commit/b2ca2c6b09f45a6fc2b88c4e0da5cd5080df2344)) +* empty table upload ([4a5204e](https://gitlab.com/macropeople/dcfrontend/commit/4a5204ee0f807e6607286820e11ee436c2403a0b)) +* error message when no root folder available ([e3ec4f9](https://gitlab.com/macropeople/dcfrontend/commit/e3ec4f99eed8ae6569cb8967750d79bc239b48a3)) +* error when createing data dictionary in viya ([6deb93d](https://gitlab.com/macropeople/dcfrontend/commit/6deb93d2faa5db2f9458d1066d60da3cba2ec400)) +* excel time exponential value ([4b16c93](https://gitlab.com/macropeople/dcfrontend/commit/4b16c937305beef553b8bb7269590ed64d9d10ce)) +* excel upload with no data rows (js error was triggered, uncaught) ([cdc8784](https://gitlab.com/macropeople/dcfrontend/commit/cdc8784d1886562caa112cec6d2df106bfc7e737)) +* exist typo ([2b13d75](https://gitlab.com/macropeople/dcfrontend/commit/2b13d75022c1d402600d8b39888fdf1f4c5adca6)) +* extended test on both viya and v9. CI separated viya and v9 test jobs ([d41ff50](https://gitlab.com/macropeople/dcfrontend/commit/d41ff508a7d69b2fa5f59a845293a2a4dd52750e)) +* filter operators not in sync with selected variable ([9e714ab](https://gitlab.com/macropeople/dcfrontend/commit/9e714abc1c9bd1f75f31bc17f9ac77d3d389ada6)) +* filtering modal datepicker (in progress) ([3f1b4a2](https://gitlab.com/macropeople/dcfrontend/commit/3f1b4a25bf9d95035073fd91df552f09ed34ad93)) +* handling of getdata error in response from SAS. Fixed abort modal style. ([e4c8cc6](https://gitlab.com/macropeople/dcfrontend/commit/e4c8cc647886c1609ae88a1b48a1eae8d3fe9b0e)) +* handling trailing slash in dcPath ([8808227](https://gitlab.com/macropeople/dcfrontend/commit/880822744407e0a52b690bee28d3d2188017ab5a)) +* hans-jeurgen processed issue ([2f4e5da](https://gitlab.com/macropeople/dcfrontend/commit/2f4e5da9b5f1df08b71813a6664b562883cb2a04)) +* hot dropdown has no arrow ([b9ead6a](https://gitlab.com/macropeople/dcfrontend/commit/b9ead6af4502a5158f363cf6b23a46db5a82a211)) +* if logged out in filter view, cannot log in ([4d682d3](https://gitlab.com/macropeople/dcfrontend/commit/4d682d38f2f2c2cee18d70976c08b9db9142228c)) +* improved upload and submit UX ([e6156dc](https://gitlab.com/macropeople/dcfrontend/commit/e6156dc55bb58bb56c0b84338267d827f6fd0f29)) +* improved UX, search dropdown of variable ([7a7504b](https://gitlab.com/macropeople/dcfrontend/commit/7a7504bac030f208111f76255eac3a27dc7cef8c)) +* keep list ([1527248](https://gitlab.com/macropeople/dcfrontend/commit/1527248167bdb110bbf9f848590972d71fab0250)) +* layout issue, in/not in filter checking errors ([d68b342](https://gitlab.com/macropeople/dcfrontend/commit/d68b342fcba3d89c15ff431339f6901e01823319)) +* length ([48dfd3f](https://gitlab.com/macropeople/dcfrontend/commit/48dfd3f86c63b18e58fb12e6a6c1b00e063c3732)) +* length issue ([37c39cf](https://gitlab.com/macropeople/dcfrontend/commit/37c39cf99c9e82058bcf3d2e37bb8bc5ed6040ad)) +* lineage issues ([b4b1680](https://gitlab.com/macropeople/dcfrontend/commit/b4b16801afbe99814732b02c734741ed1826a9a7)) +* liveness test requires submitting table to pass ([1b43a63](https://gitlab.com/macropeople/dcfrontend/commit/1b43a6394848000705ba532cf4e3d7cf7ecccfbd)) +* makeData error detect ([b977b2a](https://gitlab.com/macropeople/dcfrontend/commit/b977b2a5c2659ab9fcfb6b0dd793571eb5a7b6e0)) +* migration for incorrect datetime format ([8aefd1b](https://gitlab.com/macropeople/dcfrontend/commit/8aefd1b74ddfaba21b773259afa9ccf293597dd4)) +* missing value ([2c69aad](https://gitlab.com/macropeople/dcfrontend/commit/2c69aad426ae4081cd1b751aa1eda8db474f6a65)) +* older versions of edge licensing ([d1eea5c](https://gitlab.com/macropeople/dcfrontend/commit/d1eea5c66e816080fe2ae342838f48594d7cab74)) +* optional viya call ([8e1537e](https://gitlab.com/macropeople/dcfrontend/commit/8e1537e24edbcac1795608197987807446b27ec1)) +* pages are getting wrong details on pagination ([615af15](https://gitlab.com/macropeople/dcfrontend/commit/615af159bd1f5e1efbfb7514362392e1e26d135e)) +* processed_dttm was not dynamic ([04d17eb](https://gitlab.com/macropeople/dcfrontend/commit/04d17eb348bbcb2321bb840fd04f54f0261a5868)) +* refreshcatalog ([eae6bfd](https://gitlab.com/macropeople/dcfrontend/commit/eae6bfdfedfde33dd18d9723eb2c1e78ce0665cb)) +* removing old package to remove npm warning ([bc99db0](https://gitlab.com/macropeople/dcfrontend/commit/bc99db0bb9b36d276da7cd670ffd814714c1a44c)) +* removing tabs ([4742842](https://gitlab.com/macropeople/dcfrontend/commit/47428423cd6746257f3ce1e11a63a68222639b20)) +* renegade %end ([a4a74ac](https://gitlab.com/macropeople/dcfrontend/commit/a4a74ac54c1483da4e33d26a5eedab679d844b03)) +* replace dependencies with sas macros in header ([3acd92b](https://gitlab.com/macropeople/dcfrontend/commit/3acd92b236055fc936638fc399b1b2dda7e727dd)) +* requests modal not working if server error ([cdcd578](https://gitlab.com/macropeople/dcfrontend/commit/cdcd5781f1c5a9a8cd72e167f47d36f848ad38a3)) +* return from service ([4d9a8e5](https://gitlab.com/macropeople/dcfrontend/commit/4d9a8e55b08463e82fe343f6b41fae0b4a3291c7)) +* rows separator is comma ([060ed48](https://gitlab.com/macropeople/dcfrontend/commit/060ed484a2ab10d9d6039a57030c755aed43ee9b)) +* rxjs imports (production build error) ([83d0859](https://gitlab.com/macropeople/dcfrontend/commit/83d085916326aecfeb0c8329397e2af37a5e370a)) +* sas double slash, new loading bar ([5fe053e](https://gitlab.com/macropeople/dcfrontend/commit/5fe053ecdcbe6e8487f6fe670d50545dffae03a6)) +* sas9 metanav broken ([0503e4b](https://gitlab.com/macropeople/dcfrontend/commit/0503e4b19bd15e3f4f20a2b442576de37238624b)) +* sas9 startupservice not executed ([0914007](https://gitlab.com/macropeople/dcfrontend/commit/09140074f9564b894878fce5f47c89544fd21d58)) +* stage component error handling ([2d9f417](https://gitlab.com/macropeople/dcfrontend/commit/2d9f417913cdf14593292a267f264caadb36036f)) +* startupservice failure handling ([d8c3380](https://gitlab.com/macropeople/dcfrontend/commit/d8c3380b861386c1b5357d40ade549fdb4b0756b)) +* startupservice sasjsAbort catch ([9f30bbe](https://gitlab.com/macropeople/dcfrontend/commit/9f30bbe7b3c4b5d73908fa0329f37f4b0a5230c7)) +* **licensing:** registerkey sasjsAbort fix ([a615e12](https://gitlab.com/macropeople/dcfrontend/commit/a615e12a31a293a36600912623e328b1fe244559)) +* **tests:** licensing test fixed unstable behavior ([011fcb6](https://gitlab.com/macropeople/dcfrontend/commit/011fcb662c92a7ee8a8ecf09c540d45e95432785)) +* **tests:** licensing tests shifted all to quickKey update ([6cc0128](https://gitlab.com/macropeople/dcfrontend/commit/6cc01281d6f5b957904a5e341be2eb2d88c2bbdb)) +* Subject not constructor error ([e22afc7](https://gitlab.com/macropeople/dcfrontend/commit/e22afc72ac190f28385d709a062a7d98be34103b)) +* surrounded data excel upload ([612729b](https://gitlab.com/macropeople/dcfrontend/commit/612729b0467c76371de3cd1784af275ef935adbb)) +* switch to new SAS 9 folder ([41ee6c4](https://gitlab.com/macropeople/dcfrontend/commit/41ee6c43f56835f18b72bfef6776e49acce200be)) +* syssite added to licensing page ([009618e](https://gitlab.com/macropeople/dcfrontend/commit/009618e47d6e6a7161bfecfd23e7fb2566d011f0)) +* tests fail when switching between viya and 9 ([c315d40](https://gitlab.com/macropeople/dcfrontend/commit/c315d40890cbf21a3fe6476b548048ac9c23d6cb)) +* typos and length checks ([69beff1](https://gitlab.com/macropeople/dcfrontend/commit/69beff1edd49e51d00cb193c35f460bc9b906425)) +* unable to VIEW tables in der touristik due to lowercase librefs ([945d5ac](https://gitlab.com/macropeople/dcfrontend/commit/945d5ac77e1afad51e139e70f4c315a005124eea)) +* updates to urls to support /services/ in program path ([c978f25](https://gitlab.com/macropeople/dcfrontend/commit/c978f25a29b32360083426d492cd2ee30f1f4595)) +* updating sas9 config ([54ba22d](https://gitlab.com/macropeople/dcfrontend/commit/54ba22dee71947d372a0c936f7dca8b4124b6f4b)) +* uploading video from ci tests ([14868e0](https://gitlab.com/macropeople/dcfrontend/commit/14868e0511606ef39f95ea3c4b861a433ce6f804)) +* user menu dropdown was not closing when you click on hot table area. ([000e39e](https://gitlab.com/macropeople/dcfrontend/commit/000e39ea94388e53dbf971db86dcb8fa244df368)) +* user nav style fix ([2a6af21](https://gitlab.com/macropeople/dcfrontend/commit/2a6af214435c905217d4188123cad08a96df5992)) +* usernav issues ([b4bc47d](https://gitlab.com/macropeople/dcfrontend/commit/b4bc47d31b043acbb4f7a4bd4e675d7f38d11f62)) +* using more robust functions for encoding and decoding base64 ([899ce20](https://gitlab.com/macropeople/dcfrontend/commit/899ce2007c748691271c75f326c5da8161351df5)) +* var_active addition to mpe_config, moving redshift setup there ([35fc30e](https://gitlab.com/macropeople/dcfrontend/commit/35fc30e0a4a65b9c5e5ab12de4bccc1b50d00ef4)) +* viewer if table eixsts undefined ([cbc8cc8](https://gitlab.com/macropeople/dcfrontend/commit/cbc8cc8281cf978722c3213c5138f99a6efae872)) +* viewer library collapse after choosing a table ([84c6cd6](https://gitlab.com/macropeople/dcfrontend/commit/84c6cd65e9dddeec5a807bfc36b55cbbc40b3636)) +* viewer rendering offset is to small ([52985fb](https://gitlab.com/macropeople/dcfrontend/commit/52985fbde43bff97d0d60649bfef02b0b3434831)) +* viewer table search abort modal ([b6388da](https://gitlab.com/macropeople/dcfrontend/commit/b6388da53cce3b3e2fa5267610a4992ea49e5ab8)) +* viewing non lineage tables broken in sas9 ([fee51ed](https://gitlab.com/macropeople/dcfrontend/commit/fee51edcf3167c0649b645cd77bfb772a1b36abc)) +* warning ([0925733](https://gitlab.com/macropeople/dcfrontend/commit/0925733139d417fec36470475486c5af4737f98f)) +* web streaming & deployment for SAS 9 ([3a36280](https://gitlab.com/macropeople/dcfrontend/commit/3a362800cbf17e65fb5da368641a668b4473f086)) +* whereClause display wrap/styling ([cca4c9e](https://gitlab.com/macropeople/dcfrontend/commit/cca4c9e2d0126b5ad98ef1704bd8c94a98a833b9)) +* wording of EULA ([64d9f1c](https://gitlab.com/macropeople/dcfrontend/commit/64d9f1cbb6c5880da332caf8bd4ef4e380262585)) +* **service-paths:** use relative paths without leading slash ([bf0b7c1](https://gitlab.com/macropeople/dcfrontend/commit/bf0b7c115f071255d704b060256914d75d1703ba)) +* **updated:** angular 10, clarity 3, optimized ([5031ed2](https://gitlab.com/macropeople/dcfrontend/commit/5031ed210a3e493f2652db5cb90e0b396923c38d)) + +## [3.10.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.9.0...v3.10.0) (2020-08-18) + + +### Features + +* abort modal complete refactor, removing duplicated code for abort, error handling improved ([3175654](https://gitlab.com/macropeople/dcfrontend/commit/317565491339c5697de2fdce65796920905d711a)) +* adapter compute api integration ([22dad29](https://gitlab.com/macropeople/dcfrontend/commit/22dad297d92ea2e28c2d28db8b721f350058ca8c)) +* added typedoc ([12480c4](https://gitlab.com/macropeople/dcfrontend/commit/12480c410a1dc7a852a468973119a9aa292f53b4)) +* file upload using adapter function ([eb0dea9](https://gitlab.com/macropeople/dcfrontend/commit/eb0dea9fe509439899f2de2c144ddedd56cb88b3)) +* handsontable v8, removed edit icons - contextMenu edit button ([1092e5c](https://gitlab.com/macropeople/dcfrontend/commit/1092e5c51fd50a050b1a5adcf285c5693a14d8b3)) +* jobs error catching ([6c01e03](https://gitlab.com/macropeople/dcfrontend/commit/6c01e033d3c2d788308b545b438450d8da356d87)) +* odd rows different shade ([ed336da](https://gitlab.com/macropeople/dcfrontend/commit/ed336daeaf7459637b321b1c9c4e83921f96720e)) +* pgsql download ([a617d17](https://gitlab.com/macropeople/dcfrontend/commit/a617d1742e4d942f8245eca07b71285f8432a0a9)) +* sasjsAbort uses new abort-modal component ([2bc300b](https://gitlab.com/macropeople/dcfrontend/commit/2bc300b621438b73a5401ee9c2696f263c180047)) +* started catching of adapter response error, showing full log in abort modal ([e781703](https://gitlab.com/macropeople/dcfrontend/commit/e78170324df8573c296463dcb7ddfc9e9df36e3b)) +* viewer lineage linking ([911d0c7](https://gitlab.com/macropeople/dcfrontend/commit/911d0c711481f56af483b82683b62e4bec3b5497)) + + +### Bug Fixes + +* abort modal added syserrortext syswarningtext ([6d6ccaf](https://gitlab.com/macropeople/dcfrontend/commit/6d6ccafe1695f0fe09164c7f701e45658b28ccf2)) +* abort modal customizable title ([c222f55](https://gitlab.com/macropeople/dcfrontend/commit/c222f55cb4f885824f5310d5510e4474acf89981)) +* abort modal styling ([e753d9a](https://gitlab.com/macropeople/dcfrontend/commit/e753d9af0cff0de6ad3972ee414458cfbc60b087)) +* abort modal warning and error text style ([abaaff8](https://gitlab.com/macropeople/dcfrontend/commit/abaaff8df856a643a87692afe375c7f4fc70ff77)) +* abot leftovers in htmls ([8de9713](https://gitlab.com/macropeople/dcfrontend/commit/8de971329894d6e3ed74ebc97b437a957e750d47)) +* add record button, modal loading spinner ([8527df9](https://gitlab.com/macropeople/dcfrontend/commit/8527df9608fbc9c444bf8cce6e0ac5f13cda33ee)) +* adding uri to enable lineage linking ([2b12f8c](https://gitlab.com/macropeople/dcfrontend/commit/2b12f8c559a3ee163e5890e801afedc128be3d9b)) +* appLoc checking ([7141efd](https://gitlab.com/macropeople/dcfrontend/commit/7141efd683c8a067063db3bfb5041b61d04a2105)) +* appLocCheck for viya only ([620b94d](https://gitlab.com/macropeople/dcfrontend/commit/620b94dcedd076e2225f88e4df122d324dc5fbb9)) +* approve page vlaues overlapping ([b1d182d](https://gitlab.com/macropeople/dcfrontend/commit/b1d182d8b1109bdbe27f243ece35ab2a81485607)) +* approvers casing issue ([d4d1112](https://gitlab.com/macropeople/dcfrontend/commit/d4d1112d9480a7a47ba2f25bfea3ef1a19546de9)) +* autoselect/autodocus ([a93bf8d](https://gitlab.com/macropeople/dcfrontend/commit/a93bf8dbd274265edaba48ef30fb2830d7064a65)) +* bump sasjs/core ([5617ced](https://gitlab.com/macropeople/dcfrontend/commit/5617cedd76a6a24b935b9c4e035ceffd88f6fea6)) +* bumping core ([f5fa141](https://gitlab.com/macropeople/dcfrontend/commit/f5fa141efba99088d8ee938e7f4d612b4a287965)) +* contextMenu enabled only on edit ([e8b4d30](https://gitlab.com/macropeople/dcfrontend/commit/e8b4d309fb7667920004cc2b68075d375edaff46)) +* data creation refactor ([fb0e343](https://gitlab.com/macropeople/dcfrontend/commit/fb0e343c345fc4cbb23990bed976f20db651c1e6)) +* demo mode add record button is off screen ([993b1a6](https://gitlab.com/macropeople/dcfrontend/commit/993b1a6c898f83f11fa42c69eafeb5276610c26e)) +* deploy compute api fixes ([2b6e989](https://gitlab.com/macropeople/dcfrontend/commit/2b6e98995f7a02e693580f193ee3e66c01163859)) +* duplicate key pipe ([0116304](https://gitlab.com/macropeople/dcfrontend/commit/0116304aa46cdec4ee1b831968562e5a2f670c2d)) +* edit after invalid submit not applied ([be350d9](https://gitlab.com/macropeople/dcfrontend/commit/be350d9d21ee2180f95ace03e86a21adc55a1557)) +* edit from viewer, submit error ([e0f2d56](https://gitlab.com/macropeople/dcfrontend/commit/e0f2d567245cfb6b9722e0cc4ba24fbcf7dca3ae)) +* enabling makedata to run both as url and request format ([5989992](https://gitlab.com/macropeople/dcfrontend/commit/59899921a8279ef2fedf24b5f9a20e9f4a399c91)) +* excel submit, UX fixes ([5de9c1d](https://gitlab.com/macropeople/dcfrontend/commit/5de9c1d105fc6a4540c5a33400a77a79c78fe6f0)) +* home component cleanup ([9416f75](https://gitlab.com/macropeople/dcfrontend/commit/9416f75d85a1a384ec2eab8a90647b3ef839c931)) +* lineage download full graph ([4d8d10b](https://gitlab.com/macropeople/dcfrontend/commit/4d8d10b99321b6de5e41a4371bffb38e6a6a1d0e)) +* loading spinner on submit ([6adc797](https://gitlab.com/macropeople/dcfrontend/commit/6adc79795d3a155e2e0013d55db7a3ac946bb05b)) +* makedata seperation ([32f9cd6](https://gitlab.com/macropeople/dcfrontend/commit/32f9cd6826c3ca87c40b31e3456d848eae24620f)) +* missing dependency ([f5debd8](https://gitlab.com/macropeople/dcfrontend/commit/f5debd86ba67328f232486977fe5aa8ae537c69d)) +* model updates and build environment updates ([528ed9c](https://gitlab.com/macropeople/dcfrontend/commit/528ed9ce19830300c49d4ca6fc9bb662b6a282dc)) +* no editable tables configured ([7e344df](https://gitlab.com/macropeople/dcfrontend/commit/7e344df7f6a3ab52bca9934c975f1da75e845a3e)) +* options button styling, sasjs adapter & core bumps, excel export fix ([2752c5d](https://gitlab.com/macropeople/dcfrontend/commit/2752c5da44a7d994a4099177c768c92562b8e25d)) +* record modal linking UX ([94981cf](https://gitlab.com/macropeople/dcfrontend/commit/94981cf2abc1541c017aea0192ca1a5ff87745a8)) +* Remove the auto-hide of the sidebar above a certain screen size ([d841ec6](https://gitlab.com/macropeople/dcfrontend/commit/d841ec6839d44e34014252fb9ca605d79e8ec88d)) +* table sizing when no demo banner present ([e00533d](https://gitlab.com/macropeople/dcfrontend/commit/e00533d35f9dca2a9ecdb13eade7467245f52f56)) +* to avoid circular reference ([c715aed](https://gitlab.com/macropeople/dcfrontend/commit/c715aedecf7e1326ed65260bcf7cc363e7d54125)) +* uploader multiple files ([35e6cfd](https://gitlab.com/macropeople/dcfrontend/commit/35e6cfd84fb96bbdc919268495af00eb20160ba3)) +* viewer options icon gap ([2d7199b](https://gitlab.com/macropeople/dcfrontend/commit/2d7199b82a63b82e04a9e0e7e2dc7427337a6d21)) +* web query url ([ed85e0b](https://gitlab.com/macropeople/dcfrontend/commit/ed85e0ba06f5dd89a4ffbb3e31d7036fcfaa5fca)) + + +# [3.9.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.8.0...v3.9.0) (2020-07-14) + + +### Bug Fixes + +* deployServicePack removed ([01e3473](https://gitlab.com/macropeople/dcfrontend/commit/01e3473)) +* _program conflict ([50dfa2b](https://gitlab.com/macropeople/dcfrontend/commit/50dfa2b)) +* adapting to sasjs, removed token functions ([706eb3a](https://gitlab.com/macropeople/dcfrontend/commit/706eb3a)) +* adding maxlen ([a1a36e4](https://gitlab.com/macropeople/dcfrontend/commit/a1a36e4)) +* adding seperator ([d262685](https://gitlab.com/macropeople/dcfrontend/commit/d262685)) +* autodeploy infos p instead of input ([fab1294](https://gitlab.com/macropeople/dcfrontend/commit/fab1294)) +* bump macrocore, default value for _program ([f3d3e5e](https://gitlab.com/macropeople/dcfrontend/commit/f3d3e5e)) +* bump MC and enable public services ([5319005](https://gitlab.com/macropeople/dcfrontend/commit/5319005)) +* bump sasjs ([582c9e3](https://gitlab.com/macropeople/dcfrontend/commit/582c9e3)) +* bump sasjs ([4b5a167](https://gitlab.com/macropeople/dcfrontend/commit/4b5a167)) +* bumping sasjs and missing puri in lineage generator ([5f25bd6](https://gitlab.com/macropeople/dcfrontend/commit/5f25bd6)) +* clicking icon in viewer menu does not expand menu ([3941635](https://gitlab.com/macropeople/dcfrontend/commit/3941635)) +* client token removal ([af14883](https://gitlab.com/macropeople/dcfrontend/commit/af14883)) +* data model update ([13a53f1](https://gitlab.com/macropeople/dcfrontend/commit/13a53f1)) +* dcpath in deploy ([a157f05](https://gitlab.com/macropeople/dcfrontend/commit/a157f05)) +* demo expired styling ([61336b0](https://gitlab.com/macropeople/dcfrontend/commit/61336b0)) +* deploy and token imporvements ([9d05839](https://gitlab.com/macropeople/dcfrontend/commit/9d05839)) +* deploy buttons position ([b06ad5d](https://gitlab.com/macropeople/dcfrontend/commit/b06ad5d)) +* deploy defaults set ([a074787](https://gitlab.com/macropeople/dcfrontend/commit/a074787)) +* deploy navigate to home ([17ed9b0](https://gitlab.com/macropeople/dcfrontend/commit/17ed9b0)) +* deploy page fixes ([3f7419f](https://gitlab.com/macropeople/dcfrontend/commit/3f7419f)) +* deploy removed client and secret, debug was not switched on ([09475f2](https://gitlab.com/macropeople/dcfrontend/commit/09475f2)) +* deploy updates ([43083b4](https://gitlab.com/macropeople/dcfrontend/commit/43083b4)) +* dynamic build of getviyaclient ([21e7b9c](https://gitlab.com/macropeople/dcfrontend/commit/21e7b9c)) +* edit table styling issue ([d408a60](https://gitlab.com/macropeople/dcfrontend/commit/d408a60)) +* editor title link ([a7edd3c](https://gitlab.com/macropeople/dcfrontend/commit/a7edd3c)) +* expired token shows login page ([d1ad578](https://gitlab.com/macropeople/dcfrontend/commit/d1ad578)) +* filter issues ([ccf9ea8](https://gitlab.com/macropeople/dcfrontend/commit/ccf9ea8)) +* forbid unchanged submit ([0ec1c52](https://gitlab.com/macropeople/dcfrontend/commit/0ec1c52)) +* get all contexts, deploy ([dae7ee1](https://gitlab.com/macropeople/dcfrontend/commit/dae7ee1)) +* get executable contexts on deploy page ([d51c0d0](https://gitlab.com/macropeople/dcfrontend/commit/d51c0d0)) +* header invisible when demo banner removed ([7216154](https://gitlab.com/macropeople/dcfrontend/commit/7216154)) +* hide demo banner when license key present ([634e14e](https://gitlab.com/macropeople/dcfrontend/commit/634e14e)) +* hitting accept before diff load causes error ([dbc9fbd](https://gitlab.com/macropeople/dcfrontend/commit/dbc9fbd)) +* jobs type in idlookup ([3a138c6](https://gitlab.com/macropeople/dcfrontend/commit/3a138c6)) +* lineage column level linking ([bf04597](https://gitlab.com/macropeople/dcfrontend/commit/bf04597)) +* lineage is depending only on 'fetchlineage' service, not any other ([6631fd9](https://gitlab.com/macropeople/dcfrontend/commit/6631fd9)) +* lineage libraryid of undefined, cases covered ([f44b75a](https://gitlab.com/macropeople/dcfrontend/commit/f44b75a)) +* lineage multiple requests ([45350a0](https://gitlab.com/macropeople/dcfrontend/commit/45350a0)) +* lineage table url access fix ([ffb2477](https://gitlab.com/macropeople/dcfrontend/commit/ffb2477)) +* macro invoke ([f9b91dc](https://gitlab.com/macropeople/dcfrontend/commit/f9b91dc)) +* macrocore ([50bd41b](https://gitlab.com/macropeople/dcfrontend/commit/50bd41b)) +* macrocore bump ([778a891](https://gitlab.com/macropeople/dcfrontend/commit/778a891)) +* makedata ([773a62b](https://gitlab.com/macropeople/dcfrontend/commit/773a62b)) +* makedata updates ([2a6d6ae](https://gitlab.com/macropeople/dcfrontend/commit/2a6d6ae)) +* metadata name from response ([642428c](https://gitlab.com/macropeople/dcfrontend/commit/642428c)) +* metadata object name when linking ([62b6b6c](https://gitlab.com/macropeople/dcfrontend/commit/62b6b6c)) +* metadata objectName param ignore ([56cfa9e](https://gitlab.com/macropeople/dcfrontend/commit/56cfa9e)) +* migration for mpe_datadictionary ([b6a5edc](https://gitlab.com/macropeople/dcfrontend/commit/b6a5edc)) +* more rendered rows, undefined celValidation ([43111bb](https://gitlab.com/macropeople/dcfrontend/commit/43111bb)) +* pk duplicate check, removed cellValidtion on frontend ([6871191](https://gitlab.com/macropeople/dcfrontend/commit/6871191)) +* pk dups check on first submit ([6e41613](https://gitlab.com/macropeople/dcfrontend/commit/6e41613)) +* pk issue ([58e727b](https://gitlab.com/macropeople/dcfrontend/commit/58e727b)) +* predefined colWidths ([98bb6e6](https://gitlab.com/macropeople/dcfrontend/commit/98bb6e6)) +* refresh service ([6d1d489](https://gitlab.com/macropeople/dcfrontend/commit/6d1d489)) +* removing 'error:' string ([049d04a](https://gitlab.com/macropeople/dcfrontend/commit/049d04a)) +* removing access tokens ([9031e9a](https://gitlab.com/macropeople/dcfrontend/commit/9031e9a)) +* removing caslib assignment ([53396bb](https://gitlab.com/macropeople/dcfrontend/commit/53396bb)) +* removing session table ([e50c996](https://gitlab.com/macropeople/dcfrontend/commit/e50c996)) +* search data bug in viya ([3c54cbc](https://gitlab.com/macropeople/dcfrontend/commit/3c54cbc)) +* siemens issues (lineage, exporter) ([7eed379](https://gitlab.com/macropeople/dcfrontend/commit/7eed379)) +* sorting is lost after clicking edit/cancel edit ([65ef697](https://gitlab.com/macropeople/dcfrontend/commit/65ef697)) +* startupservice ([367a194](https://gitlab.com/macropeople/dcfrontend/commit/367a194)) +* startupservice abort in console log ([9a5e10f](https://gitlab.com/macropeople/dcfrontend/commit/9a5e10f)) +* styling and manual deploy ([d683a70](https://gitlab.com/macropeople/dcfrontend/commit/d683a70)) +* styling, admin groups limit and sort ([6c3bcad](https://gitlab.com/macropeople/dcfrontend/commit/6c3bcad)) +* submit after error ([8949021](https://gitlab.com/macropeople/dcfrontend/commit/8949021)) +* submit without changes modal ([04998e3](https://gitlab.com/macropeople/dcfrontend/commit/04998e3)) +* syscc to 0 on startup ([145866a](https://gitlab.com/macropeople/dcfrontend/commit/145866a)) +* table update ([69a6e70](https://gitlab.com/macropeople/dcfrontend/commit/69a6e70)) +* test ([bb01cd9](https://gitlab.com/macropeople/dcfrontend/commit/bb01cd9)) +* token expiration ([1e5fb39](https://gitlab.com/macropeople/dcfrontend/commit/1e5fb39)) +* tokenauth management ([20ae61d](https://gitlab.com/macropeople/dcfrontend/commit/20ae61d)) +* unable to edit and dropdown blank ([06f4aae](https://gitlab.com/macropeople/dcfrontend/commit/06f4aae)) +* validate primary keys, editor performance ([aa66cbc](https://gitlab.com/macropeople/dcfrontend/commit/aa66cbc)) +* viya auth rebuild ([f74a4da](https://gitlab.com/macropeople/dcfrontend/commit/f74a4da)) +* viya fixes ([24c6603](https://gitlab.com/macropeople/dcfrontend/commit/24c6603)) +* viya token global ([4b597f1](https://gitlab.com/macropeople/dcfrontend/commit/4b597f1)) +* viya usernav with RESTApis ([7e12bd5](https://gitlab.com/macropeople/dcfrontend/commit/7e12bd5)) +* viyainstall ([3384ee8](https://gitlab.com/macropeople/dcfrontend/commit/3384ee8)) + + +### Features + +* authentication process update ([045d6a2](https://gitlab.com/macropeople/dcfrontend/commit/045d6a2)) +* auto deploy for viya, appLoc exist check ([c4466b3](https://gitlab.com/macropeople/dcfrontend/commit/c4466b3)) +* auto deploy if startupservice not present ([635e58a](https://gitlab.com/macropeople/dcfrontend/commit/635e58a)) +* auto include sasbuild/viya.json from dist folder ([ea5f5c0](https://gitlab.com/macropeople/dcfrontend/commit/ea5f5c0)) +* dcdeploy, creating database ([f17919d](https://gitlab.com/macropeople/dcfrontend/commit/f17919d)) +* deploy page collapsable and improvements ([e6fc907](https://gitlab.com/macropeople/dcfrontend/commit/e6fc907)) +* deploy page json upload ([4bca65d](https://gitlab.com/macropeople/dcfrontend/commit/4bca65d)) +* deploy page with presistent keys ([078ff27](https://gitlab.com/macropeople/dcfrontend/commit/078ff27)) +* deployEnabled switch, removed buttons on deploy page ([36f2e5f](https://gitlab.com/macropeople/dcfrontend/commit/36f2e5f)) +* file uplaod with token, synced with formdata token ([e67a841](https://gitlab.com/macropeople/dcfrontend/commit/e67a841)) +* lineage svg linking ([e64c840](https://gitlab.com/macropeople/dcfrontend/commit/e64c840)) +* usernav shift to RESTApis ([b70091e](https://gitlab.com/macropeople/dcfrontend/commit/b70091e)) +* validate rows, pk duplicates in modal ([98ad374](https://gitlab.com/macropeople/dcfrontend/commit/98ad374)) +* viya deploy page ([8f058d1](https://gitlab.com/macropeople/dcfrontend/commit/8f058d1)) +* viya deploy without client & access_token ([f8c3bc5](https://gitlab.com/macropeople/dcfrontend/commit/f8c3bc5)) +* viya including access token ([2d4a91f](https://gitlab.com/macropeople/dcfrontend/commit/2d4a91f)) + + + + +# [3.8.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.7.0...v3.8.0) (2020-05-31) + + +### Bug Fixes + +* add record url rewrite ([8ab80e8](https://gitlab.com/macropeople/dcfrontend/commit/8ab80e8)) +* finishing up TableLineage ([ff600aa](https://gitlab.com/macropeople/dcfrontend/commit/ff600aa)) +* table lineage and post service macro append ([cee486e](https://gitlab.com/macropeople/dcfrontend/commit/cee486e)) +* **lineage table:** libref and table name ([f87cf6b](https://gitlab.com/macropeople/dcfrontend/commit/f87cf6b)) +* **table lineage:** csv download, table name ([e4580be](https://gitlab.com/macropeople/dcfrontend/commit/e4580be)) +* metadataRoot to appLoc ([d437a6f](https://gitlab.com/macropeople/dcfrontend/commit/d437a6f)) +* moment import ([718df90](https://gitlab.com/macropeople/dcfrontend/commit/718df90)) +* using sasjs vars in viya build ([bd790b6](https://gitlab.com/macropeople/dcfrontend/commit/bd790b6)) + + +### Features + +* varchar support in Viya ([c954f65](https://gitlab.com/macropeople/dcfrontend/commit/c954f65)) +* **lineage table:** title link to viewer ([2726d09](https://gitlab.com/macropeople/dcfrontend/commit/2726d09)) +* table level lineage ([54f7731](https://gitlab.com/macropeople/dcfrontend/commit/54f7731)) +* Table Level Lineage ([01256a9](https://gitlab.com/macropeople/dcfrontend/commit/01256a9)) + + + + +# [3.7.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.6.0...v3.7.0) (2020-05-22) + + +### Bug Fixes + +* ensuring _debug is always present ([299a78d](https://gitlab.com/macropeople/dcfrontend/commit/299a78d)) +* file upload debug param, staged data download package button ([3b62a5c](https://gitlab.com/macropeople/dcfrontend/commit/3b62a5c)) +* secret path ([c628553](https://gitlab.com/macropeople/dcfrontend/commit/c628553)) + + +### Features + +* download lineage as png ([0f2af40](https://gitlab.com/macropeople/dcfrontend/commit/0f2af40)) + + + + +# [3.6.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.5.0...v3.6.0) (2020-05-20) + + +### Bug Fixes + +* disable filter when editing table ([d411f9a](https://gitlab.com/macropeople/dcfrontend/commit/d411f9a)) + + +### Features + +* edit number of rows ([f82e15c](https://gitlab.com/macropeople/dcfrontend/commit/f82e15c)) +* submit only modified rows, redirect to staged data ([b3846b6](https://gitlab.com/macropeople/dcfrontend/commit/b3846b6)) +* submit statistics ([ac8e97b](https://gitlab.com/macropeople/dcfrontend/commit/ac8e97b)) + + + + +# [3.5.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.4.0...v3.5.0) (2020-05-20) + + +### Bug Fixes + +* adding cols info to getdata services ([211e943](https://gitlab.com/macropeople/dcfrontend/commit/211e943)) +* bumping sasjs version ([30aa4b2](https://gitlab.com/macropeople/dcfrontend/commit/30aa4b2)) +* edit button on table viewer ([7fbf306](https://gitlab.com/macropeople/dcfrontend/commit/7fbf306)) +* editor navigation highlight, saving space in viewer and editor ([31448a5](https://gitlab.com/macropeople/dcfrontend/commit/31448a5)) +* file upload with token ([4c0e18d](https://gitlab.com/macropeople/dcfrontend/commit/4c0e18d)) +* filter datetime dropdown to show raw value ([6a3008e](https://gitlab.com/macropeople/dcfrontend/commit/6a3008e)) +* filter values dropdown ([cd1ae54](https://gitlab.com/macropeople/dcfrontend/commit/cd1ae54)) +* hot filtering issues, submitting only filtered rows ([159bafc](https://gitlab.com/macropeople/dcfrontend/commit/159bafc)) +* IE search styling ([b2d93ef](https://gitlab.com/macropeople/dcfrontend/commit/b2d93ef)) +* loop in viewer libraries ([313495e](https://gitlab.com/macropeople/dcfrontend/commit/313495e)) +* options dropdown position ([2ae7402](https://gitlab.com/macropeople/dcfrontend/commit/2ae7402)) +* perms issues ([4953fae](https://gitlab.com/macropeople/dcfrontend/commit/4953fae)) +* removing bottom bar, saving space ([bd9c35c](https://gitlab.com/macropeople/dcfrontend/commit/bd9c35c)) +* request modal linking ([a3f581c](https://gitlab.com/macropeople/dcfrontend/commit/a3f581c)) +* SCD2 now works with OR filter ops ([6745cb1](https://gitlab.com/macropeople/dcfrontend/commit/6745cb1)) +* schemas in catalog, metarepo in metanav ([43d0109](https://gitlab.com/macropeople/dcfrontend/commit/43d0109)) +* usernav version bar ([34c6ebb](https://gitlab.com/macropeople/dcfrontend/commit/34c6ebb)) +* using existing cols data for filter ([3c6ba97](https://gitlab.com/macropeople/dcfrontend/commit/3c6ba97)) +* viya group title ([d360ec1](https://gitlab.com/macropeople/dcfrontend/commit/d360ec1)) +* viya loadfile updates ([a25d36a](https://gitlab.com/macropeople/dcfrontend/commit/a25d36a)) +* web query url duplication and spaces ([c27fe3c](https://gitlab.com/macropeople/dcfrontend/commit/c27fe3c)) + + +### Features + +* ability to exclude certain libs from the catalog refresh. Also a fix to the lineage process. ([f2e95ce](https://gitlab.com/macropeople/dcfrontend/commit/f2e95ce)) +* datastatus_libs ([528b84b](https://gitlab.com/macropeople/dcfrontend/commit/528b84b)) +* downlaod button on submiter and approval screen ([cfbba5a](https://gitlab.com/macropeople/dcfrontend/commit/cfbba5a)) +* meta nav repository presistance ([ad46c61](https://gitlab.com/macropeople/dcfrontend/commit/ad46c61)) +* rows to submit ([dc918dd](https://gitlab.com/macropeople/dcfrontend/commit/dc918dd)) +* selection on view presisted ([962ceba](https://gitlab.com/macropeople/dcfrontend/commit/962ceba)) +* sql server data dictionary upates (plus removal of error lines) ([d8e8586](https://gitlab.com/macropeople/dcfrontend/commit/d8e8586)) +* sql server integration to dictionary tables ([8610d7a](https://gitlab.com/macropeople/dcfrontend/commit/8610d7a)) +* writeback data in Viya ([da3d0ee](https://gitlab.com/macropeople/dcfrontend/commit/da3d0ee)) + + + + +# [3.4.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.3.1...v3.4.0) (2020-05-03) + + +### Features + +* data catalog for libraries, tables and columns ([1865eb1](https://gitlab.com/macropeople/dcfrontend/commit/1865eb1)) +* filter values editable ([ffa1065](https://gitlab.com/macropeople/dcfrontend/commit/ffa1065)) +* viewer number of rows ([37fbf3d](https://gitlab.com/macropeople/dcfrontend/commit/37fbf3d)) +* viewer search table ([ae65969](https://gitlab.com/macropeople/dcfrontend/commit/ae65969)) + + + + +## [3.3.1](https://gitlab.com/macropeople/dcfrontend/compare/v3.3.0...v3.3.1) (2020-04-27) + + +### Bug Fixes + +* ddl download ([ece1e79](https://gitlab.com/macropeople/dcfrontend/commit/ece1e79)) +* submit bug, stage page license key ([388c067](https://gitlab.com/macropeople/dcfrontend/commit/388c067)) + + + + +# [3.3.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.2.0...v3.3.0) (2020-04-26) + + +### Bug Fixes + +* backend changes to support frontend fixes ([2e7b6ef](https://gitlab.com/macropeople/dcfrontend/commit/2e7b6ef)) +* dqdata update ([b8db8bf](https://gitlab.com/macropeople/dcfrontend/commit/b8db8bf)) +* invalid values on submit, notnull validation ([4ac8088](https://gitlab.com/macropeople/dcfrontend/commit/4ac8088)) +* parsing errors and warning improved, performance fix, icons added ([e2b8a24](https://gitlab.com/macropeople/dcfrontend/commit/e2b8a24)) +* remove syscc=4 in approvals ([af24fd3](https://gitlab.com/macropeople/dcfrontend/commit/af24fd3)) +* switch to mp_streamfile ([8cb4529](https://gitlab.com/macropeople/dcfrontend/commit/8cb4529)) +* warning not linkable ([9491ccc](https://gitlab.com/macropeople/dcfrontend/commit/9491ccc)) + + +### Features + +* request modal error and warning linking ([ebcf2f4](https://gitlab.com/macropeople/dcfrontend/commit/ebcf2f4)) + + + + +# [3.2.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.1.0...v3.2.0) (2020-04-23) + + +### Bug Fixes + +* get username from MF_GETUSER ([10bc04f](https://gitlab.com/macropeople/dcfrontend/commit/10bc04f)) +* double scroll, add record button, add row scroll to bottom ([75fd508](https://gitlab.com/macropeople/dcfrontend/commit/75fd508)) +* dropdowns ([4247114](https://gitlab.com/macropeople/dcfrontend/commit/4247114)) +* editor page not working ([c7ae36f](https://gitlab.com/macropeople/dcfrontend/commit/c7ae36f)) +* record modal not opening, paste trim trailings, 'edit' button performance ([26da7f5](https://gitlab.com/macropeople/dcfrontend/commit/26da7f5)) +* WIP dialouge not opening for new row after cancel and reopen ([ad37092](https://gitlab.com/macropeople/dcfrontend/commit/ad37092)) + + +### Features + +* dqdata update ([ccbec0c](https://gitlab.com/macropeople/dcfrontend/commit/ccbec0c)) +* exclude data lineage and metanav if serverType is viya ([56c0459](https://gitlab.com/macropeople/dcfrontend/commit/56c0459)) +* metavav auto open on object url navigation ([ce49d75](https://gitlab.com/macropeople/dcfrontend/commit/ce49d75)) +* usernav functionality for VIYA ([63fa9ae](https://gitlab.com/macropeople/dcfrontend/commit/63fa9ae)) + + + + +# [3.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v3.0.0...v3.1.0) (2020-04-19) + + +### Bug Fixes + +* sas path in url dynamically ([241911d](https://gitlab.com/macropeople/dcfrontend/commit/241911d)) +* broken url ([397857b](https://gitlab.com/macropeople/dcfrontend/commit/397857b)) +* char input length check ([69efa6e](https://gitlab.com/macropeople/dcfrontend/commit/69efa6e)) +* incorrent url for download and upload ([2638d58](https://gitlab.com/macropeople/dcfrontend/commit/2638d58)) +* link to this record ([970f952](https://gitlab.com/macropeople/dcfrontend/commit/970f952)) +* metanav services and utf-8 issue ([3820e78](https://gitlab.com/macropeople/dcfrontend/commit/3820e78)) +* modal upcase validation, copied to clipboard, number converted to char ([9bdcf50](https://gitlab.com/macropeople/dcfrontend/commit/9bdcf50)) +* record modal original column order ([2595911](https://gitlab.com/macropeople/dcfrontend/commit/2595911)) +* submit modal, record modal improving ([ec1eab2](https://gitlab.com/macropeople/dcfrontend/commit/ec1eab2)) +* **excel-upload:** add polyfill for DateTimeFormat.formatToParts ([22ce409](https://gitlab.com/macropeople/dcfrontend/commit/22ce409)) +* **sasjs:** upgrade adapter version to fix IE ([517fff5](https://gitlab.com/macropeople/dcfrontend/commit/517fff5)) +* **url:** remove hardcoded path ([7071186](https://gitlab.com/macropeople/dcfrontend/commit/7071186)) +* wrong navigation from approve/submit to view table ([d144a2e](https://gitlab.com/macropeople/dcfrontend/commit/d144a2e)) + + +### Features + +* add "NOT IN" option to filter ([d41217b](https://gitlab.com/macropeople/dcfrontend/commit/d41217b)) +* add / edit record option ([e82b346](https://gitlab.com/macropeople/dcfrontend/commit/e82b346)) +* autoselect / autofocus on edit submit ([8833e11](https://gitlab.com/macropeople/dcfrontend/commit/8833e11)) +* metanav attributes search, auto open object details ([9dfb112](https://gitlab.com/macropeople/dcfrontend/commit/9dfb112)) +* record-edit linking ([14eedca](https://gitlab.com/macropeople/dcfrontend/commit/14eedca)) +* viya support wrapup ([d211378](https://gitlab.com/macropeople/dcfrontend/commit/d211378)) + + + + +# [3.0.0](https://gitlab.com/macropeople/dcfrontend/compare/v2.2.0...v3.0.0) (2020-04-13) + + +### Bug Fixes + +* all servies converted to SASjs ([f649bf1](https://gitlab.com/macropeople/dcfrontend/commit/f649bf1)) +* bitemporal loader error removal, build process switched to dcbuild.sh ([0ccc4bc](https://gitlab.com/macropeople/dcfrontend/commit/0ccc4bc)) +* case sensitive librefs ([198a2de](https://gitlab.com/macropeople/dcfrontend/commit/198a2de)), closes [#86](https://gitlab.com/macropeople/dcfrontend/issues/86) +* configuration and startup service ([d4e1d7b](https://gitlab.com/macropeople/dcfrontend/commit/d4e1d7b)) +* configurator ([f0f2224](https://gitlab.com/macropeople/dcfrontend/commit/f0f2224)) +* configurator, and metanav services updated ([c626f08](https://gitlab.com/macropeople/dcfrontend/commit/c626f08)) +* enabling sasjs build ([71d65e8](https://gitlab.com/macropeople/dcfrontend/commit/71d65e8)) +* environtment verson path ([8636879](https://gitlab.com/macropeople/dcfrontend/commit/8636879)) +* final build script ([9cd80cf](https://gitlab.com/macropeople/dcfrontend/commit/9cd80cf)) +* final for viya ([920d9ae](https://gitlab.com/macropeople/dcfrontend/commit/920d9ae)) +* getting to demo version ([9ffbee2](https://gitlab.com/macropeople/dcfrontend/commit/9ffbee2)) +* incorrect validations after duplicate check ([24a417d](https://gitlab.com/macropeople/dcfrontend/commit/24a417d)) +* lowercase response, approve route ([9e07fb1](https://gitlab.com/macropeople/dcfrontend/commit/9e07fb1)) +* metanav SAS integration ([3fce458](https://gitlab.com/macropeople/dcfrontend/commit/3fce458)) +* page not found on approve details ([08fea24](https://gitlab.com/macropeople/dcfrontend/commit/08fea24)) +* precision ([2321892](https://gitlab.com/macropeople/dcfrontend/commit/2321892)) +* preparing web target ([20aaf69](https://gitlab.com/macropeople/dcfrontend/commit/20aaf69)) +* re-org of files for sasjs-cli 2.2 ([81c2094](https://gitlab.com/macropeople/dcfrontend/commit/81c2094)) +* removing h54s and boemska ([120cd1b](https://gitlab.com/macropeople/dcfrontend/commit/120cd1b)) +* response lowercase, debug switch ([7660cc6](https://gitlab.com/macropeople/dcfrontend/commit/7660cc6)) +* sas errors in 9 ([5d1471c](https://gitlab.com/macropeople/dcfrontend/commit/5d1471c)) +* sas9 fixes ([45b90dd](https://gitlab.com/macropeople/dcfrontend/commit/45b90dd)) +* setting username on login and request ([8e1e0d1](https://gitlab.com/macropeople/dcfrontend/commit/8e1e0d1)) +* splash page ([6a50a22](https://gitlab.com/macropeople/dcfrontend/commit/6a50a22)) +* stagedata fref pickup ([55572cb](https://gitlab.com/macropeople/dcfrontend/commit/55572cb)) +* stagedata table object, debug switch modal close, removing appLoc in request path ([c227a2c](https://gitlab.com/macropeople/dcfrontend/commit/c227a2c)) +* switching mf_abort for mp_abort ([1ba790f](https://gitlab.com/macropeople/dcfrontend/commit/1ba790f)) +* test updates (demo version) ([cbc2723](https://gitlab.com/macropeople/dcfrontend/commit/cbc2723)) +* upgrade to latest sasjs-cli format ([8aae0b2](https://gitlab.com/macropeople/dcfrontend/commit/8aae0b2)) +* upgraded sasjs ([fdd7c17](https://gitlab.com/macropeople/dcfrontend/commit/fdd7c17)) +* uppercase issue ([08d65b8](https://gitlab.com/macropeople/dcfrontend/commit/08d65b8)) +* user _METAUSER instead of sysuserid for SAS9 ([5c12760](https://gitlab.com/macropeople/dcfrontend/commit/5c12760)) +* various, including bitemporal ([09d77ca](https://gitlab.com/macropeople/dcfrontend/commit/09d77ca)) +* viya integration ([99a8993](https://gitlab.com/macropeople/dcfrontend/commit/99a8993)) +* viya integration of getgroupmembers ([426bc88](https://gitlab.com/macropeople/dcfrontend/commit/426bc88)) +* viya updates ([22d6e98](https://gitlab.com/macropeople/dcfrontend/commit/22d6e98)) +* **dcbuild:** hostURL starts with // instead of http/https ([1f3d6e3](https://gitlab.com/macropeople/dcfrontend/commit/1f3d6e3)) + + +### Chores + +* readme update ([4ded32a](https://gitlab.com/macropeople/dcfrontend/commit/4ded32a)) + + +### Features + +* viya macros ([bef208e](https://gitlab.com/macropeople/dcfrontend/commit/bef208e)) +* data quality rules on edit mode ([65a20c5](https://gitlab.com/macropeople/dcfrontend/commit/65a20c5)) +* enabling users & groups in Viya ([30bed3d](https://gitlab.com/macropeople/dcfrontend/commit/30bed3d)) +* integrating sasjs (startupService, SAS Requests, Login) ([d7e20f9](https://gitlab.com/macropeople/dcfrontend/commit/d7e20f9)) +* sas9 auto-build with latest sasjs-cli ([5c2f1e4](https://gitlab.com/macropeople/dcfrontend/commit/5c2f1e4)) +* sasjs integration ([beb30d8](https://gitlab.com/macropeople/dcfrontend/commit/beb30d8)) +* viya mods to enable first service ([a8c8932](https://gitlab.com/macropeople/dcfrontend/commit/a8c8932)) + + +### BREAKING CHANGES + +* switch to SASjsgit add README.md + + + + +# [2.2.0](https://gitlab.com/macropeople/dcfrontend/compare/v2.1.0...v2.2.0) (2020-03-28) + + +### Bug Fixes + +* date capture ([c7c3d57](https://gitlab.com/macropeople/dcfrontend/commit/c7c3d57)) +* DOWNCASE->LOWCASE ([aecba73](https://gitlab.com/macropeople/dcfrontend/commit/aecba73)) +* hot license key ([3f5b636](https://gitlab.com/macropeople/dcfrontend/commit/3f5b636)) + + +### Features + +* apply dqrule in edit mode ([3b4afbd](https://gitlab.com/macropeople/dcfrontend/commit/3b4afbd)) + + + + +# [2.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v2.0.0...v2.1.0) (2020-03-26) + + +### Bug Fixes + +* closes [#83](https://gitlab.com/macropeople/dcfrontend/issues/83) (decimal truncation issue) ([870bf5c](https://gitlab.com/macropeople/dcfrontend/commit/870bf5c)) +* cypress ([56ddfdf](https://gitlab.com/macropeople/dcfrontend/commit/56ddfdf)) +* debug switch wrong state ([00d9ad1](https://gitlab.com/macropeople/dcfrontend/commit/00d9ad1)) +* double click triggers edit mode ([169b84d](https://gitlab.com/macropeople/dcfrontend/commit/169b84d)) +* legacy support for x variable in post edit hook ([3777c33](https://gitlab.com/macropeople/dcfrontend/commit/3777c33)) +* local vars ([ba8ce4c](https://gitlab.com/macropeople/dcfrontend/commit/ba8ce4c)) +* migration ([81a5e0d](https://gitlab.com/macropeople/dcfrontend/commit/81a5e0d)) +* test update, remove logging ([cae0735](https://gitlab.com/macropeople/dcfrontend/commit/cae0735)) +* tests ([e28d872](https://gitlab.com/macropeople/dcfrontend/commit/e28d872)) +* tidyup and enabling views in viewtables ([06639cb](https://gitlab.com/macropeople/dcfrontend/commit/06639cb)) + + +### Features + +* data dictionary and mpe_validations tables, and DQRULES now sent in getData service ([856b4f6](https://gitlab.com/macropeople/dcfrontend/commit/856b4f6)) +* hardselect, closes [#84](https://gitlab.com/macropeople/dcfrontend/issues/84) ([859cfd1](https://gitlab.com/macropeople/dcfrontend/commit/859cfd1)) +* user friendly display when library is empty ([cff71f2](https://gitlab.com/macropeople/dcfrontend/commit/cff71f2)) + + + + +# [2.0.0](https://gitlab.com/macropeople/dcfrontend/compare/v1.3.3...v2.0.0) (2020-03-16) + + +### Bug Fixes + +* backend can take either first or second file as CSV ([a3aaab6](https://gitlab.com/macropeople/dcfrontend/commit/a3aaab6)) +* click twice download dialog, link to VIEW in EDIT ([9b47b75](https://gitlab.com/macropeople/dcfrontend/commit/9b47b75)) +* enabling clicking of users in groups page ([ab2acc4](https://gitlab.com/macropeople/dcfrontend/commit/ab2acc4)) +* moving to single directory for log / staging data capture. ([766e9fc](https://gitlab.com/macropeople/dcfrontend/commit/766e9fc)) +* pagination of libraries in tree ([5e79ec3](https://gitlab.com/macropeople/dcfrontend/commit/5e79ec3)) +* removing 'multiple file load' feature ([2f21cc4](https://gitlab.com/macropeople/dcfrontend/commit/2f21cc4)) +* removing 'multiple file load' feature ([268fdc1](https://gitlab.com/macropeople/dcfrontend/commit/268fdc1)) +* saving sub-page in navigation, startup service refactor, edit in VIEW dropdown ([98280a9](https://gitlab.com/macropeople/dcfrontend/commit/98280a9)) +* typing on X and prettify JS ([9ab737d](https://gitlab.com/macropeople/dcfrontend/commit/9ab737d)) + + +### Features + +* backup Excel file ([7c5e57e](https://gitlab.com/macropeople/dcfrontend/commit/7c5e57e)) +* **excelIntegration:** upload both csv and excel file ([d90bfdf](https://gitlab.com/macropeople/dcfrontend/commit/d90bfdf)) +* cypress testcases migration ([4fa372c](https://gitlab.com/macropeople/dcfrontend/commit/4fa372c)) +* cypress testcases migration ([e2d9998](https://gitlab.com/macropeople/dcfrontend/commit/e2d9998)) +* cypress testcases migration ([8e6ccc4](https://gitlab.com/macropeople/dcfrontend/commit/8e6ccc4)) +* **excelIntegration:** upload both csv and excel file ([57698b0](https://gitlab.com/macropeople/dcfrontend/commit/57698b0)) + + +### BREAKING CHANGES + +* the previous download links will not work following this upgrade + + + + +## [1.3.3](https://gitlab.com/macropeople/dcfrontend/compare/v1.3.2...v1.3.3) (2020-03-10) + + +### Bug Fixes + +* dups in groups and missing members ([e06b269](https://gitlab.com/macropeople/dcfrontend/commit/e06b269)) + + + + +## [1.3.2](https://gitlab.com/macropeople/dcfrontend/compare/v1.3.1...v1.3.2) (2020-03-09) + + +### Bug Fixes + +* removing duplicates on groupnames ([8e8f99a](https://gitlab.com/macropeople/dcfrontend/commit/8e8f99a)) + + + + +## [1.3.1](https://gitlab.com/macropeople/dcfrontend/compare/v1.3.0...v1.3.1) (2020-03-09) + + + + +# [1.3.0](https://gitlab.com/macropeople/dcfrontend/compare/v1.2.1...v1.3.0) (2020-03-09) + + +### Bug Fixes + +* closes [#73](https://gitlab.com/macropeople/dcfrontend/issues/73), adding test data and faster viewLib service ([3fbfff2](https://gitlab.com/macropeople/dcfrontend/commit/3fbfff2)) +* moving meta specific macros to macros_meta folder ([5bb6fb0](https://gitlab.com/macropeople/dcfrontend/commit/5bb6fb0)) +* recursive join issue (was necessary to have a dependency) ([cf0c4bf](https://gitlab.com/macropeople/dcfrontend/commit/cf0c4bf)) +* services in usernav ([cb6630d](https://gitlab.com/macropeople/dcfrontend/commit/cb6630d)) + + +### Features + +* **usernav:** adding remaining backend services ([2f8ccd2](https://gitlab.com/macropeople/dcfrontend/commit/2f8ccd2)) +* **usernav:** sidebar integration ([60700fb](https://gitlab.com/macropeople/dcfrontend/commit/60700fb)) +* **usernav:** User Navigation ([265c489](https://gitlab.com/macropeople/dcfrontend/commit/265c489)) +* User Navigator services ([505b99b](https://gitlab.com/macropeople/dcfrontend/commit/505b99b)) + + + + +## [1.2.1](https://gitlab.com/macropeople/dcfrontend/compare/v1.2.0...v1.2.1) (2020-02-29) + + +### Bug Fixes + +* IE and Edge hidding libraries ([c59de7c](https://gitlab.com/macropeople/dcfrontend/commit/c59de7c)) +* resizing sidebar improvments ([fe7b4bb](https://gitlab.com/macropeople/dcfrontend/commit/fe7b4bb)) +* view new table, old removed, added column dropdown ([e8d254b](https://gitlab.com/macropeople/dcfrontend/commit/e8d254b)) + + + + +# [1.2.0](https://gitlab.com/macropeople/dcfrontend/compare/v1.1.0...v1.2.0) (2020-02-27) + + +### Bug Fixes + +* model change in selectbox table ([92fd9be](https://gitlab.com/macropeople/dcfrontend/commit/92fd9be)) +* remove autologging and make debug mode false by default ([cc625f0](https://gitlab.com/macropeople/dcfrontend/commit/cc625f0)) +* tree library leftover ([b2b9c07](https://gitlab.com/macropeople/dcfrontend/commit/b2b9c07)) + + +### Features + +* metadata navigator ([80c3fcc](https://gitlab.com/macropeople/dcfrontend/commit/80c3fcc)) +* **metadata navigator:** routing and scroll bar on objects ([9a88e5f](https://gitlab.com/macropeople/dcfrontend/commit/9a88e5f)) +* **metadata navigator:** routing update and repository addition ([571da8f](https://gitlab.com/macropeople/dcfrontend/commit/571da8f)) +* **metadata navigator:** search bar on metatypes ([3b94c0d](https://gitlab.com/macropeople/dcfrontend/commit/3b94c0d)) +* **metadata navigator:** search on metadata objects, design improvements ([1973147](https://gitlab.com/macropeople/dcfrontend/commit/1973147)) + + + + +# [1.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v1.0.2...v1.1.0) (2020-02-26) + + +### Bug Fixes + +* **docs:** direct lib now in settings ([a572625](https://gitlab.com/macropeople/dcfrontend/commit/a572625)) +* adding npm package ([cdb6c87](https://gitlab.com/macropeople/dcfrontend/commit/cdb6c87)) +* dropzone buttons one row ([a630a69](https://gitlab.com/macropeople/dcfrontend/commit/a630a69)) +* edit integration undefined table approval ([b382aa8](https://gitlab.com/macropeople/dcfrontend/commit/b382aa8)) +* editor libraries bug closes [#57](https://gitlab.com/macropeople/dcfrontend/issues/57) ([80c7719](https://gitlab.com/macropeople/dcfrontend/commit/80c7719)) +* header match case insensitivity ([63ed719](https://gitlab.com/macropeople/dcfrontend/commit/63ed719)) +* IE Tree bug, resizing sidebar ([2e0db53](https://gitlab.com/macropeople/dcfrontend/commit/2e0db53)) +* removing call to mm_getlibs and ensuring compatibility with multiple repositories ([2520ddd](https://gitlab.com/macropeople/dcfrontend/commit/2520ddd)) +* this.table ([0877332](https://gitlab.com/macropeople/dcfrontend/commit/0877332)) +* using meta libname in settings ([550b9ce](https://gitlab.com/macropeople/dcfrontend/commit/550b9ce)) +* viewer caching issue ([bdeffe2](https://gitlab.com/macropeople/dcfrontend/commit/bdeffe2)) + + +### Features + +* **excel data integration:** missing columns addition ([5fdab7b](https://gitlab.com/macropeople/dcfrontend/commit/5fdab7b)) +* **excel parsing:** order doesn't matter + wiscard extra columns if exists in between ([c0d0c9a](https://gitlab.com/macropeople/dcfrontend/commit/c0d0c9a)) +* **excel_integration:** header selection method update ([be1e2f6](https://gitlab.com/macropeople/dcfrontend/commit/be1e2f6)) +* download DDL (#closes 43) ([4ff3398](https://gitlab.com/macropeople/dcfrontend/commit/4ff3398)) +* download DDL ([9a70fff](https://gitlab.com/macropeople/dcfrontend/commit/9a70fff)) +* excel data Integration ([f630f1d](https://gitlab.com/macropeople/dcfrontend/commit/f630f1d)) +* **excelIntegration:** Date time header validations ([2213bee](https://gitlab.com/macropeople/dcfrontend/commit/2213bee)) +* list of metadata repos (new service) ([7d5e17e](https://gitlab.com/macropeople/dcfrontend/commit/7d5e17e)) +* usage tracking. closes [#45](https://gitlab.com/macropeople/dcfrontend/issues/45) ([dccd7fa](https://gitlab.com/macropeople/dcfrontend/commit/dccd7fa)) +* wide drap/drop and auto upload on file drop ([b02cfc2](https://gitlab.com/macropeople/dcfrontend/commit/b02cfc2)) + + + + +## [1.0.2](https://gitlab.com/macropeople/dcfrontend/compare/v1.0.1...v1.0.2) (2020-02-12) + + +### Bug Fixes + +* approve page overflow ([711401a](https://gitlab.com/macropeople/dcfrontend/commit/711401a)) +* editor page overlaying header bar ([a9cd778](https://gitlab.com/macropeople/dcfrontend/commit/a9cd778)) +* moving JS to be exernal ([05c41ba](https://gitlab.com/macropeople/dcfrontend/commit/05c41ba)) +* moving JS to be exernal ([5b85773](https://gitlab.com/macropeople/dcfrontend/commit/5b85773)) +* perms ([6721a67](https://gitlab.com/macropeople/dcfrontend/commit/6721a67)) +* sidebar duplicates and double selection ([edade84](https://gitlab.com/macropeople/dcfrontend/commit/edade84)) + + + + +## [1.0.1](https://gitlab.com/macropeople/dcfrontend/compare/v1.0.0...v1.0.1) (2020-02-11) + + +### Bug Fixes + +* migration mpe-security ([7cd7896](https://gitlab.com/macropeople/dcfrontend/commit/7cd7896)) +* moving scripts.js to external site in demo version ([49ad2c0](https://gitlab.com/macropeople/dcfrontend/commit/49ad2c0)) + + + + +# [1.0.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.12.1...v1.0.0) (2020-02-09) + + +### Chores + +* remove whitespace ([89fc982](https://gitlab.com/macropeople/dcfrontend/commit/89fc982)) + + +### BREAKING CHANGES + +* seems this needs to be in the footer for it to work + + + + +## [0.12.1](https://gitlab.com/macropeople/dcfrontend/compare/v0.12.0...v0.12.1) (2020-02-09) + + + + +# [0.12.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.11.2...v0.12.0) (2020-02-09) + + +### Bug Fixes + +* **new design:** clarity new version fixed elements (inputs, selects...) ([755a41c](https://gitlab.com/macropeople/dcfrontend/commit/755a41c)) +* **new design:** filter input elements (broken due new clr version) ([338faf8](https://gitlab.com/macropeople/dcfrontend/commit/338faf8)) +* issue20 security updates ([f7168b7](https://gitlab.com/macropeople/dcfrontend/commit/f7168b7)) +* new design, viewer sidebar optimizing ([bb29fb7](https://gitlab.com/macropeople/dcfrontend/commit/bb29fb7)) + + +### Features + +* **new design:** lineage component ([2e070c0](https://gitlab.com/macropeople/dcfrontend/commit/2e070c0)) +* **new design:** sidebar searchboxes ([b6cca58](https://gitlab.com/macropeople/dcfrontend/commit/b6cca58)) +* New Design ([a4f41da](https://gitlab.com/macropeople/dcfrontend/commit/a4f41da)), closes [#35](https://gitlab.com/macropeople/dcfrontend/issues/35) +* new design: lineage started ([6e1ead1](https://gitlab.com/macropeople/dcfrontend/commit/6e1ead1)) +* selectively disable tables in VIEW ([44a418e](https://gitlab.com/macropeople/dcfrontend/commit/44a418e)) +* TIME support (minus time picker). closes #issue42 ([a16e240](https://gitlab.com/macropeople/dcfrontend/commit/a16e240)), closes [#issue42](https://gitlab.com/macropeople/dcfrontend/issues/issue42) + + + + +## [0.11.2](https://gitlab.com/macropeople/dcfrontend/compare/v0.11.1...v0.11.2) (2020-01-31) + + +### Bug Fixes + +* missing macro in bitemporal loader ([7681d46](https://gitlab.com/macropeople/dcfrontend/commit/7681d46)) + + + + +## [0.11.1](https://gitlab.com/macropeople/dcfrontend/compare/v0.11.0...v0.11.1) (2020-01-29) + + +### Bug Fixes + +* enabling embedded carriage returns ([d9422dc](https://gitlab.com/macropeople/dcfrontend/commit/d9422dc)) + + + + +# [0.11.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.10.1...v0.11.0) (2020-01-28) + + +### Bug Fixes + +* short numerics and best. format numerics now handled ([b7c1279](https://gitlab.com/macropeople/dcfrontend/commit/b7c1279)) +* stp registration ([8afa679](https://gitlab.com/macropeople/dcfrontend/commit/8afa679)) + + +### Features + +* short numerics ([c840b79](https://gitlab.com/macropeople/dcfrontend/commit/c840b79)) + + + + +## [0.10.1](https://gitlab.com/macropeople/dcfrontend/compare/v0.10.0...v0.10.1) (2020-01-28) + + +### Bug Fixes + +* short numerics and numeric formats, #closes issue40 ([eb5893c](https://gitlab.com/macropeople/dcfrontend/commit/eb5893c)) + + + + +# [0.10.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.9.0...v0.10.0) (2020-01-25) + + +### Bug Fixes + +* adding more sample data ([89b25d1](https://gitlab.com/macropeople/dcfrontend/commit/89b25d1)) +* editor column max width ([8e803fc](https://gitlab.com/macropeople/dcfrontend/commit/8e803fc)) +* editor file upload abort message ([10cad83](https://gitlab.com/macropeople/dcfrontend/commit/10cad83)) +* lineage regenerate problem ([354d126](https://gitlab.com/macropeople/dcfrontend/commit/354d126)) +* sample data ([b743892](https://gitlab.com/macropeople/dcfrontend/commit/b743892)) +* viewer / editor column max width ([6c3abc7](https://gitlab.com/macropeople/dcfrontend/commit/6c3abc7)) + + +### Features + +* groups plus metadata refresh backend ([850f29a](https://gitlab.com/macropeople/dcfrontend/commit/850f29a)) +* lineage refresh cache option ([35d1b6c](https://gitlab.com/macropeople/dcfrontend/commit/35d1b6c)) +* max col width 500 plus custom groups feature ([5d5b55b](https://gitlab.com/macropeople/dcfrontend/commit/5d5b55b)) +* metadata services ([697642c](https://gitlab.com/macropeople/dcfrontend/commit/697642c)) + + + + +# [0.9.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.8.0...v0.9.0) (2020-01-19) + + +### Bug Fixes + +* maxdepth for lineage ([28cf028](https://gitlab.com/macropeople/dcfrontend/commit/28cf028)) +* MAXOBS for editing data ([5ada758](https://gitlab.com/macropeople/dcfrontend/commit/5ada758)) + + +### Features + +* 9.3 compatibility (remove fcmp in windows, updating adapter) ([11e7692](https://gitlab.com/macropeople/dcfrontend/commit/11e7692)) +* admin tools (config viewer and download) ([a95ed90](https://gitlab.com/macropeople/dcfrontend/commit/a95ed90)) +* extra checking to ensure the install user has the correct metadata and OS permissions ([4ef83db](https://gitlab.com/macropeople/dcfrontend/commit/4ef83db)) +* licence checker plus adding MPE_SELECTBOX to config download ([5109670](https://gitlab.com/macropeople/dcfrontend/commit/5109670)) + + + + +# [0.8.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.7.2...v0.8.0) (2020-01-13) + + +### Bug Fixes + +* lineage table removal ([e28cb59](https://gitlab.com/macropeople/dcfrontend/commit/e28cb59)) +* removing configurator after it is run (to prevent accidental overwrite once library is up and running) ([8759226](https://gitlab.com/macropeople/dcfrontend/commit/8759226)) +* removing stp dependency in mpeinit ([44d3c63](https://gitlab.com/macropeople/dcfrontend/commit/44d3c63)) + + +### Features + +* lineage flatdata csv download ([fce560f](https://gitlab.com/macropeople/dcfrontend/commit/fce560f)) + + + + +## [0.7.2](https://gitlab.com/macropeople/dcfrontend/compare/v0.7.1...v0.7.2) (2020-01-11) + + +### Bug Fixes + +* empty lineage screen now displays ([9876ff9](https://gitlab.com/macropeople/dcfrontend/commit/9876ff9)) + + + + +## [0.7.1](https://gitlab.com/macropeople/dcfrontend/compare/v0.7.0...v0.7.1) (2020-01-07) + + + + +# [0.7.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.6.0...v0.7.0) (2020-01-02) + + +### Bug Fixes + +* adding port to web query ([07e6a5d](https://gitlab.com/macropeople/dcfrontend/commit/07e6a5d)) +* closes [#32](https://gitlab.com/macropeople/dcfrontend/issues/32) and enbles viewing of tables that only exist in metadata ([c942b21](https://gitlab.com/macropeople/dcfrontend/commit/c942b21)) +* dropdown to download button inside popup ([ceb5b75](https://gitlab.com/macropeople/dcfrontend/commit/ceb5b75)) +* dropdowns and buttons reposition, saving space for lineage graph ([e95a713](https://gitlab.com/macropeople/dcfrontend/commit/e95a713)) +* editor table, dot check removed ([9612323](https://gitlab.com/macropeople/dcfrontend/commit/9612323)) +* IE editor library dropdown, lineage selection width ([9a1c923](https://gitlab.com/macropeople/dcfrontend/commit/9a1c923)) +* index.html metadata ([83fb505](https://gitlab.com/macropeople/dcfrontend/commit/83fb505)) +* index.html metadata ([ff0c552](https://gitlab.com/macropeople/dcfrontend/commit/ff0c552)) +* index.html metadata comment update ([c2e337f](https://gitlab.com/macropeople/dcfrontend/commit/c2e337f)) +* lineage download buttons hidden ([9227ccc](https://gitlab.com/macropeople/dcfrontend/commit/9227ccc)) +* lineage more space ([f2e6375](https://gitlab.com/macropeople/dcfrontend/commit/f2e6375)) +* lineage popup remove, positions, linkable ([9d53f2a](https://gitlab.com/macropeople/dcfrontend/commit/9d53f2a)) +* linking lineage ([4c2095b](https://gitlab.com/macropeople/dcfrontend/commit/4c2095b)) +* padding issues, editor table loading fix ([bc0c2be](https://gitlab.com/macropeople/dcfrontend/commit/bc0c2be)) + + +### Features + +* IE compatibility ([e28ac50](https://gitlab.com/macropeople/dcfrontend/commit/e28ac50)) +* linkable lineage ([d8ebc19](https://gitlab.com/macropeople/dcfrontend/commit/d8ebc19)) + + + + +# [0.6.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.5.0...v0.6.0) (2019-12-14) + + +### Bug Fixes + +* package updates ([03ace1f](https://gitlab.com/macropeople/dcfrontend/commit/03ace1f)) + + +### Features + +* lineage and metarepo option ([99090a1](https://gitlab.com/macropeople/dcfrontend/commit/99090a1)) +* Add Data Lineage ([b21a644](https://gitlab.com/macropeople/dcfrontend/commit/b21a644)) + + + + +# [0.5.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.4.0...v0.5.0) (2019-09-20) + + +### Bug Fixes + +* error message not surfaced on VIEW table, closes [#25](https://gitlab.com/macropeople/dcfrontend/issues/25) ([4687ec4](https://gitlab.com/macropeople/dcfrontend/commit/4687ec4)) +* format length issue, special chars in usernames issue ([447f483](https://gitlab.com/macropeople/dcfrontend/commit/447f483)) +* removing npm audit warnings with devkit update to 13.9 ([e1d28a9](https://gitlab.com/macropeople/dcfrontend/commit/e1d28a9)) + + +### Features + +* improved deployment process for evaluation version ([3a9e846](https://gitlab.com/macropeople/dcfrontend/commit/3a9e846)) +* Allow WLatin file upload ([1c02491](https://gitlab.com/macropeople/dcfrontend/commit/1c02491)) +* auto config for eval version ([35ab667](https://gitlab.com/macropeople/dcfrontend/commit/35ab667)) + + + + +# [0.4.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.3.0...v0.4.0) (2019-05-27) + + +### Bug Fixes + +* additional types added ([279fb6c](https://gitlab.com/macropeople/dcfrontend/commit/279fb6c)) +* editor dropdown remember selections ([75391eb](https://gitlab.com/macropeople/dcfrontend/commit/75391eb)) +* email fixes ([996b14b](https://gitlab.com/macropeople/dcfrontend/commit/996b14b)) +* email issues ([c74f668](https://gitlab.com/macropeople/dcfrontend/commit/c74f668)) +* filter remebering | cleanup ([bd59204](https://gitlab.com/macropeople/dcfrontend/commit/bd59204)) +* issue 18, use strict ([a4ac751](https://gitlab.com/macropeople/dcfrontend/commit/a4ac751)) +* issue 19 ([ca67123](https://gitlab.com/macropeople/dcfrontend/commit/ca67123)) +* metadataRoot added back ([50243a3](https://gitlab.com/macropeople/dcfrontend/commit/50243a3)) +* remember filter editor ([6fe1545](https://gitlab.com/macropeople/dcfrontend/commit/6fe1545)) +* remember filter selections ([774a42e](https://gitlab.com/macropeople/dcfrontend/commit/774a42e)) +* remember filter viewer ([de53590](https://gitlab.com/macropeople/dcfrontend/commit/de53590)) +* remembering filter selections issue15 ([d86326a](https://gitlab.com/macropeople/dcfrontend/commit/d86326a)) +* remembering filter without regenerating ([f5fa1dd](https://gitlab.com/macropeople/dcfrontend/commit/f5fa1dd)) +* remembering selections | running service onliy on startup ([f8aeef5](https://gitlab.com/macropeople/dcfrontend/commit/f8aeef5)) +* removed some settings ([222001a](https://gitlab.com/macropeople/dcfrontend/commit/222001a)) +* removing col freeze as not ready yet ([a8ac2bc](https://gitlab.com/macropeople/dcfrontend/commit/a8ac2bc)) +* removing not null constraints ([b4f4ba8](https://gitlab.com/macropeople/dcfrontend/commit/b4f4ba8)) +* save selected library and table ([c98bdfd](https://gitlab.com/macropeople/dcfrontend/commit/c98bdfd)) +* unique urls in prod build ([605de8a](https://gitlab.com/macropeople/dcfrontend/commit/605de8a)) +* unique urls in prod build ([b749b35](https://gitlab.com/macropeople/dcfrontend/commit/b749b35)) +* upgrading handsontable to 7.03 ([08200e0](https://gitlab.com/macropeople/dcfrontend/commit/08200e0)) +* viewer dropdowns remember selections ([189304c](https://gitlab.com/macropeople/dcfrontend/commit/189304c)) +* viewer dropdowns remember selections ([ae29b42](https://gitlab.com/macropeople/dcfrontend/commit/ae29b42)) + + +### Features + +* adding email options in log in mpe_alerts ([e546d8e](https://gitlab.com/macropeople/dcfrontend/commit/e546d8e)) +* adding dropdowns to mpe_alerts table by default ([f43db13](https://gitlab.com/macropeople/dcfrontend/commit/f43db13)) +* adding frontend filtering, column freeze, and readonly column switch ([003373a](https://gitlab.com/macropeople/dcfrontend/commit/003373a)) +* always on debug plus siteid linking for eval version ([fa0a418](https://gitlab.com/macropeople/dcfrontend/commit/fa0a418)) +* locking down eval version to a siteid ([bfb6325](https://gitlab.com/macropeople/dcfrontend/commit/bfb6325)) + + + + +# [0.3.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.2.0...v0.3.0) (2019-04-11) + + +### Bug Fixes + +* closes [#16](https://gitlab.com/macropeople/dcfrontend/issues/16), missing getAuditFile ([e6b6717](https://gitlab.com/macropeople/dcfrontend/commit/e6b6717)) +* issue12 dev work ([8b547af](https://gitlab.com/macropeople/dcfrontend/commit/8b547af)) +* missing macro in loadfile ([334b4a2](https://gitlab.com/macropeople/dcfrontend/commit/334b4a2)) +* problem with file upload. Also enabling licence key implementation on view & stage components. ([0f186e5](https://gitlab.com/macropeople/dcfrontend/commit/0f186e5)) + + +### Features + +* enabling multiColumnSort and manualColumnResize. Closes [#1](https://gitlab.com/macropeople/dcfrontend/issues/1) and closes [#13](https://gitlab.com/macropeople/dcfrontend/issues/13). ([56dfc90](https://gitlab.com/macropeople/dcfrontend/commit/56dfc90)) +* moving ALL config vars to MPE_CONFIG table. Closes [#11](https://gitlab.com/macropeople/dcfrontend/issues/11) ([6132793](https://gitlab.com/macropeople/dcfrontend/commit/6132793)) + + + + +# [0.2.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.1.0...v0.2.0) (2019-04-07) + + +### Bug Fixes + +* failing file uploads in demo version of DC resolved. closes [#9](https://gitlab.com/macropeople/dcfrontend/issues/9) ([f0a6aeb](https://gitlab.com/macropeople/dcfrontend/commit/f0a6aeb)) +* missing mf_abort in getStageTable ([97f0c66](https://gitlab.com/macropeople/dcfrontend/commit/97f0c66)) + + +### Features + +* switch settings to be an STP for easier modification ([a28057d](https://gitlab.com/macropeople/dcfrontend/commit/a28057d)) +* adding switch for library checking, no by default to improve responsiveness. Closes [#7](https://gitlab.com/macropeople/dcfrontend/issues/7) ([adcacf5](https://gitlab.com/macropeople/dcfrontend/commit/adcacf5)) +* enabling emails on SUBMIT, APPROVE and REJECT. Closes [#10](https://gitlab.com/macropeople/dcfrontend/issues/10) ([daec738](https://gitlab.com/macropeople/dcfrontend/commit/daec738)) + + + + +# [0.1.0](https://gitlab.com/macropeople/dcfrontend/compare/v0.0.1...v0.1.0) (2019-04-03) + + +### Bug Fixes + +* accidental deletion ([8236438](https://gitlab.com/macropeople/dcfrontend/commit/8236438)) +* enabling build ([f5e8807](https://gitlab.com/macropeople/dcfrontend/commit/f5e8807)) +* fixes to fix demo version ([6cf6c69](https://gitlab.com/macropeople/dcfrontend/commit/6cf6c69)) +* removing console logs ([3d6e6f2](https://gitlab.com/macropeople/dcfrontend/commit/3d6e6f2)) +* upgrade to avoid npm warnings ([d8f90c3](https://gitlab.com/macropeople/dcfrontend/commit/d8f90c3)) + + +### Features + +* **clarity:** the styling now workscd .. ([28b2db5](https://gitlab.com/macropeople/dcfrontend/commit/28b2db5)) +* single SPK compilation ([b785d84](https://gitlab.com/macropeople/dcfrontend/commit/b785d84)) +* removing app component replacing with document object, which is safer when importing SPKs over existing packages ([0ba14ed](https://gitlab.com/macropeople/dcfrontend/commit/0ba14ed)) + + + + +## 0.0.1 (2019-01-27) + + +### Bug Fixes + +* Adding new rows now works ([8685b4e](https://gitlab.com/macropeople/dcfrontend/commit/8685b4e)) +* removing invalid json ([7dd24e0](https://gitlab.com/macropeople/dcfrontend/commit/7dd24e0)) +* removing version.ts from source control ([186c669](https://gitlab.com/macropeople/dcfrontend/commit/186c669)) +* removing version.ts from source control, now with gitignore ([2c8ccf8](https://gitlab.com/macropeople/dcfrontend/commit/2c8ccf8)) + + +### Features + +* removing font ([325f193](https://gitlab.com/macropeople/dcfrontend/commit/325f193)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7ad7a6a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,66 @@ +# Data Controller +# Contributing + +## Dependencies that requires licences + +[SheetJS Pro Version](https://www.npmjs.com/package/sheetjs) + + +To auth for SheetJS Pro version you need to use their private registry +Add `client/.npmrc` file with following content: +``` +@sheet:registry=https://pylon.sheetjs.com:54111/ +//pylon.sheetjs.com:54111/:_authToken="TOKEN-GOES-HERE" +``` + +[Handsontable](https://www.npmjs.com/package/handsontable) + +Licence should be inserted in the `client/src/index.html` file: + +``` + + +``` +## Development +Update `client/src/index.html` so that it points to your SAS9, SASVIYA or SASJS backend. +Be aware that VIYA can be configured in such way that it would not work with cross origin frontend. +Follow this guide to disable CORS: https://sasjs.io/cors/ (NOTICE: Sometimes even this approach would fail to work, in such case it is imposible to set it up without reconfiguring the VIYA server) + +Start dev server: +``` +cd client + +npm start +``` + +## GUI Elements + +For documentation on the Clarity Design System, including a list of components and example usage, see [our website](https://vmware.github.io/clarity). + +## Code style +Run prettier fix: +```bash +npm run lint:fix +``` + +## Generate docs +Typedoc is used for generating typescript documentation based on the code. +That part is automated and beign done as a part of CI job. + +# Troubleshooting + +## Makedata service "could not create directory" error + +The dcpath folder should have its permissions set so that the system account (SYSUSERID) can both read and write to it. + +Example: + +If dcpath is: '/tmp/dc' + +Run: +``` +chmod 777 /tmp/dc +``` \ No newline at end of file diff --git a/LICENCE.md b/LICENCE.md new file mode 100644 index 0000000..ce65cf9 --- /dev/null +++ b/LICENCE.md @@ -0,0 +1,27 @@ +Licence Agreement for Data Controller for SAS® +==================== + +Copyright (c) Bowe IO Ltd + +Data Controller is a software distributed by 4GL Apps, a brand owned by Bowe IO Ltd, a UK Limited Company headquarted in 29 Oldfield Rd, Cumbria, registered by companies house under number 08777171, VAT number: 203914240 + +This software is protected by applicable copyright laws, including international treaties, and dual- +licensed – depending on whether your use for commercial purposes, meaning intended for or +resulting in commercial advantage or monetary compensation, or not. + +If your use is strictly personal or solely for evaluation purposes, meaning for the purposes of testing +the suitability, performance, and usefulness of this software outside the production environment, +you agree to be bound by the terms included in the "licence-non-commercial-datacontroller.md" file. + +Your use of this software for commercial purposes is subject to the terms included in an applicable +license agreement. + +In any case, you must not make any such use of this software as to develop software which may be +considered competitive with this software. + +UNLESS EXPRESSLY AGREED OTHERWISE, 4GL APPS PROVIDES THIS SOFTWARE ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, AND IN NO EVENT AND UNDER NO +LEGAL THEORY, SHALL 4GL APPS BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM +USE OR INABILITY TO USE THIS SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/client/.dockerignore b/client/.dockerignore new file mode 100644 index 0000000..f95b09f --- /dev/null +++ b/client/.dockerignore @@ -0,0 +1,14 @@ +.vscode/ +coverage/ +docs/ +html-report/ +node_modules/ +typings/ +**/*npm-debug.log.* +**/*yarn-error.log.* +.idea/ +.DS_Store +cypress/screenshots +cypress/videos +.env* +.sasjsrc diff --git a/client/.editorconfig b/client/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/client/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/client/.eslintrc.json b/client/.eslintrc.json new file mode 100644 index 0000000..c7a3034 --- /dev/null +++ b/client/.eslintrc.json @@ -0,0 +1,46 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended" + ], + "rules": {} + } + ] +} diff --git a/client/.hintrc b/client/.hintrc new file mode 100644 index 0000000..ee107bc --- /dev/null +++ b/client/.hintrc @@ -0,0 +1,5 @@ +{ + "extends": [ + "development" + ] +} \ No newline at end of file diff --git a/client/.vscode/.editorconfig b/client/.vscode/.editorconfig new file mode 100644 index 0000000..831610e --- /dev/null +++ b/client/.vscode/.editorconfig @@ -0,0 +1,9 @@ +{ + "search.exclude": { + "**/sasjsbuild/**": true, + "**/dist/**":true + }, + "editor.insertSpaces": true, + "editor.tabSize": 2, + "trim_trailing_whitespace": true +} diff --git a/client/.vscode/launch.json b/client/.vscode/launch.json new file mode 100644 index 0000000..8f814bd --- /dev/null +++ b/client/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "attach", + "name": "Launch Chrome", + "port": 9222, + "webRoot": "${workspaceFolder}" + } + ] +} diff --git a/client/.vscode/settings.json b/client/.vscode/settings.json new file mode 100644 index 0000000..dcd791d --- /dev/null +++ b/client/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.trimTrailingWhitespace": true, + "editor.rulers": [ + 107 + ] +} \ No newline at end of file diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 0000000..43f720a --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,13 @@ +FROM node:14-alpine as builder +WORKDIR '/app' +COPY ./package.json ./ +COPY ./package-lock.json ./ +COPY ./.npmrc ./ +RUN npm i +COPY . . +RUN npm run build + +FROM nginx +EXPOSE 3000 +COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/dist /usr/share/nginx/html diff --git a/client/Dockerfile.dev b/client/Dockerfile.dev new file mode 100644 index 0000000..a537f3b --- /dev/null +++ b/client/Dockerfile.dev @@ -0,0 +1,8 @@ +FROM node:14-alpine +WORKDIR '/app' +COPY ./package.json ./ +COPY ./package-lock.json ./ +COPY ./.npmrc ./ +RUN npm i +COPY . . +CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/client/angular.json b/client/angular.json new file mode 100644 index 0000000..6a8c96c --- /dev/null +++ b/client/angular.json @@ -0,0 +1,169 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "cli": { + "analytics": false + }, + "version": 1, + "newProjectRoot": "projects", + "projects": { + "datacontroller": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + }, + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "allowedCommonJsDependencies": [ + "handsontable", + "core-js", + "pikaday", + "querystring", + "punycode", + "url", + "rxjs", + "rxjs-compat", + "d3-graphviz", + "save-svg-as-png", + "@sheet/perf", + "@sheet/crypto", + "iconv-lite", + "buffer/", + "zone.js", + "text-encoding", + "crypto-js/md5", + "buffer", + "numbro", + "@clr/icons", + "@sasjs/adapter", + "@sasjs/utils/input/validators", + "@sasjs/utils/utils/bytesToSize", + "base64-arraybuffer", + "@handsontable/formulajs" + ], + "polyfills": [ + "src/polyfills.ts", + "zone.js" + ], + "outputPath": "dist", + "resourcesOutputPath": "images", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/images" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [ + "node_modules/@clr/icons/clr-icons.min.js", + "node_modules/marked/marked.min.js" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "13mb", + "maximumError": "15mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "7kb", + "maximumError": "10kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all", + "optimization": { + "scripts": true, + "styles": { + "minify": true, + "inlineCritical": false + }, + "fonts": true + } + }, + "development": { + "vendorChunk": true, + "extractLicenses": false, + "buildOptimizer": false, + "sourceMap": true, + "optimization": false, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "datacontroller:build:production" + }, + "development": { + "browserTarget": "datacontroller:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "datacontroller:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "codeCoverage": true, + "polyfills": [ + "src/polyfills.ts", + "zone.js", + "zone.js/testing" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [ + + ], + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "karmaConfig": "karma.conf.js" + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } + } + } + } + } +} diff --git a/client/cypress.config.ts b/client/cypress.config.ts new file mode 100644 index 0000000..0d639a2 --- /dev/null +++ b/client/cypress.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + reporter: 'mochawesome', + reporterOptions: { + reportDir: 'cypress/results', + overwrite: false, + html: true, + json: false, + }, + chromeWebSecurity: false, + defaultCommandTimeout: 30000, + env: { + hosturl:"http://localhost:4200", + appLocation: "", + site_id_SAS9: "70221618", + site_id_SASVIYA: "70253615", + site_id_SASJS: "123", + serverType: "SASJS", + libraryToOpenIncludes_SASVIYA: "viya", + libraryToOpenIncludes_SAS9: "dc", + libraryToOpenIncludes_SASJS: "dc", + debug: false, + screenshotOnRunFailure: false, + longerCommandTimeout: 50000, + testLicenceUserLimits: false + } +}) diff --git a/client/cypress.env.example.json b/client/cypress.env.example.json new file mode 100644 index 0000000..697b15f --- /dev/null +++ b/client/cypress.env.example.json @@ -0,0 +1,4 @@ +{ + "username": "sas_username", + "password": "sas_password" +} \ No newline at end of file diff --git a/client/cypress/fixtures/example.json b/client/cypress/fixtures/example.json new file mode 100644 index 0000000..da18d93 --- /dev/null +++ b/client/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} \ No newline at end of file diff --git a/client/cypress/fixtures/excels/15mb_excel.xlsx b/client/cypress/fixtures/excels/15mb_excel.xlsx new file mode 100644 index 0000000..b15d2bb Binary files /dev/null and b/client/cypress/fixtures/excels/15mb_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/5mb_excel.xlsx b/client/cypress/fixtures/excels/5mb_excel.xlsx new file mode 100644 index 0000000..e53a8a6 Binary files /dev/null and b/client/cypress/fixtures/excels/5mb_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/7th_tab_excel.xlsx b/client/cypress/fixtures/excels/7th_tab_excel.xlsx new file mode 100644 index 0000000..310255c Binary files /dev/null and b/client/cypress/fixtures/excels/7th_tab_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/MPE_DATADICTIONARY_composite_keys.xlsx b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_composite_keys.xlsx new file mode 100644 index 0000000..a269f01 Binary files /dev/null and b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_composite_keys.xlsx differ diff --git a/client/cypress/fixtures/excels/MPE_DATADICTIONARY_merged_cells.xlsx b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_merged_cells.xlsx new file mode 100644 index 0000000..70b5a78 Binary files /dev/null and b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_merged_cells.xlsx differ diff --git a/client/cypress/fixtures/excels/MPE_DATADICTIONARY_missing_row.xlsx b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_missing_row.xlsx new file mode 100644 index 0000000..ae3a955 Binary files /dev/null and b/client/cypress/fixtures/excels/MPE_DATADICTIONARY_missing_row.xlsx differ diff --git a/client/cypress/fixtures/excels/blank_column_with_header.xlsx b/client/cypress/fixtures/excels/blank_column_with_header.xlsx new file mode 100644 index 0000000..2fc93dc Binary files /dev/null and b/client/cypress/fixtures/excels/blank_column_with_header.xlsx differ diff --git a/client/cypress/fixtures/excels/blank_columns_excel.xlsx b/client/cypress/fixtures/excels/blank_columns_excel.xlsx new file mode 100644 index 0000000..953d38d Binary files /dev/null and b/client/cypress/fixtures/excels/blank_columns_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/duplicate_column_excel.xlsx b/client/cypress/fixtures/excels/duplicate_column_excel.xlsx new file mode 100644 index 0000000..f304cf8 Binary files /dev/null and b/client/cypress/fixtures/excels/duplicate_column_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/duplicate_row_excel.xlsx b/client/cypress/fixtures/excels/duplicate_row_excel.xlsx new file mode 100644 index 0000000..584fcd9 Binary files /dev/null and b/client/cypress/fixtures/excels/duplicate_row_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/extra_column_excel.xlsx b/client/cypress/fixtures/excels/extra_column_excel.xlsx new file mode 100644 index 0000000..fdf6e3e Binary files /dev/null and b/client/cypress/fixtures/excels/extra_column_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/formulas_excel.bak b/client/cypress/fixtures/excels/formulas_excel.bak new file mode 100644 index 0000000..0e51454 Binary files /dev/null and b/client/cypress/fixtures/excels/formulas_excel.bak differ diff --git a/client/cypress/fixtures/excels/formulas_excel.xlsx b/client/cypress/fixtures/excels/formulas_excel.xlsx new file mode 100644 index 0000000..acb163d Binary files /dev/null and b/client/cypress/fixtures/excels/formulas_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/missing_columns_excel.xlsx b/client/cypress/fixtures/excels/missing_columns_excel.xlsx new file mode 100644 index 0000000..5ce1a73 Binary files /dev/null and b/client/cypress/fixtures/excels/missing_columns_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/mixed_content_excel.xlsx b/client/cypress/fixtures/excels/mixed_content_excel.xlsx new file mode 100644 index 0000000..ad9436d Binary files /dev/null and b/client/cypress/fixtures/excels/mixed_content_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/nodata_rows_excel.xlsx b/client/cypress/fixtures/excels/nodata_rows_excel.xlsx new file mode 100644 index 0000000..15ee0a9 Binary files /dev/null and b/client/cypress/fixtures/excels/nodata_rows_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/regular_excel.xlsx b/client/cypress/fixtures/excels/regular_excel.xlsx new file mode 100644 index 0000000..26741ab Binary files /dev/null and b/client/cypress/fixtures/excels/regular_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/regular_excel_macro.xlsm b/client/cypress/fixtures/excels/regular_excel_macro.xlsm new file mode 100644 index 0000000..e383d26 Binary files /dev/null and b/client/cypress/fixtures/excels/regular_excel_macro.xlsm differ diff --git a/client/cypress/fixtures/excels/regular_excel_with_delete.bak b/client/cypress/fixtures/excels/regular_excel_with_delete.bak new file mode 100644 index 0000000..fefe2e6 Binary files /dev/null and b/client/cypress/fixtures/excels/regular_excel_with_delete.bak differ diff --git a/client/cypress/fixtures/excels/regular_excel_with_delete.xlsx b/client/cypress/fixtures/excels/regular_excel_with_delete.xlsx new file mode 100644 index 0000000..c3c6e69 Binary files /dev/null and b/client/cypress/fixtures/excels/regular_excel_with_delete.xlsx differ diff --git a/client/cypress/fixtures/excels/regular_excel_xls.xls b/client/cypress/fixtures/excels/regular_excel_xls.xls new file mode 100644 index 0000000..91c663b Binary files /dev/null and b/client/cypress/fixtures/excels/regular_excel_xls.xls differ diff --git a/client/cypress/fixtures/excels/surrounded_data_all_cells_empty_excel.xlsx b/client/cypress/fixtures/excels/surrounded_data_all_cells_empty_excel.xlsx new file mode 100644 index 0000000..0fb8a59 Binary files /dev/null and b/client/cypress/fixtures/excels/surrounded_data_all_cells_empty_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/surrounded_data_empty_cells_excel.xlsx b/client/cypress/fixtures/excels/surrounded_data_empty_cells_excel.xlsx new file mode 100644 index 0000000..de744f3 Binary files /dev/null and b/client/cypress/fixtures/excels/surrounded_data_empty_cells_excel.xlsx differ diff --git a/client/cypress/fixtures/excels/surrounded_data_excel.xlsx b/client/cypress/fixtures/excels/surrounded_data_excel.xlsx new file mode 100644 index 0000000..d0d419c Binary files /dev/null and b/client/cypress/fixtures/excels/surrounded_data_excel.xlsx differ diff --git a/client/cypress/fixtures/excels_general/MPE_DATADICTIONARY_duplicate_keys.xlsx b/client/cypress/fixtures/excels_general/MPE_DATADICTIONARY_duplicate_keys.xlsx new file mode 100644 index 0000000..8078633 Binary files /dev/null and b/client/cypress/fixtures/excels_general/MPE_DATADICTIONARY_duplicate_keys.xlsx differ diff --git a/client/cypress/integration/download.tests.ts b/client/cypress/integration/download.tests.ts new file mode 100644 index 0000000..a1d72f7 --- /dev/null +++ b/client/cypress/integration/download.tests.ts @@ -0,0 +1,255 @@ +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels_general/' +const downloadsFolder = Cypress.config('downloadsFolder') + +import { deleteDownloadsFolder } from '../util/deleteDownloadFolder' + +context('download files test: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + cy.get('input.username').type(username) + cy.get('input.password').type(password) + cy.get('.login-group button').click() + + visitPage('home') + }) + + this.afterEach(() => { + deleteDownloadsFolder() + }) + + it('1 | downloads audit file', (done) => { + visitPage('approve/toapprove') + + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.btn.btn-success') + .should('be.visible') + .then((buttons) => { + buttons[0].click() + const id = buttons[0].id + + checkForFileDownloaded(id, 'zip', () => done()) + }) + }) + }) + + it('2 | downloads viewer csv', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('CSV') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'csv', () => done()) + }) + }) + }) + }) + + it('3 | downloads viewer excel', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('Excel') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'xlsx', () => done()) + }) + }) + }) + }) + + it('4 | downloads viewer SAS Datalines', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('SAS Datalines') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'sas', () => done()) + }) + }) + }) + }) + + it('5 | downloads viewer SAS DDL', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('SAS DDL') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'ddl', () => done(), '_') + }) + }) + }) + }) + + it('6 | downloads viewer TSQL DDL', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('TSQL DDL') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'ddl', () => done(), '_') + }) + }) + }) + }) + + it('7 | downloads viewer PGSQL DDL', (done) => { + visitPage('view/data') + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openDownloadModal(() => { + cy.get('select') + .select('PGSQL DDL') + .then(() => { + cy.get('.btn.btn-sm.btn-success-outline').then((button) => { + button.trigger('click') + + const id = button[0].id + + checkForFileDownloaded(id, 'ddl', () => done(), '_') + }) + }) + }) + }) + + this.afterEach(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + }) + + this.afterAll(() => { + cy.visit(`https://sas.4gl.io/mihmed/cypress_finish`) + }) +}) + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} + +const checkForFileDownloaded = ( + id: string, + extension: string, + callback?: any, + libDivider: string = '.' +) => { + cy.on('url:changed', (newUrl) => { + console.log('newUrl', newUrl) + }) + + id = id.replace('.', libDivider) + + const filename = downloadsFolder + '/' + id + '.' + extension + // browser might take a while to download the file, + // so use "cy.readFile" to retry until the file exists + // and has length - and we assume that it has finished downloading then + cy.readFile(filename, { timeout: longerCommandTimeout }) + .should('have.length.gt', 10) + .then((file) => { + if (callback) callback() + }) +} + +const openDownloadModal = (callback?: any) => { + cy.get('.btn.btn-sm.btn-outline.filterSide.dropdown-toggle') + .click() + .then(() => { + cy.get('clr-dropdown-menu button').then((buttons) => { + for (let button of buttons) { + if (button.innerText.toLowerCase().includes('download')) { + button.click() + + if (callback) callback() + } + } + }) + }) +} + +const openTableFromTree = (libNameIncludes: string, tablename: string) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + console.log('viyaLib', viyaLib) + + cy.get(viyaLib).within(() => { + cy.get( + '.clr-tree-node-content-container .clr-treenode-content p' + ).click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + break + } + } + }) + }) + }) + }) +} diff --git a/client/cypress/integration/editor.tests.ts b/client/cypress/integration/editor.tests.ts new file mode 100644 index 0000000..9284987 --- /dev/null +++ b/client/cypress/integration/editor.tests.ts @@ -0,0 +1,257 @@ +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels_general/' + +context('editor tests: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + }) + + it('1 | Submits duplicate primary keys', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary') + + attachExcelFile('MPE_DATADICTIONARY_duplicate_keys.xlsx', () => { + clickOnUploadPreview(() => { + confirmEditPreviewFile(() => { + submitTable(() => { + cy.get('.modal-body').then((modalBody: any) => { + if (modalBody[0].innerText.includes(`Duplicates found:`)) { + done() + } + }) + }) + }) + }) + }) + }) + + it('2 | Submits null cells which must not be null', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + clickOnEdit(() => { + cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', { + timeout: longerCommandTimeout + }).then(() => { + cy.get('.ht_master tbody tr').then((rows: any) => { + cy.get(rows[1].childNodes[2]) + .dblclick({ force: true }) + .then(() => { + cy.focused() + .clear() + .type('{enter}') + .then(() => { + submitTable(() => { + cy.get('.modal-body').then((modalBody: any) => { + if ( + modalBody[0].innerHTML + .toLowerCase() + .includes(`invalid values are present`) + ) { + done() + } + }) + }) + }) + }) + }) + }) + }) + }) + + it('3 | Gets basic dynamic cell validation', () => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + clickOnEdit(() => { + cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', { + timeout: longerCommandTimeout + }).then(() => { + cy.get('.ht_master tbody tr').then((rows: any) => { + cy.get(rows[1].childNodes[5]) + .click({ force: true }) + .then(($td) => { + cy.get('.htAutocompleteArrow', { withinSubject: $td }).should( + 'exist' + ) + }) + }) + }) + }) + }) + + it('4 | Gets advanced dynamic cell validation', () => { + openTableFromTree(libraryToOpenIncludes, 'mpe_tables') + + clickOnEdit(() => { + cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', { + timeout: longerCommandTimeout + }).then(() => { + cy.get('.ht_master tbody tr').then((rows: any) => { + cy.get(rows[1].childNodes[3]) + .click({ force: true }) + .then(($td) => { + cy.get('.htAutocompleteArrow', { withinSubject: $td }).should( + 'exist' + ) + cy.get('.htAutocompleteArrow', { + withinSubject: rows[1].childNodes[7] + }).should('exist') + cy.get('.htAutocompleteArrow', { + withinSubject: rows[1].childNodes[8] + }).should('exist') + }) + }) + }) + }) + }) + + this.afterEach(() => { + // cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const clickOnEdit = (callback?: any) => { + cy.get('.btnCtrl button.btn-primary', { timeout: longerCommandTimeout }) + .click() + .then(() => { + if (callback) callback() + }) +} + +const openTableFromTree = (libNameIncludes: string, tablename: string) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container > button').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + break + } + } + }) + }) + }) + }) +} + +const attachExcelFile = (excelFilename: string, callback?: any) => { + cy.get('.buttonBar button:last-child') + .click() + .then(() => { + cy.get('input[type="file"]#file-upload') + .attachFile(`/${fixturePath}/${excelFilename}`) + .then(() => { + cy.get('.modal-footer .btn.btn-primary').then((modalBtn) => { + modalBtn.click() + if (callback) callback() + }) + }) + }) +} + +const clickOnUploadPreview = (callback?: any) => { + cy.get('.buttonBar button.btn-primary.btn-upload-preview') + .click() + .then(() => { + if (callback) callback() + }) +} + +const confirmEditPreviewFile = (callback?: any) => { + cy.get('.modal-footer button.btn-success-outline') + .click() + .then(() => { + if (callback) callback() + }) +} + +const submitTable = (callback?: any) => { + cy.get('.btnCtrl button.btn-primary') + .click() + .then(() => { + if (callback) callback() + }) +} + +const submitTableMessage = (callback?: any) => { + cy.get('.modal-footer .btn.btn-sm.btn-success-outline') + .click() + .then(() => { + if (callback) callback() + }) +} + +const submitExcel = (callback?: any) => { + cy.get('.buttonBar button.preview-submit') + .click() + .then(() => { + if (callback) callback() + }) +} + +const rejectExcel = (callback?: any) => { + cy.get('button', { timeout: longerCommandTimeout }) + .should('contain', 'Go to approvals screen') + .then((allButtons: any) => { + for (let approvalButton of allButtons) { + if ( + approvalButton.innerText + .toLowerCase() + .includes('go to approvals screen') + ) { + approvalButton.click() + break + } + } + + cy.get('button.btn-danger') + .should('exist') + .should('not.be.disabled') + .click() + .then(() => { + cy.get('.modal-footer button.btn-success-outline') + .click() + .then(() => { + cy.get('app-history') + .should('exist') + .then(() => { + if (callback) callback() + }) + }) + }) + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} diff --git a/client/cypress/integration/excel.tests.ts b/client/cypress/integration/excel.tests.ts new file mode 100644 index 0000000..1353263 --- /dev/null +++ b/client/cypress/integration/excel.tests.ts @@ -0,0 +1,539 @@ +import { Callbacks } from 'cypress/types/jquery/index' + +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels/' + +// TODO: 4 and 9 failing + +context('excel tests: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + + colorLog( + `TEST START ---> ${ + Cypress.mocha.getRunner().suite.ctx.currentTest.title + }`, + '#3498DB' + ) + }) + + it('1 | Uploads regular Excel file', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('regular_excel.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('2 | Uploads Excel with data on the 7th tab', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('7th_tab_excel.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('3 | Uploads Excel with missing columns (should fail)', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('missing_columns_excel.xlsx', () => { + cy.get('.abortMsg', { timeout: longerCommandTimeout }) + .should('exist') + .then((elements: any) => { + if (elements[0]) { + if (elements[0].innerText.toLowerCase().includes('missing')) done() + } + }) + }) + }) + + it('4 | Uploads Excel with formulas', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary') + + attachExcelFile('formulas_excel.xlsx', () => { + checkResultOfFormulaUpload(done) + }) + }) + + it('5 | Uploads Excel with no data rows', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('nodata_rows_excel.xlsx', () => { + cy.get('.abortMsg', { timeout: longerCommandTimeout }) + .should('exist') + .then((elements: any) => { + if (elements[0]) { + if ( + elements[0].innerText + .toLowerCase() + .includes('no relevant data found') + ) + done() + } + }) + }) + }) + + it('6 | Uploads Excel with a table that is surrounded by other data', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('surrounded_data_excel.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('7 | Uploads Excel with a extra columns in the middle', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('extra_column_excel.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('8 | Uploads Excel with a duplicate column', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('duplicate_column_excel.xlsx', () => { + cy.get('.abortMsg', { timeout: longerCommandTimeout }) + .should('exist') + .then((elements: any) => { + if (elements[0]) { + if (elements[0].innerText.toLowerCase().includes('missing')) done() + } + }) + }) + }) + + // it('9 | Uploads Excel with a duplicate row', (done) => { + // openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + // attachExcelFile('duplicate_row_excel.xlsx', () => { + // submitExcel(() => { + // cy.get('.abortMsg', { timeout: longerCommandTimeout }) + // .should('exist') + // .then((elements: any) => { + // if (elements[0]) { + // if (elements[0].innerText.toLowerCase().includes('duplicates')) + // done() + // } + // }) + // }) + // }) + // }) + + it('10 | Uploads Excel with a mixed content', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('mixed_content_excel.xlsx', () => { + submitExcel(() => { + cy.get('.modal-body').then((modalBody: any) => { + if ( + modalBody[0].innerHTML + .toLowerCase() + .includes(`invalid values are present`) + ) { + done() + } + }) + }) + }) + }) + + it('11 | Uploads Excel with a blank columns', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('blank_columns_excel.xlsx', () => { + cy.get('.abortMsg', { timeout: longerCommandTimeout }) + .should('exist') + .then((elements: any) => { + if (elements[0]) { + if (elements[0].innerText.toLowerCase().includes('missing')) done() + } + }) + }) + }) + + it('12 | Uploads Excel xls extension', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('regular_excel_xls.xls', () => { + submitExcel() + rejectExcel(done) + }) + }) + + // For some strange reason this file breaks cypress. When uploaded manually in DC it is working. + // it('13 | Uploads Excel xlsm extension', (done) => { + // openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + // attachExcelFile('regular_excel_macro.xlsm', () => { + // submitExcel() + // rejectExcel(done) + // }) + // }) + + it('14 | Uploads Excel with composite primary key', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary') + + attachExcelFile('MPE_DATADICTIONARY_composite_keys.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('15 | Uploads Excel with missing row (empty table)', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary') + + attachExcelFile('MPE_DATADICTIONARY_missing_row.xlsx', () => { + cy.get('.abortMsg', { timeout: longerCommandTimeout }) + .should('exist') + .then((elements: any) => { + if (elements[0]) { + if ( + elements[0].innerText + .toLowerCase() + .includes('no relevant data found') + ) + done() + } + }) + }) + }) + + it('16 | Uploads Excel with merged cells', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary') + + attachExcelFile('MPE_DATADICTIONARY_merged_cells.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + + it('17 | Check uploaded values from excel with xls extension', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('regular_excel_xls.xls', () => { + checkResultOfXLSUpload(done) + }) + }) + + it('18 | Uploads Excel with missing row (empty table)', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('blank_column_with_header.xlsx', () => { + cy.get('.btn-upload-preview', { timeout: 60000 }) + .should('be.visible') + .then(() => { + cy.get('#hotInstance', { timeout: 30000 }) + .find('div.ht_master.handsontable') + .find('div.wtHolder') + .find('div.wtHider') + .find('div.wtSpreader') + .find('table.htCore') + .find('tbody') + .should((data) => { + let allEmpty = true + + for (let col = 0; col < data[0].children.length; col++) { + const cell: any = data[0].children[col].children[5] + + if (cell.innerText !== '') { + allEmpty = false + + break + } + } + + if (allEmpty) done() + }) + }) + }) + }) + + it('19 | Uploads Excel with data on random sheet surrounded with all empty cells', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('surrounded_data_all_cells_empty_excel.xlsx', () => { + checkResultOfXLSUpload(done) + }) + }) + + it('20 | Uploads Excel with data surrounded with empty cells ', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('surrounded_data_empty_cells_excel.xlsx', () => { + checkResultOfXLSUpload(done) + }) + }) + + it('21 | Uploads regular Excel file with first row marked for Delete (yes)', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + attachExcelFile('regular_excel_with_delete.xlsx', () => { + cy.get('.btn-upload-preview', { timeout: 60000 }) + .should('be.visible') + .then(() => { + cy.get('#hotInstance', { timeout: 30000 }) + .find('div.ht_master.handsontable') + .find('div.wtHolder') + .find('div.wtHider') + .find('div.wtSpreader') + .find('table.htCore') + .find('tbody') + .should((data: JQuery) => { + const firstRowFirstCol: Partial = + data[0].children[0].children[1] + + if ( + firstRowFirstCol.innerText && + !firstRowFirstCol.innerText.toLowerCase().includes('yes') + ) { + done('Delete? column from file not applied') + } + }) + .then(() => { + submitExcel() + rejectExcel(done) + }) + }) + }) + }) + + // Large files break Cypress + + // it ('? | Uploads Excel with size of 5MB', (done) => { + // attachExcelFile('5mb_excel.xlsx', () => { + // submitExcel(); + // rejectExcel(done); + // }); + // }) + + // it ('? | Uploads Excel with size of 15MB', (done) => { + // attachExcelFile('15mb_excel.xlsx', () => { + // submitExcel(); + // rejectExcel(done); + // }); + // }) + + //Large files tests end + + this.afterEach(() => { + colorLog(`TEST END -------------`, '#3498DB') + // cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const openTableFromTree = (libNameIncludes: string, tablename: string) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container > button').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + break + } + } + }) + }) + }) + }) +} + +const attachExcelFile = (excelFilename: string, callback?: any) => { + cy.get('.buttonBar button:last-child') + .should('exist') + .click() + .then(() => { + cy.get('input[type="file"]#file-upload') + .attachFile(`/${fixturePath}/${excelFilename}`) + .then(() => { + cy.get('.clr-abort-modal .modal-title').then((modalTitle) => { + if (!modalTitle[0].innerHTML.includes('Abort Message')) { + cy.get('.modal-footer .btn.btn-primary').then((modalBtn) => { + modalBtn.click() + if (callback) callback() + }) + } else { + if (callback) callback() + } + }) + }) + }) +} + +const submitExcel = (callback?: any) => { + cy.get('.buttonBar button.preview-submit', { timeout: longerCommandTimeout }) + .click() + .then(() => { + if (callback) callback() + }) +} + +const rejectExcel = (callback?: any) => { + cy.get('button', { timeout: longerCommandTimeout }) + .should('contain', 'Go to approvals screen') + .then((allButtons: any) => { + for (let approvalButton of allButtons) { + if ( + approvalButton.innerText + .toLowerCase() + .includes('go to approvals screen') + ) { + approvalButton.click() + break + } + } + + cy.get('button.btn-danger') + .should('exist') + .should('not.be.disabled') + .click() + .then(() => { + cy.get('.modal-footer button.btn-success-outline') + .click() + .then(() => { + cy.get('app-history') + .should('exist') + .then(() => { + if (callback) callback() + }) + }) + }) + }) +} + +const acceptExcel = (callback?: any) => { + cy.get('button', { timeout: longerCommandTimeout }) + .should('contain', 'Go to approvals screen') + .then((allButtons: any) => { + for (let approvalButton of allButtons) { + if ( + approvalButton.innerText + .toLowerCase() + .includes('go to approvals screen') + ) { + approvalButton.click() + break + } + } + + cy.get('#acceptBtn') + .should('exist') + .should('not.be.disabled') + .click() + .then(() => { + if (callback) { + callback() + } + }) + }) +} + +const checkResultOfFormulaUpload = (callback?: any) => { + cy.get('#hotInstance', { timeout: longerCommandTimeout }) + .find('div.ht_master.handsontable') + .find('div.wtHolder') + .find('div.wtHider') + .find('div.wtSpreader') + .find('table.htCore') + .find('tbody') + .should((data) => { + const cell: any = data[0].children[0].children[5] + expect(cell.innerText).to.equal('=1+1') + if (callback) callback() + }) +} + +const checkResultOfXLSUpload = (callback?: any) => { + cy.viewport(1280, 720) + cy.get('#hotInstance', { timeout: 30000 }) + .find('div.ht_master.handsontable') + .find('div.wtHolder') + .find('div.wtHider') + .find('div.wtSpreader') + .find('table.htCore') + .find('tbody') + .should((data) => { + let cell: any = data[0].children[0].children[2] + + expect(cell.innerText).to.equal('0') + cell = data[0].children[0].children[3] + expect(cell.innerText).to.equal('this is dummy data changed in excel') + cell = data[0].children[0].children[4] + expect(cell.innerText).to.equal('▼\nOption 1') + cell = data[0].children[0].children[5] + expect(cell.innerText).to.equal('42') + cell = data[0].children[0].children[6] + expect(cell.innerText).to.equal('▼\n1960-02-12') + cell = data[0].children[0].children[7] + expect(cell.innerText).to.equal('▼\n1960-01-01 00:00:42') + cell = data[0].children[0].children[8] + expect(cell.innerText).to.equal('00:00:42') + cell = data[0].children[0].children[9] + expect(cell.innerText).to.equal('3') + + if (callback) callback() + }) + + cy.get('#hotInstance', { timeout: 30000 }) + .find('div.ht_master.handsontable') + .find('div.wtHolder') + .scrollTo('right') + .find('div.wtHider') + .find('div.wtSpreader') + .find('table.htCore') + .find('tbody') + .should((data) => { + let cell: any = data[0].children[0].children[1] + + cell = data[0].children[0].children[9] + + expect(cell.innerText).to.equal('44') + + if (callback) callback() + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} + +const colorLog = (msg: string, color: string) => { + console.log('%c' + msg, 'color:' + color + ';font-weight:bold;') +} diff --git a/client/cypress/integration/filtering.tests.ts b/client/cypress/integration/filtering.tests.ts new file mode 100644 index 0000000..19e368d --- /dev/null +++ b/client/cypress/integration/filtering.tests.ts @@ -0,0 +1,383 @@ +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels_general/' + +context('filtering tests: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`, { timeout: longerCommandTimeout }) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout }) + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + }) + + it('1 | filter char field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_CHAR', 'this is dummy data', 'value', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_CHAR,=,"'this is dummy data'"`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }) + }) + + it('2 | filter number field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_NUM', '42', 'value', () => { + checkInfoBarIncludes(`AND,AND,0,SOME_NUM,=,42`, (includes: boolean) => { + if (includes) done() + }) + }) + }) + }) + + it.only('3 | filter time field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_TIME', '00:00:42', 'time', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_TIME,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }) + }) + + it('3.1 | Non picker - filter time field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_TIME', '42', 'value', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_TIME,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }, false) + }) + + it('4 | filter date field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_DATE', '12/02/1960', 'date', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_DATE,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }) + }) + + it('4.1 | Non picker - filter date field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_DATE', '42', 'value', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_DATE,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }, false) + }) + + it('5 | filter datetime field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue( + 'SOME_DATETIME', + '01/01/1960 00:00:42', + 'datetime', + () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_DATETIME,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + } + ) + }) + }) + + it('5.1 | Non picker - filter datetime field', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_DATETIME', '42', 'value', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_DATETIME,=,42`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }, false) + }) + + it('6 | filter date field IN', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_DATE', '', 'in', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_DATE,IN,(0)`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }) + }) + + it('7 | filter bestnum field BETWEEN', (done) => { + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + openFilterPopup(() => { + setFilterWithValue('SOME_BESTNUM', '0-10', 'between', () => { + checkInfoBarIncludes( + `AND,AND,0,SOME_BESTNUM,BETWEEN,0 AND 10`, + (includes: boolean) => { + if (includes) done() + } + ) + }) + }) + }) + + this.afterEach(() => { + // cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const checkInfoBarIncludes = (text: string, callback: any) => { + cy.get('.infoBar b', { timeout: longerCommandTimeout }).then((el: any) => { + const includes = el[0].innerText.toLowerCase().includes(text.toLowerCase()) + + if (callback) callback(includes) + }) +} + +const openFilterPopup = ( + callback?: any, + usePickers: boolean = true, + isViewerFiltering: boolean = false +) => { + const filterButton = isViewerFiltering + ? '.btn-outline.filterSide' + : '.btnCtrl .btnView' + + cy.get(filterButton, { timeout: longerCommandTimeout }).then( + (optionsButton: any) => { + optionsButton.click() + + if (isViewerFiltering) { + cy.wait(300) + + cy.get('.dropdown-menu button').then(async (dropdownButtons: any) => { + let filterButton = null + + for (let btn of dropdownButtons) { + if (btn.innerText.toLowerCase().includes('filter')) { + filterButton = btn + + break + } + } + + if (filterButton) { + filterButton.click() + + if (usePickers) turnOnPickers() + + if (callback) callback() + + return + } + }) + } + + if (usePickers) turnOnPickers() + if (callback) callback() + } + ) +} + +const turnOnPickers = () => { + cy.get('#usePickers') + .should('exist') + .then((picker: any) => { + picker[0].click() + }) +} + +const setFilterWithValue = ( + variableValue: string, + valueString: string, + valueField: 'value' | 'time' | 'date' | 'datetime' | 'in' | 'between', + callback?: any +) => { + cy.wait(600) + + cy.focused().type(variableValue) + cy.wait(100) + // cy.focused().trigger('input') + cy.get('.variable-col .autocomplete-wrapper', { withinSubject: null }) + .first() + .trigger('keydown', { key: 'ArrowDown' }) + cy.get('.variable-col .autocomplete-wrapper', { + withinSubject: null + }).trigger('keydown', { key: 'Enter' }) + cy.focused().tab() + cy.wait(100) + + if (valueField === 'in') { + cy.focused().select(valueField.toUpperCase()).trigger('change') + } else if (valueField === 'between') { + cy.focused().select(valueField.toUpperCase()).trigger('change') + } else { + cy.focused().tab() + cy.wait(100) + } + + switch (valueField) { + case 'value': { + cy.focused().type(valueString) + + break + } + case 'time': { + cy.focused().type(valueString) + + break + } + case 'date': { + cy.focused().type(valueString) + cy.focused().tab() + + break + } + case 'datetime': { + const date = valueString.split(' ')[0] + const time = valueString.split(' ')[1] + + cy.focused().type(date) + cy.focused().tab() + cy.focused().tab() + cy.focused().type(time) + + break + } + case 'in': { + cy.get('.checkbox-vals').then(() => { + cy.focused().tab() + cy.focused().click() + cy.get('.no-values') + .should('not.exist') + .then(() => { + cy.get('clr-checkbox-wrapper input').then((inputs: any) => { + inputs[0].click() + cy.get('.in-values-modal .modal-footer button').click() + + cy.get('.modal-footer .btn-success-outline').click() + + if (callback) callback() + }) + }) + }) + + break + } + case 'between': { + cy.focused().tab() + + const start = valueString.split('-')[0] + const end = valueString.split('-')[1] + + cy.focused().type(start) + cy.focused().tab() + cy.focused().type(end) + } + default: { + break + } + } + + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().click() + + if (callback) callback() +} + +const openTableFromTree = (libNameIncludes: string, tablename: string) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (new RegExp(libNameIncludes).test(node.innerText.toLowerCase())) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container p').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + break + } + } + }) + }) + }) + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} diff --git a/client/cypress/integration/licensing.tests.ts b/client/cypress/integration/licensing.tests.ts new file mode 100644 index 0000000..f72ed4e --- /dev/null +++ b/client/cypress/integration/licensing.tests.ts @@ -0,0 +1,731 @@ +import { arrayBufferToBase64 } from './../util/helper-functions' +import * as moment from 'moment' + +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const fixturePath = 'excels_general/' +const serverType = Cypress.env('serverType') +const site_id = Cypress.env(`site_id_${serverType}`) +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const testLicenceUserLimits = Cypress.env('testLicenceUserLimits') + +/** IMPORTANT NOTICE + * Before running tests, make sure that table `MPE_USERS` is present + */ + +interface EditConfigTableCells { + varName: string + varValue: string +} + +context('licensing tests: ', function () { + this.beforeAll(() => { + // cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + }) + + it('1 | key valid, not expired', (done) => { + let keyData = { + valid_until: moment().add(1, 'year').format('YYYY-MM-DD'), + users_allowed: 4, + hot_license_key: '', + demo: false, + site_id: site_id + } + + let keys: { licenseKey: any; activationKey: any } + generateKeys(keyData, (keysGen: any) => { + keys = keysGen + + cy.wait(2000) + + isLicensingPage((result: boolean) => { + if (result) { + inputLicenseKeyPage(keys.licenseKey, keys.activationKey) + + cy.wait(2000) + } + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(10000) + } + + visitPage('home') + + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + done() + }) + }) + }) + }) + }) + + it('2 | Key will expire in less then 14 days, not free tier', (done) => { + // make 2 separate for this one + let keyData = { + valid_until: moment().add(10, 'day').format('YYYY-MM-DD'), + users_allowed: 4, + hot_license_key: '', + demo: false, + site_id: site_id + } + + let keys: { licenseKey: any; activationKey: any } + generateKeys(keyData, (keysGen: any) => { + keys = keysGen + console.log('keys', keys) + + cy.wait(2000) + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + verifyLicensingWarning('This license key will expire in ', () => { + done() + }) + }) + }) + }) + }) + }) + + it('3 | key expired, free tier works', (done) => { + let keyData = { + valid_until: moment().subtract(1, 'day').format('YYYY-MM-DD'), + users_allowed: 4, + hot_license_key: '', + demo: false, + site_id: site_id + } + + let keys: { licenseKey: any; activationKey: any } + generateKeys(keyData, (keysGen: any) => { + keys = keysGen + + cy.wait(2000) + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + cy.wait(2000) + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + verifyLicensingPage( + 'Licence key is expired - please contact', + (success: boolean) => { + if (success) { + verifyLicensingWarning( + '(FREE Tier) - Problem with licence', + () => { + done() + } + ) + } + } + ) + }) + }) + }) + }) + }) + + it('4 | key invalid, free tier works', (done) => { + let keyData = { + valid_until: moment().subtract(1, 'day').format('YYYY-MM-DD'), + users_allowed: 4, + hot_license_key: '', + demo: false, + site_id: site_id + } + + let keys: { licenseKey: any; activationKey: any } + generateKeys(keyData, (keysGen: any) => { + keys = keysGen + keys.activationKey = 'invalid' + keys.activationKey + + cy.wait(2000) + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + cy.wait(2000) + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + verifyLicensingPage( + 'Licence key is invalid - please contact', + (success: boolean) => { + if (success) { + verifyLicensingWarning( + '(FREE Tier) - Problem with licence', + () => { + done() + } + ) + } + } + ) + }) + }) + }) + }) + }) + + it('5 | key for wrong organisation, free tier works', (done) => { + let keyData = { + valid_until: moment().add(1, 'year').format('YYYY-MM-DD'), + users_allowed: 4, + hot_license_key: '', + demo: false, + site_id: 100 + } + + let keys: { licenseKey: any; activationKey: any } + generateKeys(keyData, (keysGen: any) => { + keys = keysGen + keys.activationKey = keys.activationKey + + cy.wait(2000) + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + cy.wait(2000) + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + verifyLicensingPage( + 'SYSSITE (below) is not found', + (success: boolean) => { + if (success) { + verifyLicensingWarning( + '(FREE Tier) - Problem with licence', + () => { + done() + } + ) + } + } + ) + }) + }) + }) + }) + }) + + if (testLicenceUserLimits) { + it('4 | User try to register when limit is reached', (done) => { + let keyData = { + valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), + users_allowed: 10, + hot_license_key: '', + demo: false, + site_id: site_id + } + let keyData2 = { + valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), + users_allowed: 1, + hot_license_key: '', + demo: false, + site_id: site_id + } + generateKeys(keyData, (keysGen: any) => { + generateKeys(keyData2, (keysGen2: any) => { + cy.wait(2000) + + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + + updateLicenseKeyQuick(keysGen2, () => { + cy.wait(2000) + + const random = Cypress._.random(0, 1000) + const newUser = { + username: `randomusername${random}notregistered`, + last_seen_at: moment().add(1, 'month').format('YYYY-MM-DD'), + registered_at: moment().add(1, 'month').format('YYYY-MM-DD') + } + updateUsersTable( + { deleteAll: true, newUsers: [newUser] }, + () => { + logout(() => { + cy.visit(hostUrl + appLocation) + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + + cy.wait(2000) + + verifyLicensingPage( + 'The registered number of users reached the limit specified for your licence.', + (success: boolean) => { + if (success) done() + } + ) + }) + } + ) + }) + }) + }) + }) + }) + }) + }) + + it('5 | Show warning banner when limit is exceeded', (done) => { + let keyData = { + valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), + users_allowed: 10, + hot_license_key: '', + demo: false, + site_id: site_id + } + let keyData2 = { + valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), + users_allowed: 1, + hot_license_key: '', + demo: false, + site_id: site_id + } + + generateKeys(keyData, (keysGen: any) => { + generateKeys(keyData2, (keysGen2: any) => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + updateLicenseKeyQuick(keysGen, () => { + cy.wait(2000) + acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + const random = Cypress._.random(0, 1000) + const newUser = { + username: `randomusername${random}`, + last_seen_at: moment().add(1, 'month').format('YYYY-MM-DD'), + registered_at: moment().add(1, 'month').format('YYYY-MM-DD') + } + updateUsersTable( + { deleteAll: true, keep: username, newUsers: [newUser] }, + () => { + updateLicenseKeyQuick(keysGen2, () => { + cy.wait(2000) + verifyLicensingWarning( + 'The registered number of users exceeds the limit specified for your license.', + () => { + done() + } + ) + }) + } + ) + }) + }) + }) + }) + }) + }) + } + + this.afterEach(() => { + // cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const logout = (callback?: any) => { + cy.get('.header-actions .dropdown-toggle') + .click() + .then(() => { + cy.get('.header-actions .dropdown-menu > .separator') + .next() + .click() + .then(() => { + if (callback) callback() + }) + }) +} + +const acceptTermsIfPresented = (callback?: any) => { + cy.url().then((url: string) => { + if (url.includes('licensing/register')) { + cy.get('.card-block') + .scrollTo('bottom') + .then(() => { + cy.get('#checkbox1') + .click() + .then(() => { + if (callback) callback(true) + }) + }) + } else { + if (callback) callback(false) + } + }) +} + +const isLicensingPage = (callback: any) => { + return cy.url().then((url: string) => { + callback( + url.includes('#/licensing/') && !url.includes('licensing/register') + ) + }) +} + +const verifyLicensingPage = (text: string, callback: any) => { + // visitPage('home') + + cy.wait(1000) + isLicensingPage((result: boolean) => { + if (result) { + cy.get('p.key-error') + .should('contain', text) + .then((treeNodes: any) => { + callback(true) + }) + } + }) +} + +const verifyLicensingWarning = (text: string, callback: any) => { + visitPage('home') + + cy.wait(1000) + cy.get("div[role='alert'] .alert-text") + .invoke('text') + .should('contain', text) + .then(() => { + callback() + }) +} + +const inputLicenseKeyPage = (licenseKey: string, activationKey: string) => { + cy.get('button').contains('Paste licence').click() + + cy.get('.license-key-form textarea', { timeout: longerCommandTimeout }) + .invoke('val', licenseKey) + .trigger('input') + .should('not.be.undefined') + cy.get('.activation-key-form textarea', { timeout: longerCommandTimeout }) + .invoke('val', activationKey) + .trigger('input') + .should('not.be.undefined') + cy.get('button.apply-keys').click() +} + +const updateUsersTable = (options: any, callback?: any) => { + visitPage('home') + openTableFromTree(libraryToOpenIncludes, 'mpe_users') + + clickOnEdit(() => { + cy.get('.ht_master tbody tr').then((rows: any) => { + if (options.deleteAll) { + for (let row of rows) { + const user_id = row.childNodes[2] + if (!options.keep || user_id.innerText !== options.keep) { + cy.get(row.childNodes[1]) + .dblclick() + .then(() => { + cy.focused().type('{selectall}').type('Yes').type('{enter}') + }) + } + } + } + if (options.newUsers && options.newUsers.length) { + for (let newUser of options.newUsers) { + clickOnAddRow(() => { + cy.get('#hotInstance tbody tr:last-child').then((rows: any) => { + cy.get(rows[0].childNodes[2]) + .dblclick() + .then(() => { + cy.focused() + .type('{selectall}') + .type(newUser.username) + .type('{enter}') + }) + // cy.get(rows[0].childNodes[3]) + // .dblclick() + // .then(() => { + // cy.focused() + // .type('{selectall}') + // .type(newUser.last_seen_at) + // .type('{enter}') + // }) + // cy.get(rows[0].childNodes[4]) + // .dblclick() + // .then(() => { + // cy.focused() + // .type('{selectall}') + // .type(newUser.registered_at) + // .type('{enter}') + // }) + submitTable(() => { + cy.wait(2000) + approveTable(callback) + }) + }) + }) + } + } + }) + }) +} + +const changeLicenseKeyTable = (keys: any, callback?: any) => { + visitPage('home') + openTableFromTree(libraryToOpenIncludes, 'mpe_config') + + clickOnEdit(() => { + editTableField( + [ + { varName: 'DC_ACTIVATION_KEY', varValue: keys.activationKey }, + { varName: 'DC_LICENCE_KEY', varValue: keys.licenseKey } + ], + () => { + submitTable(() => { + cy.wait(2000) + approveTable(() => { + cy.reload() + if (callback) callback() + }) + }) + } + ) + }) +} + +const updateLicenseKeyQuick = (keys: any, callback: any) => { + isLicensingPage((result: boolean) => { + if (!result) { + visitPage('licensing/update') + cy.wait(2000) + } + inputLicenseKeyPage(keys.licenseKey, keys.activationKey) + + callback() + }) +} + +const generateKeys = async (licenseData: any, resultCallback?: any) => { + let keyPair = await window.crypto.subtle.generateKey( + { + name: 'RSA-OAEP', + modulusLength: 2024, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256' + }, + true, + ['encrypt', 'decrypt'] + ) + + const encoded = new TextEncoder().encode(JSON.stringify(licenseData)) + + const cipher = await window.crypto.subtle + .encrypt( + { + name: 'RSA-OAEP' + }, + keyPair.publicKey, + encoded + ) + .then( + (value) => { + return value + }, + (err) => { + console.log('Encrpyt error', err) + } + ) + + if (!cipher) { + alert('Encryptin keys failed') + throw new Error('Encryptin keys failed') + } + + const privateKeyBytes = await window.crypto.subtle.exportKey( + 'pkcs8', + keyPair.privateKey + ) + + const activationKey = await arrayBufferToBase64(privateKeyBytes) + const licenseKey = await arrayBufferToBase64(cipher) + + if (resultCallback) + resultCallback({ + activationKey, + licenseKey + }) +} + +const editTableField = (edits: EditConfigTableCells[], callback?: any) => { + cy.get('td').then((tdNodes: any) => { + for (let edit of edits) { + let correctRow = false + + for (let node of tdNodes) { + if (correctRow) { + cy.get(node) + .dblclick() + .then(() => { + // textarea update on long keys + cy.focused().invoke('val', edit.varValue).type('{enter}') + }) + + correctRow = false + break + } + + if (node.innerText.includes(edit.varName)) { + correctRow = true + } + } + } + + if (callback) callback() + }) +} + +const openTableFromTree = ( + libNameIncludes: string, + tablename: string, + callback?: any +) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container > button').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + if (callback) callback() + break + } + } + }) + }) + }) + }) +} + +const clickOnAddRow = (callback?: any) => { + cy.get('.btnCtrl button.btn-success') + .click() + .then(() => { + if (callback) callback() + }) +} + +const clickOnEdit = (callback?: any) => { + cy.get('.btnCtrl button.btn-primary', { timeout: longerCommandTimeout }) + .click() + .then(() => { + if (callback) callback() + }) +} + +const submitTable = (callback?: any) => { + cy.get('.btnCtrl button.btn-primary', { timout: longerCommandTimeout }) + .click() + .then(() => { + cy.get(".modal.ng-star-inserted button[type='submit']") + .click() + .then(() => { + if (callback) callback() + }) + }) +} + +const approveTable = (callback?: any) => { + cy.get('button', { timeout: longerCommandTimeout }) + .should('contain', 'Go to approvals screen') + .then((allButtons: any) => { + for (let approvalButton of allButtons) { + if ( + approvalButton.innerText + .toLowerCase() + .includes('go to approvals screen') + ) { + approvalButton.click() + break + } + } + + cy.get('button#acceptBtn', { timeout: longerCommandTimeout }) + .should('exist') + .should('not.be.disabled') + .click() + .then(() => { + cy.get('app-history', { timeout: longerCommandTimeout }) + .should('exist') + .then(() => { + if (callback) callback() + }) + }) + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} diff --git a/client/cypress/integration/liveness.tests.ts b/client/cypress/integration/liveness.tests.ts new file mode 100644 index 0000000..8e350b0 --- /dev/null +++ b/client/cypress/integration/liveness.tests.ts @@ -0,0 +1,157 @@ +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels/' + +context('liveness tests: ', function () { + this.beforeAll(() => { + if (serverType !== 'SASJS') { + cy.visit(`${hostUrl}/SASLogon/logout`) + } + cy.loginAndUpdateValidKey(true) + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + + // cy.get('input.username').type(username) + // cy.get('input.password').type(password) + // cy.get('.login-group button').click() + + visitPage('home') + }) + + it('1 | Login and submit test', (done) => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + libraryExistsInTree('viya', treeNodes) + ? openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + : openTableFromTree('dc', 'mpe_x_test') + + attachExcelFile('regular_excel.xlsx', () => { + submitExcel() + rejectExcel(done) + }) + }) + }) + + /** + * Thist part will be needed if we add more tests in future + */ + // this.afterEach(() => { + // cy.visit('https://sas.4gl.io/SASLogon/logout'); + // }) +}) + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} + +const libraryExistsInTree = (libName: string, nodes: any) => { + for (let node of nodes) { + if (node.innerText.toLowerCase().includes(libName.toLowerCase())) + return true + } + + return false +} + +const openTableFromTree = ( + libNameIncludes: string, + tablename: string, + finish: any +) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + if (!viyaLib && finish) finish(false) + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container > button').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + if (finish) finish(true) + break + } + } + }) + }) + }) + }) +} + +const attachExcelFile = (excelFilename: string, callback?: any) => { + cy.get('.buttonBar button:last-child') + .should('exist') + .click() + .then(() => { + cy.get('input[type="file"]#file-upload').attachFile( + `/${fixturePath}/${excelFilename}` + ) + cy.get('.modal-footer .btn.btn-primary').then((modalBtn) => { + modalBtn.click() + if (callback) callback() + }) + }) +} + +const submitExcel = (callback?: any) => { + cy.get('.buttonBar button.preview-submit', { timeout: longerCommandTimeout }) + .click() + .then(() => { + if (callback) callback() + }) +} + +const rejectExcel = (callback?: any) => { + cy.get('button', { timeout: longerCommandTimeout }) + .should('contain', 'Go to approvals screen') + .then((allButtons: any) => { + for (let approvalButton of allButtons) { + if ( + approvalButton.innerText + .toLowerCase() + .includes('go to approvals screen') + ) { + approvalButton.click() + break + } + } + + cy.get('button.btn-danger') + .should('exist') + .should('not.be.disabled') + .click() + .then(() => { + cy.get('.modal-footer button.btn-success-outline') + .click() + .then(() => { + cy.get('app-history') + .should('exist') + .then(() => { + if (callback) callback() + }) + }) + }) + }) +} diff --git a/client/cypress/integration/metanav.tests.ts b/client/cypress/integration/metanav.tests.ts new file mode 100644 index 0000000..3244d86 --- /dev/null +++ b/client/cypress/integration/metanav.tests.ts @@ -0,0 +1,61 @@ +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels_general/' + +context('metanav tests: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + cy.get('input.username').type(username) + cy.get('input.password').type(password) + cy.get('.login-group button').click() + + visitPage('view/metadata') + }) + + it('1 | Opens metadata object', (done) => { + openFirstMetadataFromTree(() => { + // BLOCKER + // For unkown reasons, .clr-accordion-header-button always null although it is present on the page. + cy.get('.clr-accordion-header-button').then((panelNodes: any) => { + panelNodes[0].querySelector('button').click() + }) + }) + }) + + this.afterEach(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const openFirstMetadataFromTree = (callback?: any) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let firstMetaNode + + firstMetaNode = treeNodes[1] + + cy.get(firstMetaNode).within(() => { + cy.get('.clr-treenode-content').click() + callback() + }) + }) + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} diff --git a/client/cypress/integration/viewbox.tests.ts b/client/cypress/integration/viewbox.tests.ts new file mode 100644 index 0000000..ea139c8 --- /dev/null +++ b/client/cypress/integration/viewbox.tests.ts @@ -0,0 +1,629 @@ +import { cloneDeep } from 'lodash-es' + +const username = Cypress.env('username') +const password = Cypress.env('password') +const hostUrl = Cypress.env('hosturl') +const appLocation = Cypress.env('appLocation') +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const serverType = Cypress.env('serverType') +const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) +const fixturePath = 'excels_general/' + +context('editor tests: ', function () { + this.beforeAll(() => { + cy.visit(`${hostUrl}/SASLogon/logout`) + cy.loginAndUpdateValidKey() + }) + + this.beforeEach(() => { + cy.visit(hostUrl + appLocation) + + cy.wait(2000) + + cy.get('body').then(($body) => { + const usernameInput = $body.find('input.username')[0] + + if (usernameInput && !Cypress.dom.isHidden(usernameInput)) { + cy.get('input.username').type(username) + cy.get('input.password').type(password) + + cy.get('.login-group button').click() + } + }) + + visitPage('home') + }) + + it('1 | Add one viewbox', (done) => { + const viewbox_table = 'mpe_audit' + const columns = ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, [viewbox_table]) + + cy.get('.open-viewbox').then((viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + if (!viewboxNode.innerText.toLowerCase().includes(viewbox_table)) { + return + } + + checkColumns(columns, () => { + done() + }) + } + }) + }) + + it('2 | Add two viewboxes', (done) => { + const viewboxes = [ + { + viewbox_table: 'mpe_audit', + columns: ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'] + }, + { + viewbox_table: 'mpe_alerts', + columns: [ + 'TX_FROM', + 'ALERT_EVENT', + 'ALERT_LIB', + 'ALERT_DS', + 'ALERT_USER' + ] + } + ] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + cy.get('.viewbox-open').click() + openTableFromViewboxTree( + libraryToOpenIncludes, + viewboxes.map((viewbox) => viewbox.viewbox_table) + ) + + cy.get('.open-viewbox').then((viewboxNodes: any) => { + let found = 0 + + for (let viewboxNode of viewboxNodes) { + for (let viewbox of viewboxes) { + if ( + viewboxNode.innerText.toLowerCase().includes(viewbox.viewbox_table) + ) + found++ + } + } + + if (found < viewboxes.length) return + + cy.get('.viewboxes-container .viewbox').then((viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + cy.get(viewboxNode).within(() => { + cy.get('.table-title').then((tableTitle) => { + const title = tableTitle[0].innerText + const viewbox = viewboxes.find((vb) => + title.toLowerCase().includes(vb.viewbox_table) + ) + + if (viewbox) { + cy.get('.ht_master.handsontable .htCore thead tr').then( + (viewboxColNodes: any) => { + let allColsHtml = viewboxColNodes[0].innerHTML + + for (let col of viewbox?.columns) { + if (!allColsHtml.includes(col)) return + } + + done() + } + ) + } + }) + }) + } + }) + }) + }) + + it('3 | Add viewbox, add columns', (done) => { + const viewbox_table = 'mpe_audit' + const columns = ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'] + const additionalColumns = ['IS_PK'] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, [viewbox_table]) + + cy.get('.open-viewbox').then((viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + if (!viewboxNode.innerText.toLowerCase().includes(viewbox_table)) { + return + } + + openViewboxConfig(viewbox_table) + + addColumns(additionalColumns) + + checkColumns([...columns, ...additionalColumns], () => { + done() + }) + } + }) + }) + + it('4 | Add viewbox, add columns and reorder', (done) => { + const viewbox_table = 'mpe_audit' + const columns = ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'] + const additionalColumns = ['IS_PK', 'MOVE_TYPE'] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, [viewbox_table]) + + cy.get('.open-viewbox').then((viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + if (!viewboxNode.innerText.toLowerCase().includes(viewbox_table)) { + return + } + + openViewboxConfig(viewbox_table) + + addColumns(additionalColumns, () => { + cy.wait(1000) + //reorder + cy.get('.col-box.column-MOVE_TYPE') + .realMouseDown({ button: 'left', position: 'center' }) + .realMouseMove(0, 10, { position: 'center' }) + cy.wait(200) // In our case, we wait 200ms cause we have animations which we are sure that take this amount of time + cy.get('.col-box.column-IS_PK') + .realMouseMove(0, 0, { position: 'center' }) + .realMouseUp() + //reorder end + + cy.wait(500) + + checkColumns([...columns, ...additionalColumns.reverse()], () => { + done() + }) + }) + } + }) + }) + + it('5 | Add viewbox, add columns, reorder, remove column, add again', (done) => { + const viewbox_table = 'mpe_audit' + const columns = ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'] + const additionalColumns = ['IS_PK', 'MOVE_TYPE'] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, [viewbox_table]) + + cy.get('.open-viewbox').then((viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + if (!viewboxNode.innerText.toLowerCase().includes(viewbox_table)) { + return + } + + viewboxNode.click() + + addColumns(additionalColumns, () => { + cy.wait(1000) + //reorder + cy.get('.col-box.column-MOVE_TYPE') + .realMouseDown({ button: 'left', position: 'center' }) + .realMouseMove(0, 10, { position: 'center' }) + cy.wait(200) // In our case, we wait 200ms cause we have animations which we are sure that take this amount of time + cy.get('.col-box.column-IS_PK') + .realMouseMove(0, 0, { position: 'center' }) + .realMouseUp() + //reorder end + + cy.wait(500) + + checkColumns([...columns, ...additionalColumns.reverse()], () => { + const colToRemove = 'MOVE_TYPE' + + removeColumn(colToRemove) + checkColumns( + [ + ...columns, + ...additionalColumns.filter((col) => col !== colToRemove) + ], + () => { + addColumns([colToRemove], () => { + checkColumns( + [...columns, ...additionalColumns.reverse()], + () => { + done() + } + ) + }) + } + ) + }) + }) + } + }) + }) + + it('6 | Add viewboxes, reload and check url restored configuration', (done) => { + const viewboxes = [ + { + viewbox_table: 'mpe_audit', + columns: ['LOAD_REF', 'LIBREF', 'DSN', 'KEY_HASH', 'TGTVAR_NM'], + additionalColumns: ['IS_PK', 'MOVE_TYPE'] + }, + { + viewbox_table: 'mpe_alerts', + columns: [ + 'TX_FROM', + 'ALERT_EVENT', + 'ALERT_LIB', + 'ALERT_DS', + 'ALERT_USER' + ], + additionalColumns: ['TX_TO'] + } + ] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, [ + viewboxes[0].viewbox_table, + viewboxes[1].viewbox_table + ]) + + openViewboxConfig(viewboxes[0].viewbox_table) + + cy.wait(500) + + addColumns(viewboxes[0].additionalColumns, () => { + cy.wait(1000) + + if (viewboxes[0].viewbox_table === 'mpe_audit') { + cy.get('.col-box.column-MOVE_TYPE') + .realMouseDown({ button: 'left', position: 'center' }) + .realMouseMove(0, 10, { position: 'center' }) + cy.wait(200) // In our case, we wait 200ms cause we have animations which we are sure that take this amount of time + cy.get('.col-box.column-IS_PK') + .realMouseMove(0, 0, { position: 'center' }) + .realMouseUp() + } + + cy.wait(1000) + + openViewboxConfig(viewboxes[1].viewbox_table) + addColumns(viewboxes[1].additionalColumns, () => { + cy.wait(1000).reload() + + let result = 0 + + checkColumns( + [ + ...viewboxes[0].columns, + ...cloneDeep(viewboxes[0].additionalColumns.reverse()) + ], + () => { + result++ + + if (result === 2) done() + } + ) + checkColumns( + [...viewboxes[1].columns, ...viewboxes[1].additionalColumns], + () => { + result++ + + if (result === 2) done() + } + ) + }) + }) + }) + + it('7 | Add viewboxes and filter', () => { + const viewboxes = ['mpe_x_test', 'mpe_validations'] + + openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') + + cy.get('.viewbox-open').click() + openTableFromViewboxTree(libraryToOpenIncludes, viewboxes) + + cy.wait(1000) + + closeViewboxModal() + + cy.get('.viewboxes-container .viewbox', { withinSubject: null }).then( + (viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + cy.get(viewboxNode).within(() => { + cy.get('.table-title').then((title: any) => { + cy.get('.hot-spinner') + .should('not.exist') + .then(() => { + cy.get('clr-icon[shape="filter"]').then((filterButton) => { + filterButton[0].click() + }) + + if (title[0].innerText.includes('MPE_X_TEST')) { + setFilterWithValue( + 'SOME_CHAR', + 'this is dummy data', + 'value', + () => { + cy.get('app-query', { withinSubject: null }) + .should('not.exist') + .get('.ht_master.handsontable tbody tr') + .then((rowNodes) => { + const tr = rowNodes[0] + + expect(rowNodes).to.have.length(1) + expect(tr.innerText).to.equal('0') + }) + } + ) + } else if (title[0].innerText.includes('MPE_VALIDATIONS')) { + setFilterWithValue('BASE_COL', 'ALERT_LIB', 'value', () => { + cy.get('app-query', { withinSubject: null }) + .should('not.exist') + .get('.ht_master.handsontable tbody tr') + .then((rowNodes) => { + const tr = rowNodes[0] + + expect(rowNodes).to.have.length(1) + expect(tr.innerText).to.contain('ALERT_LIB') + }) + }) + } + }) + }) + }) + } + } + ) + }) + + this.afterEach(() => { + // cy.visit(`${hostUrl}/SASLogon/logout`) + }) +}) + +const checkColumns = (columns: string[], callback: () => void) => { + cy.get('.viewboxes-container .viewbox', { withinSubject: null }).then( + (viewboxNodes: any) => { + for (let viewboxNode of viewboxNodes) { + cy.get(viewboxNode).within(() => { + cy.get('.ht_master.handsontable thead tr th').then( + (viewboxColNodes: any) => { + for (let i = 0; i < viewboxColNodes.length; i++) { + const col = columns[i] + const colNode = viewboxColNodes[i] + + if ( + !colNode.innerHTML.toLowerCase().includes(col.toLowerCase()) + ) + return + } + + callback() + } + ) + }) + } + } + ) +} + +const closeViewboxModal = () => { + cy.get('app-viewboxes .close', { withinSubject: null }).click() +} + +const removeColumn = (column: string) => { + cy.get(`.col-box.column-${column} clr-icon`, { withinSubject: null }).click() +} + +const addColumns = (columns: string[], callback?: () => void) => { + for (let i = 0; i < columns.length; i++) { + const column = columns[i] + + cy.get('.cols-search input', { withinSubject: null }).type(column) + cy.get('.cols-search .autocomplete-wrapper', { withinSubject: null }) + .first() + .trigger('keydown', { key: 'ArrowDown' }) + cy.get('.cols-search .autocomplete-wrapper', { withinSubject: null }) + .first() + .trigger('keydown', { key: 'Enter' }) + .then(() => { + if (i === columns.length - 1 && callback) callback() + }) + } +} + +const openViewboxConfig = (viewbox_tablename: string) => { + cy.get('.open-viewbox').then((viewboxes: any) => { + for (let openViewbox of viewboxes) { + if (openViewbox.innerText.toLowerCase().includes(viewbox_tablename)) + openViewbox.click() + } + }) +} + +const openTableFromTree = (libNameIncludes: string, tablename: string) => { + cy.get('.app-loading', { timeout: longerCommandTimeout }) + .should('not.exist') + .then(() => { + cy.get('.nav-tree clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (new RegExp(libNameIncludes).test(node.innerText.toLowerCase())) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('.clr-tree-node-content-container p').click() + + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + break + } + } + }) + }) + }) + }) +} + +const setFilterWithValue = ( + variableValue: string, + valueString: string, + valueField: 'value' | 'time' | 'date' | 'datetime' | 'in' | 'between', + callback?: any +) => { + cy.wait(600) + + cy.focused().type(variableValue) + cy.wait(100) + // cy.focused().trigger('input') + cy.get('.variable-col .autocomplete-wrapper', { withinSubject: null }) + .first() + .trigger('keydown', { key: 'ArrowDown' }) + cy.get('.variable-col .autocomplete-wrapper', { + withinSubject: null + }).trigger('keydown', { key: 'Enter' }) + cy.focused().tab() + cy.wait(100) + + if (valueField === 'in') { + cy.focused().select(valueField.toUpperCase()).trigger('change') + } else if (valueField === 'between') { + cy.focused().select(valueField.toUpperCase()).trigger('change') + } else { + cy.focused().tab() + cy.wait(100) + } + + switch (valueField) { + case 'value': { + cy.focused().type(valueString) + + break + } + case 'time': { + cy.focused().type(valueString) + + break + } + case 'date': { + cy.focused().type(valueString) + cy.focused().tab() + + break + } + case 'datetime': { + const date = valueString.split(' ')[0] + const time = valueString.split(' ')[1] + + cy.focused().type(date) + cy.focused().tab() + cy.focused().tab() + cy.focused().type(time) + + break + } + case 'in': { + cy.get('.checkbox-vals').then(() => { + cy.focused().tab() + cy.focused().click() + cy.get('.no-values') + .should('not.exist') + .then(() => { + cy.get('clr-checkbox-wrapper input').then((inputs: any) => { + inputs[0].click() + cy.get('.in-values-modal .modal-footer button').click() + + cy.get('.modal-footer .btn-success-outline').click() + + if (callback) callback() + }) + }) + }) + + break + } + case 'between': { + cy.focused().tab() + + const start = valueString.split('-')[0] + const end = valueString.split('-')[1] + + cy.focused().type(start) + cy.focused().tab() + cy.focused().type(end) + } + default: { + break + } + } + + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().tab() + cy.wait(100) + cy.focused().click() + + if (callback) callback() +} + +const openTableFromViewboxTree = ( + libNameIncludes: string, + tablenames: string[] +) => { + cy.get('.add-new clr-tree > clr-tree-node', { + timeout: longerCommandTimeout + }).then((treeNodes: any) => { + let viyaLib + + for (let node of treeNodes) { + if (node.innerText.toLowerCase().includes(libNameIncludes)) { + viyaLib = node + break + } + } + + cy.get(viyaLib).within(() => { + cy.get('p') + .click() + .then(() => { + cy.get('.clr-treenode-link').then((innerNodes: any) => { + for (let innerNode of innerNodes) { + for (let tablename of tablenames) { + if (innerNode.innerText.toLowerCase().includes(tablename)) { + innerNode.click() + } + } + } + }) + }) + }) + }) +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`) +} diff --git a/client/cypress/plugins/cy-ts-preprocessor.js b/client/cypress/plugins/cy-ts-preprocessor.js new file mode 100644 index 0000000..ba6d8ec --- /dev/null +++ b/client/cypress/plugins/cy-ts-preprocessor.js @@ -0,0 +1,31 @@ +const wp = require('@cypress/webpack-preprocessor') + +const webpackOptions = { + resolve: { + extensions: ['.ts', '.js'] + }, + module: { + rules: [ + { + test: /\.ts$/, + loaders: ['ts-loader', 'angular2-template-loader'], + exclude: [/node_modules/], + }, + { + test: /\.(html|css)$/, + loader: 'raw-loader', + exclude: /\.async\.(html|css)$/ + }, + { + test: /\.async\.(html|css)$/, + loaders: ['file?name=[name].[hash].[ext]', 'extract'] + } + ] + } +} + +const options = { + webpackOptions +} + +module.exports = wp(options) \ No newline at end of file diff --git a/client/cypress/plugins/index.js b/client/cypress/plugins/index.js new file mode 100644 index 0000000..d1a332c --- /dev/null +++ b/client/cypress/plugins/index.js @@ -0,0 +1,58 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +const wp = require("@cypress/webpack-preprocessor"); +const { rmdir } = require('fs') + +/** + * @type {Cypress.PluginConfig} + */ +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config + + const options = { + webpackOptions: require("../webpack.config.js") + }; + on("file:preprocessor", wp(options)); + + on("before:browser:launch", (browser = {}, launchOptions) => { + if (browser.name === "chrome") { + launchOptions.args.push("--disable-site-isolation-trials"); + launchOptions.args.push("--auto-open-devtools-for-tabs"); + launchOptions.args.push("--aggressive-cache-discard") + launchOptions.args.push("--disable-cache") + launchOptions.args.push("--disable-application-cache") + launchOptions.args.push("--disable-offline-load-stale-cache") + launchOptions.args.push("--disk-cache-size=0") + launchOptions.args.push("--no-sandbox") + + return launchOptions; + } + }); + + on('task', { + deleteFolder(folderName) { + return new Promise((resolve, reject) => { + rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => { + if (err) { + console.error(err) + return reject(err) + } + resolve(null) + }) + }) + } + }) +} \ No newline at end of file diff --git a/client/cypress/support/commands.ts b/client/cypress/support/commands.ts new file mode 100644 index 0000000..0db3680 --- /dev/null +++ b/client/cypress/support/commands.ts @@ -0,0 +1,213 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add("login", (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) +import 'cypress-file-upload'; + +import { arrayBufferToBase64 } from './../util/helper-functions' +import * as moment from 'moment' + +const username = Cypress.env('username'); +const password = Cypress.env('password'); +const hostUrl = Cypress.env('hosturl'); +const appLocation = Cypress.env('appLocation'); +const longerCommandTimeout = Cypress.env('longerCommandTimeout') +const site_id_SASJS = Cypress.env('site_id_SASJS') + +Cypress.Commands.add('isLoggedIn', (callback: (exist: boolean) => void) => { + cy.get('body').then($body => { + if ($body.find(".nav-tree").length > 0) { + if (callback) callback(true) + } else { + if (callback) callback(false) + } + }) +}) + +Cypress.Commands.add('loginAndUpdateValidKey', (forceLicenceKey: boolean = false) => { + cy.visit(hostUrl + appLocation); + + cy.wait(2000) + + cy.get('body').then($body =>{ + const usernameInput = $body.find("input.username")[0] + + if (usernameInput && !Cypress.dom.isHidden(usernameInput)) { + cy.get('input.username').type(username); + cy.get('input.password').type(password); + + cy.get('.login-group button').click() + } + + cy.get('.app-loading', {timeout: longerCommandTimeout}).should('not.exist').then(() => { + cy.wait(2000) + + if ($body.find(".nav-tree").length > 0) { + /** + * If licence key is already working, then skip rest of the function + */ + return logout(() => { + return + }) + } else{ + const keyData = { + valid_until: moment().add(20, 'day').format('YYYY-MM-DD'), + number_of_users: 10, + hot_license_key: '', + site_id: '', + demo: false + } + + return generateKeys(keyData.valid_until, keyData.number_of_users, keyData.hot_license_key, keyData.demo, (keysGen: any) => { + return acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + + if (!forceLicenceKey) { + return logout(() => { + return + }) + } else { + return updateLicenseKeyQuick(keysGen, () => { + cy.wait(25000) + return acceptTermsIfPresented((result: boolean) => { + if (result) { + cy.wait(20000) + } + return logout(() => { + return + }) + }) + }) + } + }) + }) + } + }) + }); +}); + +const logout = (callback?: any) => { + cy.get('.header-actions .dropdown-toggle').click().then(() => { + cy.get('.header-actions .dropdown-menu > .separator').next().click().then(() => { + if (callback) callback() + }) + }) +} + +const updateLicenseKeyQuick = (keys: any, callback: any) => { + isLicensingPage((result: boolean) => { + if (!result) { + visitPage('licensing/update') + cy.wait(2000) + } + inputLicenseKeyPage(keys.licenseKey, keys.activationKey) + + callback() + }) +} + +const acceptTermsIfPresented = (callback?: any) => { + cy.url().then((url: string) => { + if (url.includes('licensing/register')) { + cy.get('.card-block').scrollTo('bottom').then(() => { + cy.get('#checkbox1').click().then(() => { + if (callback) callback(true) + }) + }) + } else { + if (callback) callback(false) + } + }) +} + +const isLicensingPage = (callback: any) => { + cy.url().then((url: string) => { + callback(url.includes('licensing') && !url.includes('licensing/register')) + }) +} + +const inputLicenseKeyPage = (licenseKey: string, activationKey: string) => { + cy.get('button').contains('Paste licence').click() + cy.get('.license-key-form textarea', {timeout: longerCommandTimeout}).invoke('val', licenseKey).trigger('input').should('not.be.undefined') + cy.get('.activation-key-form textarea', {timeout: longerCommandTimeout}).invoke('val', activationKey).trigger('input').should('not.be.undefined') + cy.get('button.apply-keys').click() +} + +const visitPage = (url: string) => { + cy.visit(`${hostUrl}${appLocation}/#/${url}`); +} +const generateKeys = async (valid_until: string, users_allowed: number, hot_license_key: string, demo: boolean, resultCallback?: any) => { + let keyPair = await window.crypto.subtle.generateKey({ + name: "RSA-OAEP", + modulusLength: 2024, + publicExponent: new Uint8Array([1, 0, 1]), + hash: "SHA-256" + }, + true, + ["encrypt", "decrypt"] + ) + + let licenseData = { + valid_until: valid_until, + users_allowed: users_allowed, + hot_license_key: hot_license_key, + site_id: site_id_SASJS, + demo: demo + } + + console.log('License data', licenseData) + + let encoded = new TextEncoder().encode(JSON.stringify(licenseData)) + + console.log(encoded) + + let cipher = await window.crypto.subtle.encrypt( + { + name: "RSA-OAEP" + }, + keyPair.publicKey, + encoded + ).then((value) => { + return value + }, (err) => { + console.log('Encrpyt error', err) + }) + + if (!cipher) { + alert('Encryptin keys failed') + throw new Error('Encryptin keys failed') + } + + let privateKeyBytes = await window.crypto.subtle.exportKey('pkcs8', keyPair.privateKey) + + let activationKey = await arrayBufferToBase64(privateKeyBytes) + let licenseKey = await arrayBufferToBase64(cipher) + + if (resultCallback) resultCallback({ + activationKey, + licenseKey + }) +} \ No newline at end of file diff --git a/client/cypress/support/index.js b/client/cypress/support/index.js new file mode 100644 index 0000000..a675b55 --- /dev/null +++ b/client/cypress/support/index.js @@ -0,0 +1,23 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands.ts' + +// Alternatively you can use CommonJS syntax: +// require('./commands') + +import 'cypress-plugin-tab' +import "cypress-real-events"; diff --git a/client/cypress/tsconfig.json b/client/cypress/tsconfig.json new file mode 100644 index 0000000..709e378 --- /dev/null +++ b/client/cypress/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "baseUrl": "../node_modules", + "target": "es6", + "lib": ["es2019", "dom"], + "types": ["cypress", "cypress-real-events"] + }, + "include": ["**/*.ts"] + } \ No newline at end of file diff --git a/client/cypress/util/deleteDownloadFolder.ts b/client/cypress/util/deleteDownloadFolder.ts new file mode 100644 index 0000000..b4a3be2 --- /dev/null +++ b/client/cypress/util/deleteDownloadFolder.ts @@ -0,0 +1,4 @@ +export const deleteDownloadsFolder = () => { + const downloadsFolder = Cypress.config('downloadsFolder') + cy.task('deleteFolder', downloadsFolder) +} \ No newline at end of file diff --git a/client/cypress/util/helper-functions.ts b/client/cypress/util/helper-functions.ts new file mode 100644 index 0000000..b68a9f9 --- /dev/null +++ b/client/cypress/util/helper-functions.ts @@ -0,0 +1,32 @@ +export const base64ToArrayBuffer = (base64: string) => { + return new Promise(async (resolve, reject) => { + const dataUrl = "data:application/octet-binary;base64," + base64; + + fetch(dataUrl) + .then(res => res.arrayBuffer()) + .then(buffer => { + resolve(new Uint8Array(buffer)) + }).catch((err) => { + reject(err) + }) + }) +} + +export const arrayBufferToBase64 = (arrayBuffer: any) => { + return new Promise((resolve, reject) => { + const blob = new Blob([arrayBuffer]) + + const reader = new FileReader(); + + reader.onload = async function(event){ + if (event.target) { + var base64: any = event.target.result + base64 = base64.substring(37, base64.length) + + resolve(base64) + } + }; + + reader.readAsDataURL(blob); + }) +} \ No newline at end of file diff --git a/client/cypress/webpack.config.js b/client/cypress/webpack.config.js new file mode 100644 index 0000000..eeaef94 --- /dev/null +++ b/client/cypress/webpack.config.js @@ -0,0 +1,23 @@ +module.exports = { + mode: "development", + resolve: { + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: [/node_modules/], + use: [ + { + loader: "ts-loader", + options: { + // skip typechecking for speed + transpileOnly: true + } + } + ] + } + ] + } + }; \ No newline at end of file diff --git a/client/karma.conf.js b/client/karma.conf.js new file mode 100644 index 0000000..2cd4b4b --- /dev/null +++ b/client/karma.conf.js @@ -0,0 +1,45 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage/datacontroller'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + browsers: ['Chrome', 'ChromeHeadless', 'ChromeHeadlessCI'], + restartOnFileChange: true, + customLaunchers: { + ChromeHeadlessCI: { + base: 'ChromeHeadless', + flags: ['--no-sandbox'] + } + }, + }); +}; diff --git a/client/libraries/ngx-json-viewer-3.2.1.tgz b/client/libraries/ngx-json-viewer-3.2.1.tgz new file mode 100644 index 0000000..006064d Binary files /dev/null and b/client/libraries/ngx-json-viewer-3.2.1.tgz differ diff --git a/client/licenseChecker.js b/client/licenseChecker.js new file mode 100644 index 0000000..a2c5149 --- /dev/null +++ b/client/licenseChecker.js @@ -0,0 +1,28 @@ +const licenseChecker = require('license-checker') + +const check = (cwd) => { + return new Promise((resolve, reject) => { + licenseChecker.init( + { + production: true, + start: cwd, + excludePrivatePackages: true, + onlyAllow: + 'AFLv2.1;Apache 2.0;Apache-2.0;Apache*;Artistic-2.0;0BSD;BSD*;BSD-2-Clause;BSD-3-Clause;CC0-1.0;CC-BY-3.0;CC-BY-4.0;ISC;MIT;MPL-2.0;ODC-By-1.0;Python-2.0;Unlicense;', + excludePackages: + '@cds/city@1.1.0;@handsontable/angular@13.0.0;handsontable@13.0.0;hyperformula@2.5.0;jackspeak@2.2.0;path-scurry@1.7.0' + }, + (error, json) => { + if (error) { + reject(error) + } else { + resolve(json) + } + } + ) + }) +} + +check(process.cwd(), true) + .then((res) => console.log('All packages are licensed properly')) + .catch((err) => console.log('license checker err', err)) diff --git a/client/nginx/default.conf b/client/nginx/default.conf new file mode 100644 index 0000000..1951abf --- /dev/null +++ b/client/nginx/default.conf @@ -0,0 +1,8 @@ +server { + listen 3000; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } +} \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json new file mode 100644 index 0000000..1b6e005 --- /dev/null +++ b/client/package-lock.json @@ -0,0 +1,31118 @@ +{ + "name": "dc-client", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "dc-client", + "hasInstallScript": true, + "dependencies": { + "@angular/animations": "^16.1.2", + "@angular/cdk": "^15.2.0", + "@angular/common": "^16.1.2", + "@angular/compiler": "^16.1.2", + "@angular/core": "^16.1.2", + "@angular/forms": "^16.1.2", + "@angular/platform-browser": "^16.1.2", + "@angular/platform-browser-dynamic": "^16.1.2", + "@angular/router": "^16.1.2", + "@cds/core": "^6.4.2", + "@clr/angular": "^13.17.0", + "@clr/icons": "^13.0.2", + "@clr/ui": "^13.17.0", + "@handsontable/angular": "^13.0.0", + "@sasjs/adapter": "4.3.6", + "@sasjs/utils": "^3.3.0", + "@sheet/crypto": "1.20211122.1", + "@types/d3-graphviz": "^2.6.7", + "@types/text-encoding": "0.0.35", + "base64-arraybuffer": "^0.2.0", + "buffer": "^5.4.3", + "crypto-browserify": "3.12.0", + "crypto-js": "^3.3.0", + "d3-graphviz": "^5.0.2", + "fs-extra": "^7.0.1", + "handsontable": "^13.0.0", + "https-browserify": "1.0.0", + "hyperformula": "^2.5.0", + "iconv-lite": "^0.5.0", + "jquery-datetimepicker": "^2.5.21", + "jsrsasign": "^10.2.0", + "marked": "^5.0.0", + "moment": "^2.26.0", + "ngx-clipboard": "^16.0.0", + "ngx-json-viewer": "file:libraries/ngx-json-viewer-3.2.1.tgz", + "nodejs": "0.0.0", + "numbro": "^2.1.1", + "os-browserify": "0.3.0", + "rxjs": "^7.8.0", + "save-svg-as-png": "^1.4.17", + "stream-browserify": "3.0.0", + "stream-http": "3.2.0", + "text-encoding": "^0.7.0", + "tslib": "^2.3.0", + "zone.js": "~0.13.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^16.1.0", + "@angular-eslint/builder": "16.0.3", + "@angular-eslint/eslint-plugin": "16.0.3", + "@angular-eslint/eslint-plugin-template": "16.0.3", + "@angular-eslint/schematics": "16.0.3", + "@angular-eslint/template-parser": "16.0.3", + "@angular/cli": "^16.1.0", + "@angular/compiler-cli": "^16.1.2", + "@cypress/webpack-preprocessor": "^5.11.1", + "@types/core-js": "^2.5.5", + "@types/crypto-js": "^4.0.1", + "@types/es6-shim": "^0.31.39", + "@types/jasmine": "~3.6.0", + "@types/lodash-es": "^4.17.3", + "@types/marked": "^4.3.0", + "@types/node": "12.20.50", + "@typescript-eslint/eslint-plugin": "^5.29.0", + "@typescript-eslint/parser": "^5.29.0", + "core-js": "^2.5.4", + "cypress": "^9.5.3", + "cypress-file-upload": "^5.0.8", + "cypress-plugin-tab": "^1.0.5", + "cypress-real-events": "^1.7.6", + "es6-shim": "^0.35.5", + "eslint": "^8.33.0", + "git-describe": "^4.0.4", + "jasmine-core": "~3.6.0", + "karma": "~6.3.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "~1.7.0", + "license-checker": "25.0.1", + "lodash-es": "^4.17.21", + "mochawesome": "^7.1.3", + "mutationobserver-shim": "^0.3.3", + "replace-in-file": "^6.3.5", + "rimraf": "3.0.2", + "ts-loader": "^9.2.8", + "ts-node": "^3.3.0", + "typedoc": "^0.23.24", + "typescript": "~4.9.4", + "wait-on": "^6.0.1", + "watch": "^1.0.2" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1601.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1601.3.tgz", + "integrity": "sha512-HvW51cCEoIYe2mYqcmnm2RZiMMFbFn7iIdsjbCJe7etFhcG+Y3hGDZMh4IFSiQiss+pwPSYOvQY2zwGrndMgLw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.1.3", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.1.3.tgz", + "integrity": "sha512-1scrdUdKRa9TkJ9jev/KRzFttbLUVACQvVRL0G67nUAdtJ/bQX8eui85axpCNPFihK4ReSW3R4lrgcVC2NUSoA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.2.1", + "@angular-devkit/architect": "0.1601.3", + "@angular-devkit/build-webpack": "0.1601.3", + "@angular-devkit/core": "16.1.3", + "@babel/core": "7.22.5", + "@babel/generator": "7.22.5", + "@babel/helper-annotate-as-pure": "7.22.5", + "@babel/helper-split-export-declaration": "7.22.5", + "@babel/plugin-proposal-async-generator-functions": "7.20.7", + "@babel/plugin-transform-async-to-generator": "7.22.5", + "@babel/plugin-transform-runtime": "7.22.5", + "@babel/preset-env": "7.22.5", + "@babel/runtime": "7.22.5", + "@babel/template": "7.22.5", + "@discoveryjs/json-ext": "0.5.7", + "@ngtools/webpack": "16.1.3", + "@vitejs/plugin-basic-ssl": "1.0.1", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.14", + "babel-loader": "9.1.2", + "babel-plugin-istanbul": "6.1.1", + "browserslist": "^4.21.5", + "cacache": "17.1.3", + "chokidar": "3.5.3", + "copy-webpack-plugin": "11.0.0", + "critters": "0.0.19", + "css-loader": "6.8.1", + "esbuild-wasm": "0.17.19", + "fast-glob": "3.2.12", + "https-proxy-agent": "5.0.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "karma-source-map-support": "1.4.0", + "less": "4.1.3", + "less-loader": "11.1.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.2.1", + "magic-string": "0.30.0", + "mini-css-extract-plugin": "2.7.6", + "mrmime": "1.0.1", + "open": "8.4.2", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "2.3.1", + "piscina": "3.2.0", + "postcss": "8.4.24", + "postcss-loader": "7.3.2", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.63.2", + "sass-loader": "13.3.1", + "semver": "7.5.3", + "source-map-loader": "4.0.1", + "source-map-support": "0.5.21", + "terser": "5.17.7", + "text-table": "0.2.0", + "tree-kill": "1.2.2", + "tslib": "2.5.3", + "vite": "4.3.9", + "webpack": "5.86.0", + "webpack-dev-middleware": "6.1.1", + "webpack-dev-server": "4.15.0", + "webpack-merge": "5.9.0", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.17.19" + }, + "peerDependencies": { + "@angular/compiler-cli": "^16.0.0", + "@angular/localize": "^16.0.0", + "@angular/platform-server": "^16.0.0", + "@angular/service-worker": "^16.0.0", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^16.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=4.9.3 <5.2" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1601.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1601.3.tgz", + "integrity": "sha512-744+72vi/Vx010VxizGgilhpnDCOG29qyhMmu7BkUhtpq8E8eQn2HU3nPpxAqrg3bKVAwD7v3F111MVIhub8kA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1601.3", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^4.0.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.3.tgz", + "integrity": "sha512-cFhNdJHumNMZGD3NYxOtNuMGRQXeDnKbwvK+IJmKAttXt8na6EvURR/ZxZOI7rl/YRVX+vcNSdtXz3hE6g+Isw==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.3.tgz", + "integrity": "sha512-hWEuQnfQOgcSs4YX6iF4QR/34ROeSPaMi7lQOYg33hStg+pnk/JDdIU0f2nrIIz3t0jqAj+5VXVLBJvOCd84vg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.1.3", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.0", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-eslint/builder": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.0.3.tgz", + "integrity": "sha512-pv/CrnOHHOnBqhyBmqUPsIHKXOHYMJztxYJ83tjxeXL5Moyu5e6CBMIQ58UtqmgWfEIA3n7owYy9KvHTJcemyQ==", + "dev": true, + "dependencies": { + "@nx/devkit": "16.2.2", + "nx": "16.2.2" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.0.3.tgz", + "integrity": "sha512-8zwY6ustiPXBEF3+jELKVwGk6j2HJn7GHbqAhDFR02YiE27iRMSGTHIAWGs6ZI7F1JgfrIsOHrUgzC1x95K6rg==", + "dev": true + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.0.3.tgz", + "integrity": "sha512-1c+dFytcQDOA2wJ8/rtydMV6UYq1BgVfOcBXOr0WJxC9g8Cad9czcUOkW41WGrTp5kICMliV0ypH5eEaCM2WDQ==", + "dev": true, + "dependencies": { + "@angular-eslint/utils": "16.0.3", + "@typescript-eslint/utils": "5.59.7" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.0.3.tgz", + "integrity": "sha512-OKTMWOjC7F5tdv7gm2tlmgyr/uVyS1RWJZn4X/6D6p0kOpiDXmajtbYHD5tzbshX2Ep62Nt+rg8+1XGHrU0ScA==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "@angular-eslint/utils": "16.0.3", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "aria-query": "5.1.3", + "axobject-query": "3.1.1" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/schematics": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.0.3.tgz", + "integrity": "sha512-vRdSY0ovE+wfTvYeguPp/QAxvGejLADO8CzJkas0PxdCQiyLuTscKsYE82XcvX2kitMexvH71lNF0ggnGoMRXA==", + "dev": true, + "dependencies": { + "@angular-eslint/eslint-plugin": "16.0.3", + "@angular-eslint/eslint-plugin-template": "16.0.3", + "@nx/devkit": "16.2.2", + "ignore": "5.2.4", + "nx": "16.2.2", + "strip-json-comments": "3.1.1", + "tmp": "0.2.1" + }, + "peerDependencies": { + "@angular/cli": ">= 16.0.0 < 17.0.0" + } + }, + "node_modules/@angular-eslint/template-parser": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.0.3.tgz", + "integrity": "sha512-IAWdwp/S9QC3EMiVxSS0E3ABy9PSidN3PW0Ll2EtM3mzXMYlpZXmxqd+B1xV/xKWzhk1Mp04QX8hHfG6Vq+qaQ==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "eslint-scope": "^7.0.0" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/utils": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.0.3.tgz", + "integrity": "sha512-QsbUVHJLk+fE08/D4y3wOyGk1iX2LVSygw+uzilbaAXfjD5/c0Ei5FbVx2mMYPk+aOl4yrvGQW3dmetMiAR0MQ==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "@typescript-eslint/utils": "5.59.7" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular/animations": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.1.3.tgz", + "integrity": "sha512-ET6ahrlbOyTYXOTouKs2VJxx0CMTrYkfz0HfI6IHnSKBC6wguDxXYnamMouHgrCkDDEB5qClfGHyS9se0AOX4w==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "16.1.3" + } + }, + "node_modules/@angular/cdk": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.9.tgz", + "integrity": "sha512-koaM07N1AIQ5oHU27l0/FoQSSoYAwlAYwVZ4Di3bYrJsTBNCN2Xsby7wI8gZxdepMnV4Fe9si382BDBov+oO4Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^15.0.0 || ^16.0.0", + "@angular/core": "^15.0.0 || ^16.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.1.3.tgz", + "integrity": "sha512-D0gU12z/N2oJ+s6pggAnWYrTUZ+2duGb3Y5oUyClsubz7JWpAwHjSZpb8exPUrgYhr+qIEMGO685y1JazJQ2tA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1601.3", + "@angular-devkit/core": "16.1.3", + "@angular-devkit/schematics": "16.1.3", + "@schematics/angular": "16.1.3", + "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "4.1.3", + "ini": "4.1.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "npm-package-arg": "10.1.0", + "npm-pick-manifest": "8.0.1", + "open": "8.4.2", + "ora": "5.4.1", + "pacote": "15.2.0", + "resolve": "1.22.2", + "semver": "7.5.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.1.3.tgz", + "integrity": "sha512-ZzJ6EwQHUkiZYV0zH/UxyUYW5uxomsyk7tdtqZIxAR5m2ktYkQ5XlqgPjBO8voF54Rs5Ot43RkPCLesbZyJDsw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "16.1.3", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.1.3.tgz", + "integrity": "sha512-7Ckvssk9+s5xLyXvp72IwAw5vd/Osa3tR6oiQatdbw+O3XjLO04QycoGXwkp/fYVexGsjFyOn6QJ5n1F/PYPbQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "16.1.3" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.1.3.tgz", + "integrity": "sha512-aUqnIV9rRTBNgiQRS0Gv6lhghaGj1vpVRyXgiE4VnTR9uBONSsGKMNALYBBhXRTSk2e0cvutt0ubLgmNpdyWyQ==", + "dev": true, + "dependencies": { + "@babel/core": "7.22.5", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.1.2", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/compiler": "16.1.3", + "typescript": ">=4.9.3 <5.2" + } + }, + "node_modules/@angular/core": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.1.3.tgz", + "integrity": "sha512-yhRo9hVS8KhfcEgzciWuRWF4Pnnko98bmSJTqd7u8Kys6z3Uj0qgXMssXHIPUALe3mQKjVkdSZPLIZ9/CaVn/Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.13.0" + } + }, + "node_modules/@angular/forms": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.1.3.tgz", + "integrity": "sha512-9tJHgoi/Jmeo30zfnReVZWFcd1WthR+QwYUNwPev+ys58u1mB0cDGORvROySmC2YUyXFSpXt8sxwyWCkYvaV2w==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "16.1.3", + "@angular/core": "16.1.3", + "@angular/platform-browser": "16.1.3", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.1.3.tgz", + "integrity": "sha512-qZA6Lua2fpBe+KD/QArY/4hilypSZFcTcJsPjZwIzo5pavXqYDI8BVghwh5dcZoUa56hVRDJjv+XW6kl8m9Tdw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/animations": "16.1.3", + "@angular/common": "16.1.3", + "@angular/core": "16.1.3" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.1.3.tgz", + "integrity": "sha512-UHxSWpPB5+FSv8zm8T+4ZikLqyy+VE6GlOLp/DdgEz77j81rz2C1pMqozwTnVbD16XbI4rhTp+RFY3C9ArWOtw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "16.1.3", + "@angular/compiler": "16.1.3", + "@angular/core": "16.1.3", + "@angular/platform-browser": "16.1.3" + } + }, + "node_modules/@angular/router": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.1.3.tgz", + "integrity": "sha512-bkn8cWGBKKZidDaP+R7g/S/6miSfH8iP24d2k86Awo+vaO+7G/5WWGfKJMKK8UNM/A5ueX6ugAZrMHpQ9e6Y4w==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "16.1.3", + "@angular/core": "16.1.3", + "@angular/platform-browser": "16.1.3", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@assemblyscript/loader": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", + "dev": true + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", + "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/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/@babel/generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", + "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", + "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz", + "integrity": "sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@nicolo-ribaudo/semver-v6": "^6.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz", + "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "regexpu-core": "^5.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz", + "integrity": "sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", + "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", + "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", + "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", + "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", + "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", + "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", + "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", + "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "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-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.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-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", + "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", + "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", + "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", + "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", + "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", + "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", + "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", + "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", + "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", + "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", + "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", + "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", + "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", + "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", + "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", + "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", + "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", + "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", + "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", + "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.5.tgz", + "integrity": "sha512-bg4Wxd1FWeFx3daHFTWk1pkSWK/AyQuiyAoeZAOkAOUBjnZPH6KT7eMxouV47tQ6hl6ax2zyAWBdWZXbrvXlaw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/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/@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", + "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", + "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.5", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-classes": "^7.22.5", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", + "@babel/plugin-transform-numeric-separator": "^7.22.5", + "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5", + "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", + "core-js-compat": "^3.30.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/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/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "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/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", + "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cds/city": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@cds/city/-/city-1.1.0.tgz", + "integrity": "sha512-S9K+Q39BGOghyLHmR0Wdcmu1i1noSUk8HcvMj+3IaohZw02WFd99aPTQDHJeseXrXZP3CNovaSlePI0R11NcFg==", + "optional": true + }, + "node_modules/@cds/core": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@cds/core/-/core-6.4.4.tgz", + "integrity": "sha512-DX02/KyCkECMvxuBeqrk/CmQGTynonQa9GDN8bK/Qje43esU4iYvoTfiuBSBGaNIQYv/0dFCY85QHcL68CCATg==", + "dependencies": { + "lit": "^2.1.3", + "ramda": "^0.29.0", + "tslib": "^2.3.1" + }, + "optionalDependencies": { + "@cds/city": "^1.1.0", + "modern-normalize": "1.1.0" + } + }, + "node_modules/@clr/angular": { + "version": "13.18.2", + "resolved": "https://registry.npmjs.org/@clr/angular/-/angular-13.18.2.tgz", + "integrity": "sha512-LEvua9GItCheHNESey5yJb2oBBI0lvtgUJCgOJLqVsMM9BDtkE/l5R4rBcIFjwnHg+tnuM0xhnUqKaCJSDr0OA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "13 || 14 || 15", + "@angular/core": "13 || 14 || 15", + "@cds/core": "^5.6.0 || ^6.0.0", + "@clr/ui": "13.18.2" + } + }, + "node_modules/@clr/icons": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@clr/icons/-/icons-13.0.2.tgz", + "integrity": "sha512-bdcSuFvQAbIIp8Q2Fm55BjHW5cawP4xEOkZf2IEIin0d9ViRcAJNjACBCOMDhx2up7nPZsXwN2gL8zJhL7TSZQ==", + "peerDependencies": { + "@webcomponents/custom-elements": "^1.0.0" + } + }, + "node_modules/@clr/ui": { + "version": "13.18.2", + "resolved": "https://registry.npmjs.org/@clr/ui/-/ui-13.18.2.tgz", + "integrity": "sha512-ippjTqG0FHMW3/3UPO3iskWh+g7mH4twSpgkAqL4oPTRlyCVFPtilW69FqTGAioVmO2gLxCyxIxZBDNcYoJwog==" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "2.88.11", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", + "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", + "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", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.10.3", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/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/@cypress/request/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/@cypress/webpack-preprocessor": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.17.1.tgz", + "integrity": "sha512-FE/e8ikPc8z4EVopJCaior3RGy0jd2q9Xcp5NtiwNG4XnLfEnUFTZlAGwXe75sEh4fNMPrBJW1KIz77PX5vGAw==", + "dev": true, + "dependencies": { + "bluebird": "3.7.1", + "debug": "^4.3.4", + "lodash": "^4.17.20" + }, + "peerDependencies": { + "@babel/core": "^7.0.1", + "@babel/preset-env": "^7.0.0", + "babel-loader": "^8.0.2 || ^9", + "webpack": "^4 || ^5" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" + }, + "node_modules/@handsontable/angular": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@handsontable/angular/-/angular-13.0.0.tgz", + "integrity": "sha512-wbka5xCFdD9gdtceu7UuVac+0I4zg5RDlK/u6vv9ACmrgPbYTkR5W/KqhG2FLmpUfICGEqV1cyzmQRavdQH1UQ==", + "optionalDependencies": { + "tslib": "^2.2.0" + }, + "peerDependencies": { + "@angular/animations": ">=12.0.0", + "@angular/common": ">=12.0.0", + "@angular/compiler": ">=12.0.0", + "@angular/core": ">=12.0.0", + "@angular/forms": ">=12.0.0", + "@angular/platform-browser": ">=12.0.0", + "@angular/platform-browser-dynamic": ">=12.0.0", + "@angular/router": ">=12.0.0", + "handsontable": "^13.0.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@hpcc-js/wasm": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.5.0.tgz", + "integrity": "sha512-G26BamgaHW46f6P8bmkygapgNcy+tTDMwIvCzmMzdp39sxUS1u4gaT/vR2SSDc4x3SfL5RE4B2B8ef/wd429Hg==", + "dependencies": { + "yargs": "17.6.2" + }, + "bin": { + "dot-wasm": "bin/dot-wasm.js" + } + }, + "node_modules/@hpcc-js/wasm/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@hpcc-js/wasm/node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz", + "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==" + }, + "node_modules/@lit/reactive-element": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz", + "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.0.0" + } + }, + "node_modules/@ngtools/webpack": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.1.3.tgz", + "integrity": "sha512-YTL1RzP7ErJqskx+ZwdC/nWsOSBfC4yYWmMyWL2J0d+oJ3N2XIzrKVoDcZ4IVzv3Du+3zoGp0ups/wWXvfzM/Q==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^16.0.0", + "typescript": ">=4.9.3 <5.2", + "webpack": "^5.54.0" + } + }, + "node_modules/@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "dev": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "dev": true, + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@nrwl/devkit": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.2.2.tgz", + "integrity": "sha512-R8OSh33HtGycSuu0KshpH/tsTdi6j4w7DuIb+Sa59UDIkchpvMeNAz8tj/05Z2tTntDZnYqPkmCs6rkZ4PvY4Q==", + "dev": true, + "dependencies": { + "@nx/devkit": "16.2.2" + } + }, + "node_modules/@nrwl/tao": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-16.2.2.tgz", + "integrity": "sha512-cPj6b+wSWs2WNFQ0p1fMyrvSLjkKJo7vXQTtd7MXNJT2NWEZdCtRy+nidZzjs7gKvVXGdZ8zDBXmCHWorOieXw==", + "dev": true, + "dependencies": { + "nx": "16.2.2" + }, + "bin": { + "tao": "index.js" + } + }, + "node_modules/@nx/devkit": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-16.2.2.tgz", + "integrity": "sha512-MTYzetk4AQ9u2syEb9z+drDsu6U6NRAXVuUDMNg0tpZcbtE9bCSLH2ngfvTCqmLrAMBsJZRdv0twS1iepMhlAg==", + "dev": true, + "dependencies": { + "@nrwl/devkit": "16.2.2", + "ejs": "^3.1.7", + "ignore": "^5.0.4", + "semver": "7.3.4", + "tmp": "~0.2.1", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "nx": ">= 15 <= 17" + } + }, + "node_modules/@nx/devkit/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nx/devkit/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/@nx/nx-darwin-arm64": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.2.2.tgz", + "integrity": "sha512-CKfyLl92mhWqpv1hRTj3WgjVBY6yj3Et5T31m1N0assNWdTfuSB4ycdWzdlxXHx3yptnTOD/FCymTpUQI0GZRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.2.2.tgz", + "integrity": "sha512-++uDfp/Oo8DDVU53DiJVkRNjNbOLzahDH6dINeA/3yTCU/IS0wXoaoclNZBReMWlDKTVvWgLF/eSbGINMqUHRg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.2.2.tgz", + "integrity": "sha512-A4XFk63Q7fxgZaHnigIeofp/xOT2ZGDoNUyzld+UTlyJyNcClcOcqrro74aKOCG7PH0D56oE06JW3g7GKszgsA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.2.2.tgz", + "integrity": "sha512-aQpTLVSawFVr33pBWjj8elqvjA5uWvzDW7hGaFQPgWgmjxrtJikIAkcLjfNOz8XYjRAP4OZkTVh4/E3GUch0kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.2.2.tgz", + "integrity": "sha512-20vyNYQ2SYSaWdxORj9HdOyGxiqE8SauaFiBjjid6/e5mSyaSKu+HHGsvhDUqzlWn3OaABKBqx0iYa9Kmf3BOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.2.2.tgz", + "integrity": "sha512-0G8kYpEmGHD+tT7RvUEvVXvPbvQD9GfEjeWEzZAdNAAMJu7JFjIo/oZDJYV7cMvXnC+tbpI9Gba5xfv8Al95eA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.2.2.tgz", + "integrity": "sha512-Incv7DbKLfh6kakzMBuy6GYRgI+jEdZBRiFw0GoN9EsknmrPT/URn+w6uuicGGEXOLYpO3HUO3E374+b5Wz2zg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.2.2.tgz", + "integrity": "sha512-8m+Usj9faCl0pdQLFeBGhbYUObT3/tno5oGMPtJLyRjITNvTZAaIS4FFctp/rwJPehDBRQsUxwMJ2JRaU4jQdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.2.2.tgz", + "integrity": "sha512-liHtyVVOttcqHIV3Xrg/1AJzEgfiOCeqJsleHXHGgPr1fxPx7SIZaa3/QnDY1lNMN+t6Gvj0/r2Ba3iuptYD3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", + "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.2.1", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sasjs/adapter": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.6.tgz", + "integrity": "sha512-l6BJNqWa4k0OpLgghED/BqTzUgWCgv7BGJpKheMTdHys3f5KgyKtEqXwwloXSvCTPVn441zsRT2Z0WsS7DNWrw==", + "hasInstallScript": true, + "dependencies": { + "@sasjs/utils": "2.52.0", + "axios": "0.27.2", + "axios-cookiejar-support": "1.0.1", + "form-data": "4.0.0", + "https": "1.0.0", + "tough-cookie": "4.0.0" + } + }, + "node_modules/@sasjs/adapter/node_modules/@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "hasInstallScript": true, + "dependencies": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "node_modules/@sasjs/adapter/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sasjs/adapter/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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/@sasjs/adapter/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sasjs/adapter/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==" + }, + "node_modules/@sasjs/adapter/node_modules/fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sasjs/adapter/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sasjs/adapter/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@sasjs/adapter/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sasjs/adapter/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@sasjs/utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-3.3.0.tgz", + "integrity": "sha512-ZJ+c2d/rEoF340Ay3TZrXO4c2ain7AvSzkRuKG2H2qxwIlQQTk/9Rbknmy0mo3Y/QRScBYl0Fw5xSZ8SMHjljg==", + "hasInstallScript": true, + "dependencies": { + "@fast-csv/format": "4.3.5", + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "node_modules/@sasjs/utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sasjs/utils/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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/@sasjs/utils/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sasjs/utils/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==" + }, + "node_modules/@sasjs/utils/node_modules/fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sasjs/utils/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sasjs/utils/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@sasjs/utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sasjs/utils/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@schematics/angular": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.1.3.tgz", + "integrity": "sha512-bNSxCLf6f+/dsQ1k3PhcZhrC/qgJSCpM6h3m6ATpjR+tYW/v7WR1OyE5r3DQmDe7NJSazBvpbrRtg8xjRsMzvw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.1.3", + "@angular-devkit/schematics": "16.1.3", + "jsonc-parser": "3.2.0" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sheet/crypto": { + "version": "1.20211122.1", + "resolved": "https://pylon.sheetjs.com:54111/@sheet%2fcrypto/-/crypto-1.20211122.1.tgz", + "integrity": "sha512-G3/HWyzFUYbbVQoQIa+KSeMOhFnK492Ep595FXbzWN9IGZSwuvFl4saEyMl8R8pE2Al5YgSZuR9MpDpx3f7Izg==", + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz", + "integrity": "sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.2.tgz", + "integrity": "sha512-vjwcYePJzM01Ha6oWWZ9gNcdIgnzyFxfqfWzph483DPJTH8Tb7f7bQRRll3CYVkyH56j0AgcPAcl6Vg95DPF+Q==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha512-C4vwOHrhsvxn7UFyk4NDQNUpgNKdWsT/bL39UWyD75KSEOObZSKa9mYDOCM5FGeJG2qtbG0XiEbUKND2+j0WOg==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==", + "dev": true + }, + "node_modules/@types/d3-color": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz", + "integrity": "sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA==" + }, + "node_modules/@types/d3-graphviz": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/d3-graphviz/-/d3-graphviz-2.6.7.tgz", + "integrity": "sha512-dKJjD5HiFvAmC0FL/c70VB1diie8FCpyiCZfxMlf6TwYBqUyFvS4XJt6MoxjIuQTJhKDBGzrIvDOgM8gYMLSVA==", + "dependencies": { + "@types/d3-selection": "^1", + "@types/d3-transition": "^1", + "@types/d3-zoom": "^1" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz", + "integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==", + "dependencies": { + "@types/d3-color": "^1" + } + }, + "node_modules/@types/d3-selection": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.3.tgz", + "integrity": "sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==" + }, + "node_modules/@types/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg==", + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-zoom": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.4.tgz", + "integrity": "sha512-K+6jCM9llyC5U4WvkmiXbCoOIuUX03Wi72C/L9PMPVxymWDaxTHzDgHD/HYlEyDRGiVp7D77m7XPcD/m/TRDrw==", + "dependencies": { + "@types/d3-interpolate": "^1", + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/es6-shim": { + "version": "0.31.42", + "resolved": "https://registry.npmjs.org/@types/es6-shim/-/es6-shim-0.31.42.tgz", + "integrity": "sha512-GS3EuEgiGv/TP7bwPLOlkSiTfdSL4XHOj0jJuvz4/UbR89QrC4Py3lYlMlH/7w0dKfJ8fIori0rVIl2gQ7lb5A==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.40.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", + "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz", + "integrity": "sha512-S6pvzQDvMZHrkBz2Mcn/8Du7cpr76PlRJBAoHnSDNbulULsH5dp0Gns+WRyNX5LHejz/ljxK4/vIHK/caHt6SQ==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "node_modules/@types/lodash-es": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz", + "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/marked": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.1.tgz", + "integrity": "sha512-vSSbKZFbNktrQ15v7o1EaH78EbWV+sPQbPjHG+Cp8CaNcPFUEfjZ0Iml/V0bFDwsTlYe8o6XC5Hfdp91cqPV2g==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.20.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.50.tgz", + "integrity": "sha512-+9axpWx2b2JCVovr7Ilgt96uc6C1zBKOQMpGtRbWT9IoR/8ue32GGMfGA4woP8QyP2gBs6GQWEVM3tCybGCxDA==" + }, + "node_modules/@types/pikaday": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@types/pikaday/-/pikaday-1.7.4.tgz", + "integrity": "sha512-0KsHVyw5pTG829nqG4IRu7m+BFQlFEBdbE/1i3S5182HeKUKv1uEW0gyEmkJVp5i4IV+9pyh23O83+KpRkSQbw==", + "dependencies": { + "moment": ">=2.14.0" + } + }, + "node_modules/@types/prompts": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.13.tgz", + "integrity": "sha512-jwMOIGy49VruR/gYehhJYgpVzB+EVpEE7t7j9m1oTo4HMpOe7KmsyqdBuoxAzA5B4caUgx0cKrWr7wUEqMXJ7Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/text-encoding": { + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/@types/text-encoding/-/text-encoding-0.0.35.tgz", + "integrity": "sha512-jfo/A88XIiAweUa8np+1mPbm3h2w0s425YrI8t3wk5QxhH6UI7w517MboNVnGDeMSuoFwA8Rwmklno+FicvV4g==" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" + }, + "node_modules/@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", + "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/type-utils": "5.61.0", + "@typescript-eslint/utils": "5.61.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", + "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/utils": "5.61.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", + "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/parser": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", + "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", + "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", + "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/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/@typescript-eslint/visitor-keys": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", + "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@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/@yarnpkg/parsers": { + "version": "3.0.0-rc.48.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.48.1.tgz", + "integrity": "sha512-qEewJouhRvaecGjbkjz9kMKn96UASbDodNrE5MYy2TrXkHcisIkbMxZdGBYfAq+s1dFtCSx/5H4k5bEkfakM+A==", + "dev": true, + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@zkochan/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ally.js": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/ally.js/-/ally.js-1.4.1.tgz", + "integrity": "sha512-ZewdfuwP6VewtMN36QY0gmiyvBfMnmEaNwbVu2nTS6zRt069viTgkYgaDiqu6vRJ1VJCriNqV0jGMu44R8zNbA==", + "dev": true, + "dependencies": { + "css.escape": "^1.5.0", + "platform": "1.3.3" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "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": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "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": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "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": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "dependencies": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@types/tough-cookie": ">=2.3.3", + "axios": ">=0.16.2", + "tough-cookie": ">=2.3.3" + } + }, + "node_modules/axobject-query": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/babel-loader": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", + "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^3.3.2", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", + "integrity": "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.1", + "@nicolo-ribaudo/semver-v6": "^6.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz", + "integrity": "sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.1", + "core-js-compat": "^3.31.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz", + "integrity": "sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "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/bignumber.js": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz", + "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "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/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/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "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==", + "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": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "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==", + "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==", + "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==", + "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.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "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": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" + }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/caniuse-lite": { + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "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/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/chevrotain": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz", + "integrity": "sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg==", + "dependencies": { + "regexp-to-ast": "0.4.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "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/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", + "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "dependencies": { + "colors": "1.0.3" + }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "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/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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "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==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "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/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "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": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/consola": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.0.tgz", + "integrity": "sha512-vlcSGgdYS26mPf7qNi+dCisbhiyDnrN1zaRbw3CSuc2wGOMEGGPsp46PdRG5gqXwgtJfjxDkxRNAgRPr1B77vQ==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "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": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.1.tgz", + "integrity": "sha512-DPCBxctI7dN4EeIqjW2KGqgdcUMbrhJ9AzON+PlxCtvppWhubTLD4+a0GFxiym14ZvacUydTPjLPc2DlKz7EIg==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-js-compat": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.0.tgz", + "integrity": "sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-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": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "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==", + "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==", + "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/critters": { + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.19.tgz", + "integrity": "sha512-Fm4ZAXsG0VzWy1U30rP4qxbaWGSsqXDgSupJW1OUJGDAs0KWC+j37v7p5a2kZ9BPJvhRzWm3be+Hc9WvQOBUOw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "css-select": "^5.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.2", + "htmlparser2": "^8.0.2", + "postcss": "^8.4.23", + "pretty-bytes": "^5.3.0" + } + }, + "node_modules/critters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/critters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/critters/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/critters/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/critters/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/critters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "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==", + "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-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "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/csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, + "node_modules/cypress": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", + "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^2.88.10", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.6", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.3.2", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cypress-file-upload": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz", + "integrity": "sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==", + "dev": true, + "engines": { + "node": ">=8.2.1" + }, + "peerDependencies": { + "cypress": ">3.0.0" + } + }, + "node_modules/cypress-plugin-tab": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cypress-plugin-tab/-/cypress-plugin-tab-1.0.5.tgz", + "integrity": "sha512-QtTJcifOVwwbeMP3hsOzQOKf3EqKsLyjtg9ZAGlYDntrCRXrsQhe4ZQGIthRMRLKpnP6/tTk6G0gJ2sZUfRliQ==", + "dev": true, + "dependencies": { + "ally.js": "^1.4.1" + } + }, + "node_modules/cypress-real-events": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/cypress-real-events/-/cypress-real-events-1.8.1.tgz", + "integrity": "sha512-8fFnA8EzS3EVbAmpSEUf3A8yZCmfU3IPOSGUDVFCdE1ke1gYL1A+gvXXV6HKUbTPRuvKKt2vpaMbUwYLpDRswQ==", + "dev": true, + "peerDependencies": { + "cypress": "^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x || ^12.x" + } + }, + "node_modules/cypress/node_modules/@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==", + "dev": true + }, + "node_modules/cypress/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cypress/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/cypress/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/cypress/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/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/cypress/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/cypress/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/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/cypress/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/cypress/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-graphviz": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.0.2.tgz", + "integrity": "sha512-EVRow9rnFgm/L1trbbnu2PGOND11IcSEdWXbrDbz9hH0/Kj3YM2AqMkkTN/EAWgawD5/zryyCy+3Vm05oSJ1Kg==", + "dependencies": { + "@hpcc-js/wasm": "2.5.0", + "d3-dispatch": "^3.0.1", + "d3-format": "^3.1.0", + "d3-interpolate": "^3.0.1", + "d3-path": "^3.1.0", + "d3-timer": "^3.0.1", + "d3-transition": "^3.0.1", + "d3-zoom": "^3.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "d3-selection": "^3.0.0" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/deep-equal": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", + "integrity": "sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.0", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/default-gateway/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-gateway/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "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": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "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==", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.5.tgz", + "integrity": "sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA==" + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "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": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.450", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", + "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "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==" + }, + "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": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "6.5.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.1.tgz", + "integrity": "sha512-mGqhI+D7YxS9KJMppR6Iuo37Ed3abhU8NdfgSvJSDUafQutrN+sPTncJYTyM9+tkhSmWodKtVYGPPHyXJEwEQA==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.1.0", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.1.0.tgz", + "integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "devOptional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": 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-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "dev": true + }, + "node_modules/es6-shim": { + "version": "0.35.8", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.8.tgz", + "integrity": "sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.19.tgz", + "integrity": "sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/eslint/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/eslint/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/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/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/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "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": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter-asyncresource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", + "dev": true + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "dev": true + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "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==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "dev": true, + "dependencies": { + "merge": "^1.2.0" + } + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/executable/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "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": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "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/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/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/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "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/external-editor/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/external-editor/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/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "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/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "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-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "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": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "dependencies": { + "traverse-chain": "~0.1.0" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "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-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/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "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==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", + "integrity": "sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==", + "dev": true, + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fsu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", + "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-describe": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-describe/-/git-describe-4.1.1.tgz", + "integrity": "sha512-JC8ganO5kO80G8+XE98TDDjnMXQN3Estk3qdJuG2EGRF/l6zuMTMcN+8OSfQZ5FWpqIRLB015anWX4aSRgnxAQ==", + "dev": true, + "dependencies": { + "@types/semver": "^7.3.8", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=4.0.0" + }, + "optionalDependencies": { + "semver": "^5.6.0" + } + }, + "node_modules/git-describe/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/glob": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.1.tgz", + "integrity": "sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.10.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "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/handsontable": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-13.0.0.tgz", + "integrity": "sha512-qjfUQCJCeD5OJbUnXpEaruJJ8MfI2/yZI6q0wAGd+85tCAcpknJODR9FqRHpcTrKf+Mc9HO/CJ6qBAJHiXSrhA==", + "dependencies": { + "@types/pikaday": "1.7.4", + "core-js": "^3.0.0", + "dompurify": "^2.1.1", + "moment": "2.29.4", + "numbro": "2.1.2", + "pikaday": "1.8.2" + }, + "optionalDependencies": { + "hyperformula": "^2.4.0" + } + }, + "node_modules/handsontable/node_modules/core-js": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz", + "integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/handsontable/node_modules/numbro": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/numbro/-/numbro-2.1.2.tgz", + "integrity": "sha512-7w833BxZmKGLE9HI0aREtNVRVH6WTYUUlWf4qgA5gKNhPQ4F/MRZ14sc0v8eoLORprk9ZTVwYaLwj8N3Zgxwiw==", + "dependencies": { + "bignumber.js": "^8.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "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==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hdr-histogram-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", + "dev": true, + "dependencies": { + "@assemblyscript/loader": "^0.10.1", + "base64-js": "^1.2.0", + "pako": "^1.0.3" + } + }, + "node_modules/hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", + "dev": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "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/hpack.js/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/hpack.js/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/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "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/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/hyperformula": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hyperformula/-/hyperformula-2.5.0.tgz", + "integrity": "sha512-HkP7JZAmG7EQFF5XAhB3aGtTHvafblSRITTMYUsVoT9czIvYY7CvMQFfK1JNHJUVS844t8bnJpKEOqwcgBcHZg==", + "dependencies": { + "chevrotain": "^6.5.0", + "tiny-emitter": "^2.1.0", + "unorm": "^1.6.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz", + "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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==" + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "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": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "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": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "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": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "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": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "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": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/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/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "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": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", + "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jake/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/jake/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/jake/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/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jasmine-core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz", + "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==", + "dev": true + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", + "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.9.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz", + "integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.3", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/jquery": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" + }, + "node_modules/jquery-datetimepicker": { + "version": "2.5.21", + "resolved": "https://registry.npmjs.org/jquery-datetimepicker/-/jquery-datetimepicker-2.5.21.tgz", + "integrity": "sha512-wDTpZ4f1PWd1XGaIIE0n6jLynlm+akBJ7/NjaB1bk2UJSS593CHJPZ3+FNEXoyvNVUeBlBC0oX6WTfCyfUhX/w==", + "dependencies": { + "jquery": ">= 1.7.2", + "jquery-mousewheel": ">= 3.1.13", + "php-date-formatter": "^1.3.4" + } + }, + "node_modules/jquery-mousewheel": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", + "integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg==" + }, + "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.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "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": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "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-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "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": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "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": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/jsrsasign": { + "version": "10.8.6", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.8.6.tgz", + "integrity": "sha512-bQmbVtsfbgaKBTWCKiDCPlUPbdlRIK/FzSwT3BzIgZl/cU6TqXu6pZJsCI/dJVrZ9Gir5GC4woqw9shH/v7MBw==", + "funding": { + "url": "https://github.com/kjur/jsrsasign#donations" + } + }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, + "node_modules/karma": { + "version": "6.3.20", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.20.tgz", + "integrity": "sha512-HRNQhMuKOwKpjYlWiJP0DUrJOh+QjaI/DTaD8b9rEm4Il3tJ8MijutVZH4ts10LuUFst/CedwTS6vieCN8yTSw==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", + "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-chrome-launcher/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/karma-coverage": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.1.1.tgz", + "integrity": "sha512-oxeOSBVK/jdZsiX03LhHQkO4eISSQb5GbHi6Nsw3Mw7G4u6yUgacBAftnO7q+emPBLMsrNbz1pGIrj+Jb3z17A==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/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/karma-jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.2.tgz", + "integrity": "sha512-ggi84RMNQffSDmWSyyt4zxzh2CQGwsxvYYsprgyR1j8ikzIduEdOlcLvXjZGwXG/0j41KUXOWsUCBfbEHPWP9g==", + "dev": true, + "dependencies": { + "jasmine-core": "^3.6.0" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "karma": "*" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==", + "dev": true, + "peerDependencies": { + "jasmine-core": ">=3.8", + "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/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/less": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", + "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", + "dev": true, + "dependencies": { + "klona": "^2.0.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/less/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, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/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, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/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, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "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/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "bin": { + "license-checker": "bin/license-checker" + } + }, + "node_modules/license-checker/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/license-checker/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/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/lit": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz", + "integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==", + "dependencies": { + "@lit/reactive-element": "^1.6.0", + "lit-element": "^3.3.0", + "lit-html": "^2.7.0" + } + }, + "node_modules/lit-element": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz", + "integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.1.0", + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.7.0" + } + }, + "node_modules/lit-html": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz", + "integrity": "sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "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/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "node_modules/lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==", + "dev": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/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/log-update/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/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/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/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "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/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "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/make-dir/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/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": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/marked": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.0.tgz", + "integrity": "sha512-z3/nBe7aTI8JDszlYLk7dDVNpngjw0o1ZJtrA9kIfkkHcIF+xH7mO23aISl4WxP83elU+MFROgahqdpd05lMEQ==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "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==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "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/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.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": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "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==" + }, + "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": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "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-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect/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/minipass-fetch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", + "dev": true, + "dependencies": { + "minipass": "^5.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "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-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/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/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream/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/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/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/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/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/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/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/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mochawesome": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz", + "integrity": "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "diff": "^5.0.0", + "json-stringify-safe": "^5.0.1", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isobject": "^3.0.2", + "lodash.isstring": "^4.0.1", + "mochawesome-report-generator": "^6.2.0", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "mocha": ">=7" + } + }, + "node_modules/mochawesome-report-generator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz", + "integrity": "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "dateformat": "^4.5.1", + "escape-html": "^1.0.3", + "fs-extra": "^10.0.0", + "fsu": "^1.1.1", + "lodash.isfunction": "^3.0.9", + "opener": "^1.5.2", + "prop-types": "^15.7.2", + "tcomb": "^3.2.17", + "tcomb-validation": "^3.3.0", + "validator": "^13.6.0", + "yargs": "^17.2.1" + }, + "bin": { + "marge": "bin/cli.js" + } + }, + "node_modules/mochawesome-report-generator/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mochawesome-report-generator/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/mochawesome-report-generator/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/mochawesome-report-generator/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/mochawesome-report-generator/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mochawesome-report-generator/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/mochawesome-report-generator/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/mochawesome-report-generator/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mochawesome-report-generator/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/mochawesome/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mochawesome/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/mochawesome/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/mochawesome/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/mochawesome/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/mochawesome/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==", + "optional": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mutationobserver-shim": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/mutationobserver-shim/-/mutationobserver-shim-0.3.7.tgz", + "integrity": "sha512-oRIDTyZQU96nAiz2AQyngwx1e89iApl2hN5AOYwyxLUB47UYsU3Wv9lJWqH5y/QdiYkc5HQLi23ZNB3fELdHcQ==", + "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/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/needle": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/ngx-clipboard": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-16.0.0.tgz", + "integrity": "sha512-rZ/Eo1PqiKMiyF8tdjhmUkoUu68f7OzBJ7YH1YFeh2RAaNrerTaW8XfFOzppSckjFQqA1fwGSYuTTJlDhDag5w==", + "dependencies": { + "ngx-window-token": ">=7.0.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": ">=13.0.0", + "@angular/core": ">=13.0.0" + } + }, + "node_modules/ngx-json-viewer": { + "version": "3.2.1", + "resolved": "file:libraries/ngx-json-viewer-3.2.1.tgz", + "integrity": "sha512-Qa24rEXam1gNr3pAg31Xb/ycs+yFcF0Y+woCcPET3XKaxQthpZ9T5VM7tPRRDWUFEWsTZuOQARsAdN9DAIPp8A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + } + }, + "node_modules/ngx-window-token": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ngx-window-token/-/ngx-window-token-7.0.0.tgz", + "integrity": "sha512-5+XfRVSY7Dciu8xyCNMkOlH2UfwR9W2P1Pirz7caaZgOZDjFbL8aEO2stjfJJm2FFf1D6dlVHNzhLWGk9HGkqA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=13.0.0", + "@angular/core": ">=13.0.0" + } + }, + "node_modules/nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "!win32" + ], + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "dev": true + }, + "node_modules/nodejs": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/nodejs/-/nodejs-0.0.0.tgz", + "integrity": "sha512-1V+0HwaB/dhxzidEFc4uJ3k52gLI4B6YBZgJIofjwYCSAkD6CI0me6TDBT2QM2nbGWNxCHcq9/wVynzQYZOhUg==" + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz", + "integrity": "sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", + "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/numbro": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/numbro/-/numbro-2.3.6.tgz", + "integrity": "sha512-pxpoTT3hVxQGaOA2RTzXR/muonQNd1K1HPJbWo7QOmxPwiPmoFCFfsG9XXgW3uqjyzezJ0P9IvCPDXUtJexjwg==", + "dependencies": { + "bignumber.js": "^8.1.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-16.2.2.tgz", + "integrity": "sha512-gOcpqs6wf8YdFIq6P0IlMxBGr2c27pM55zpqO7epSlN6NqW6SOFKnZa+6z4NV9qmifMqzWPx2VF0BY54ARuqYg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nrwl/tao": "16.2.2", + "@parcel/watcher": "2.0.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "^3.0.0-rc.18", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.0.0", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^7.0.2", + "dotenv": "~10.0.0", + "enquirer": "~2.3.6", + "fast-glob": "3.2.7", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.3.4", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "v8-compile-cache": "2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "16.2.2", + "@nx/nx-darwin-x64": "16.2.2", + "@nx/nx-linux-arm-gnueabihf": "16.2.2", + "@nx/nx-linux-arm64-gnu": "16.2.2", + "@nx/nx-linux-arm64-musl": "16.2.2", + "@nx/nx-linux-x64-gnu": "16.2.2", + "@nx/nx-linux-x64-musl": "16.2.2", + "@nx/nx-win32-arm64-msvc": "16.2.2", + "@nx/nx-win32-x64-msvc": "16.2.2" + }, + "peerDependencies": { + "@swc-node/register": "^1.4.2", + "@swc/core": "^1.2.173" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nx/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/nx/node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/nx/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/nx/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/nx/node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/nx/node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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/nx/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/nx/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/nx/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/nx/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/nx/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/nx/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/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "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": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "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": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "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/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "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/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/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "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/pacote": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dev": true, + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "devOptional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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/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/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz", + "integrity": "sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", + "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "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": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "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/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/php-date-formatter": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/php-date-formatter/-/php-date-formatter-1.3.6.tgz", + "integrity": "sha512-/CKsZYmAwXeNh8KpD/CF9hcJDZNhdb2ICN8+qgqOt5sUu9liZIxZ1R284TNj5MtPt8RjG5X0xn6WSqL0kcKMBg==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pikaday": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/pikaday/-/pikaday-1.8.2.tgz", + "integrity": "sha512-TNtsE+34BIax3WtkB/qqu5uepV1McKYEgvL3kWzU7aqPCpMEN6rBF3AOwu4WCwAealWlBGobXny/9kJb49C1ew==" + }, + "node_modules/piscina": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", + "dev": true, + "dependencies": { + "eventemitter-asyncresource": "^1.0.0", + "hdr-histogram-js": "^2.0.1", + "hdr-histogram-percentiles-obj": "^3.0.0" + }, + "optionalDependencies": { + "nice-napi": "^1.0.2" + } + }, + "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/platform": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz", + "integrity": "sha512-VJK1SRmXBpjwsB4YOHYSturx48rLKMzHgCqDH2ZDa6ZbMS/N5huoNqyQdK5Fj/xayu3fqbXckn5SeCS1EbMDZg==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.2.tgz", + "integrity": "sha512-c7qDlXErX6n0VT+LUsW+nwefVtTu3ORtVvK8EXuUIDcxo+b/euYqpuHlJAvePb0Af5e8uMjR/13e0lTuYifaig==", + "dev": true, + "dependencies": { + "cosmiconfig": "^8.1.3", + "jiti": "^1.18.2", + "klona": "^2.0.6", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.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-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/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/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "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/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "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.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ramda": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", + "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "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==", + "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.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/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/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/read-installed/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-installed/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-installed/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/read-installed/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/read-installed/node_modules/read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "node_modules/read-installed/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/read-package-json": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "dev": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "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.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true + }, + "node_modules/regexp-to-ast": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz", + "integrity": "sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "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": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/replace-in-file": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.3.5.tgz", + "integrity": "sha512-arB9d3ENdKva2fxRnSjwBEXfK1npgyci7ZZuwysgAp7ORjHSyxz6oqIjTEv8R0Ydl4Ll7uOAZXL4vbkhGIizCg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "glob": "^7.2.0", + "yargs": "^17.2.1" + }, + "bin": { + "replace-in-file": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/replace-in-file/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/replace-in-file/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/replace-in-file/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/replace-in-file/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/replace-in-file/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/replace-in-file/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/replace-in-file/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/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/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/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "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==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "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==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rollup": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.1.tgz", + "integrity": "sha512-I5gJCSpSMr3U9wv4D5YA8g7w7cj3eaSDeo7t+JcaFQOmoOUBgu4K9iMp8k3EZnwbJrjQxUMSKxMyB8qEQzzaSg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "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-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sass": { + "version": "1.63.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.2.tgz", + "integrity": "sha512-u56TU0AIFqMtauKl/OJ1AeFsXqRHkgO7nCWmHaDwfxDo9GUMSqBA4NEh6GMuh1CYVM7zuROYtZrHzPc2ixK+ww==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.1.tgz", + "integrity": "sha512-cBTxmgyVA1nXPvIK4brjJMXOMJ2v2YrQEuHqLw3LylGb3gsR6jAvdjHMcy/+JGTmmIF9SauTrLLR7bsWDMWqgg==", + "dev": true, + "dependencies": { + "klona": "^2.0.6", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/save-svg-as-png": { + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/save-svg-as-png/-/save-svg-as-png-1.4.17.tgz", + "integrity": "sha512-7QDaqJsVhdFPwviCxkgHiGm9omeaMBe1VKbHySWU6oFB2LtnGCcYS13eVoslUgq6VZC6Tjq/HddBd1K6p2PGpA==" + }, + "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, + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "dev": true, + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/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/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "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": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/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/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "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/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "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": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "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": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "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": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "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.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "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": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "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==", + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shiki": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", + "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sigstore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.7.0.tgz", + "integrity": "sha512-KP7QULhWdlu3hlp+jw2EvgWKlOGOY9McLj/jrchLjHNlNPK0KWIwF919cbmOp6QiKXLmPijR2qH/5KYWlbtG9Q==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.1", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/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/slice-ansi/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/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.1.tgz", + "integrity": "sha512-W+utHys2w//dhFjy7iQQu9sGd3eokCjGbl2r59tyLqNiJJBdIebn3GAKEXBr3osqHTObJi2die/25bCx2zsaaw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dev": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/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/spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "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.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "node_modules/spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "dependencies": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "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/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "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": "10.0.4", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", + "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", + "dev": true, + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/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/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, + "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/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/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/tar/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/tcomb": { + "version": "3.2.29", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", + "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", + "dev": true + }, + "node_modules/tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "dev": true, + "dependencies": { + "tcomb": "^3.0.0" + } + }, + "node_modules/terser": { + "version": "5.17.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", + "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/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/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/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==", + "dev": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==", + "deprecated": "no longer maintained" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "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/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "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": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==" + }, + "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/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-loader": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/ts-loader/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/ts-loader/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/ts-loader/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/ts-loader/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", + "integrity": "sha512-S87fS5QGinpnvi6I1aW8PnEEwJbkQsr2o+9C3qdAkmaYQn33PKVkXowI2/wggr8FzAwKhvCaomB0EX60LW3/Fw==", + "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "chalk": "^2.0.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.0", + "tsconfig": "^6.0.0", + "v8flags": "^3.0.0", + "yn": "^2.0.0" + }, + "bin": { + "_ts-node": "dist/_bin.js", + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/ts-node/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ts-node/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/tsconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", + "integrity": "sha512-n3i8c4BOozElBHYMVkEyF9AudHRvvq6NTc6sVRVmLBQM2A02JKjLoICxRtKkoGu3gROOnRZ85KxiTAcmhWgR0w==", + "dev": true, + "dependencies": { + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tuf-js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "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": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "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/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true + }, + "node_modules/typedoc": { + "version": "0.23.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", + "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.2.12", + "minimatch": "^7.1.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 14.14" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", + "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "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": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "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/vite": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "dev": true, + "dependencies": { + "esbuild": "^0.17.5", + "postcss": "^8.4.23", + "rollup": "^3.21.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/wait-on": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", + "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", + "dev": true, + "dependencies": { + "axios": "^0.25.0", + "joi": "^17.6.0", + "lodash": "^4.17.21", + "minimist": "^1.2.5", + "rxjs": "^7.5.4" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/wait-on/node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/watch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz", + "integrity": "sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==", + "dev": true, + "dependencies": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.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": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", + "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz", + "integrity": "sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", + "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/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/webpack/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/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/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==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "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/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.1.tgz", + "integrity": "sha512-+bIeDAFEBYuXRuU3qGQvzdPap+N1zjM4KkBAiiQuVVCrHrhjDuY6VkUhNa5+U27+9w0q3fbKiMCbpJ0XzMmSWA==", + "dependencies": { + "tslib": "^2.3.0" + } + } + }, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@angular-devkit/architect": { + "version": "0.1601.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1601.3.tgz", + "integrity": "sha512-HvW51cCEoIYe2mYqcmnm2RZiMMFbFn7iIdsjbCJe7etFhcG+Y3hGDZMh4IFSiQiss+pwPSYOvQY2zwGrndMgLw==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.1.3", + "rxjs": "7.8.1" + } + }, + "@angular-devkit/build-angular": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.1.3.tgz", + "integrity": "sha512-1scrdUdKRa9TkJ9jev/KRzFttbLUVACQvVRL0G67nUAdtJ/bQX8eui85axpCNPFihK4ReSW3R4lrgcVC2NUSoA==", + "dev": true, + "requires": { + "@ampproject/remapping": "2.2.1", + "@angular-devkit/architect": "0.1601.3", + "@angular-devkit/build-webpack": "0.1601.3", + "@angular-devkit/core": "16.1.3", + "@babel/core": "7.22.5", + "@babel/generator": "7.22.5", + "@babel/helper-annotate-as-pure": "7.22.5", + "@babel/helper-split-export-declaration": "7.22.5", + "@babel/plugin-proposal-async-generator-functions": "7.20.7", + "@babel/plugin-transform-async-to-generator": "7.22.5", + "@babel/plugin-transform-runtime": "7.22.5", + "@babel/preset-env": "7.22.5", + "@babel/runtime": "7.22.5", + "@babel/template": "7.22.5", + "@discoveryjs/json-ext": "0.5.7", + "@ngtools/webpack": "16.1.3", + "@vitejs/plugin-basic-ssl": "1.0.1", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.14", + "babel-loader": "9.1.2", + "babel-plugin-istanbul": "6.1.1", + "browserslist": "^4.21.5", + "cacache": "17.1.3", + "chokidar": "3.5.3", + "copy-webpack-plugin": "11.0.0", + "critters": "0.0.19", + "css-loader": "6.8.1", + "esbuild": "0.17.19", + "esbuild-wasm": "0.17.19", + "fast-glob": "3.2.12", + "https-proxy-agent": "5.0.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "karma-source-map-support": "1.4.0", + "less": "4.1.3", + "less-loader": "11.1.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.2.1", + "magic-string": "0.30.0", + "mini-css-extract-plugin": "2.7.6", + "mrmime": "1.0.1", + "open": "8.4.2", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "2.3.1", + "piscina": "3.2.0", + "postcss": "8.4.24", + "postcss-loader": "7.3.2", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.63.2", + "sass-loader": "13.3.1", + "semver": "7.5.3", + "source-map-loader": "4.0.1", + "source-map-support": "0.5.21", + "terser": "5.17.7", + "text-table": "0.2.0", + "tree-kill": "1.2.2", + "tslib": "2.5.3", + "vite": "4.3.9", + "webpack": "5.86.0", + "webpack-dev-middleware": "6.1.1", + "webpack-dev-server": "4.15.0", + "webpack-merge": "5.9.0", + "webpack-subresource-integrity": "5.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true + } + } + }, + "@angular-devkit/build-webpack": { + "version": "0.1601.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1601.3.tgz", + "integrity": "sha512-744+72vi/Vx010VxizGgilhpnDCOG29qyhMmu7BkUhtpq8E8eQn2HU3nPpxAqrg3bKVAwD7v3F111MVIhub8kA==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1601.3", + "rxjs": "7.8.1" + } + }, + "@angular-devkit/core": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.3.tgz", + "integrity": "sha512-cFhNdJHumNMZGD3NYxOtNuMGRQXeDnKbwvK+IJmKAttXt8na6EvURR/ZxZOI7rl/YRVX+vcNSdtXz3hE6g+Isw==", + "dev": true, + "requires": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "rxjs": "7.8.1", + "source-map": "0.7.4" + } + }, + "@angular-devkit/schematics": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.3.tgz", + "integrity": "sha512-hWEuQnfQOgcSs4YX6iF4QR/34ROeSPaMi7lQOYg33hStg+pnk/JDdIU0f2nrIIz3t0jqAj+5VXVLBJvOCd84vg==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.1.3", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.0", + "ora": "5.4.1", + "rxjs": "7.8.1" + } + }, + "@angular-eslint/builder": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.0.3.tgz", + "integrity": "sha512-pv/CrnOHHOnBqhyBmqUPsIHKXOHYMJztxYJ83tjxeXL5Moyu5e6CBMIQ58UtqmgWfEIA3n7owYy9KvHTJcemyQ==", + "dev": true, + "requires": { + "@nx/devkit": "16.2.2", + "nx": "16.2.2" + } + }, + "@angular-eslint/bundled-angular-compiler": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.0.3.tgz", + "integrity": "sha512-8zwY6ustiPXBEF3+jELKVwGk6j2HJn7GHbqAhDFR02YiE27iRMSGTHIAWGs6ZI7F1JgfrIsOHrUgzC1x95K6rg==", + "dev": true + }, + "@angular-eslint/eslint-plugin": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.0.3.tgz", + "integrity": "sha512-1c+dFytcQDOA2wJ8/rtydMV6UYq1BgVfOcBXOr0WJxC9g8Cad9czcUOkW41WGrTp5kICMliV0ypH5eEaCM2WDQ==", + "dev": true, + "requires": { + "@angular-eslint/utils": "16.0.3", + "@typescript-eslint/utils": "5.59.7" + } + }, + "@angular-eslint/eslint-plugin-template": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.0.3.tgz", + "integrity": "sha512-OKTMWOjC7F5tdv7gm2tlmgyr/uVyS1RWJZn4X/6D6p0kOpiDXmajtbYHD5tzbshX2Ep62Nt+rg8+1XGHrU0ScA==", + "dev": true, + "requires": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "@angular-eslint/utils": "16.0.3", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "aria-query": "5.1.3", + "axobject-query": "3.1.1" + } + }, + "@angular-eslint/schematics": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.0.3.tgz", + "integrity": "sha512-vRdSY0ovE+wfTvYeguPp/QAxvGejLADO8CzJkas0PxdCQiyLuTscKsYE82XcvX2kitMexvH71lNF0ggnGoMRXA==", + "dev": true, + "requires": { + "@angular-eslint/eslint-plugin": "16.0.3", + "@angular-eslint/eslint-plugin-template": "16.0.3", + "@nx/devkit": "16.2.2", + "ignore": "5.2.4", + "nx": "16.2.2", + "strip-json-comments": "3.1.1", + "tmp": "0.2.1" + } + }, + "@angular-eslint/template-parser": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.0.3.tgz", + "integrity": "sha512-IAWdwp/S9QC3EMiVxSS0E3ABy9PSidN3PW0Ll2EtM3mzXMYlpZXmxqd+B1xV/xKWzhk1Mp04QX8hHfG6Vq+qaQ==", + "dev": true, + "requires": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "eslint-scope": "^7.0.0" + } + }, + "@angular-eslint/utils": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.0.3.tgz", + "integrity": "sha512-QsbUVHJLk+fE08/D4y3wOyGk1iX2LVSygw+uzilbaAXfjD5/c0Ei5FbVx2mMYPk+aOl4yrvGQW3dmetMiAR0MQ==", + "dev": true, + "requires": { + "@angular-eslint/bundled-angular-compiler": "16.0.3", + "@typescript-eslint/utils": "5.59.7" + } + }, + "@angular/animations": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.1.3.tgz", + "integrity": "sha512-ET6ahrlbOyTYXOTouKs2VJxx0CMTrYkfz0HfI6IHnSKBC6wguDxXYnamMouHgrCkDDEB5qClfGHyS9se0AOX4w==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/cdk": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.9.tgz", + "integrity": "sha512-koaM07N1AIQ5oHU27l0/FoQSSoYAwlAYwVZ4Di3bYrJsTBNCN2Xsby7wI8gZxdepMnV4Fe9si382BDBov+oO4Q==", + "requires": { + "parse5": "^7.1.2", + "tslib": "^2.3.0" + } + }, + "@angular/cli": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.1.3.tgz", + "integrity": "sha512-D0gU12z/N2oJ+s6pggAnWYrTUZ+2duGb3Y5oUyClsubz7JWpAwHjSZpb8exPUrgYhr+qIEMGO685y1JazJQ2tA==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1601.3", + "@angular-devkit/core": "16.1.3", + "@angular-devkit/schematics": "16.1.3", + "@schematics/angular": "16.1.3", + "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "4.1.3", + "ini": "4.1.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "npm-package-arg": "10.1.0", + "npm-pick-manifest": "8.0.1", + "open": "8.4.2", + "ora": "5.4.1", + "pacote": "15.2.0", + "resolve": "1.22.2", + "semver": "7.5.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + } + }, + "@angular/common": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.1.3.tgz", + "integrity": "sha512-ZzJ6EwQHUkiZYV0zH/UxyUYW5uxomsyk7tdtqZIxAR5m2ktYkQ5XlqgPjBO8voF54Rs5Ot43RkPCLesbZyJDsw==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/compiler": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.1.3.tgz", + "integrity": "sha512-7Ckvssk9+s5xLyXvp72IwAw5vd/Osa3tR6oiQatdbw+O3XjLO04QycoGXwkp/fYVexGsjFyOn6QJ5n1F/PYPbQ==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/compiler-cli": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.1.3.tgz", + "integrity": "sha512-aUqnIV9rRTBNgiQRS0Gv6lhghaGj1vpVRyXgiE4VnTR9uBONSsGKMNALYBBhXRTSk2e0cvutt0ubLgmNpdyWyQ==", + "dev": true, + "requires": { + "@babel/core": "7.22.5", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.1.2", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + } + }, + "@angular/core": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.1.3.tgz", + "integrity": "sha512-yhRo9hVS8KhfcEgzciWuRWF4Pnnko98bmSJTqd7u8Kys6z3Uj0qgXMssXHIPUALe3mQKjVkdSZPLIZ9/CaVn/Q==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/forms": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.1.3.tgz", + "integrity": "sha512-9tJHgoi/Jmeo30zfnReVZWFcd1WthR+QwYUNwPev+ys58u1mB0cDGORvROySmC2YUyXFSpXt8sxwyWCkYvaV2w==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/platform-browser": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.1.3.tgz", + "integrity": "sha512-qZA6Lua2fpBe+KD/QArY/4hilypSZFcTcJsPjZwIzo5pavXqYDI8BVghwh5dcZoUa56hVRDJjv+XW6kl8m9Tdw==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/platform-browser-dynamic": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.1.3.tgz", + "integrity": "sha512-UHxSWpPB5+FSv8zm8T+4ZikLqyy+VE6GlOLp/DdgEz77j81rz2C1pMqozwTnVbD16XbI4rhTp+RFY3C9ArWOtw==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@angular/router": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.1.3.tgz", + "integrity": "sha512-bkn8cWGBKKZidDaP+R7g/S/6miSfH8iP24d2k86Awo+vaO+7G/5WWGfKJMKK8UNM/A5ueX6ugAZrMHpQ9e6Y4w==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@assemblyscript/loader": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", + "dev": true + }, + "@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.5" + } + }, + "@babel/compat-data": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", + "dev": true + }, + "@babel/core": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", + "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", + "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", + "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz", + "integrity": "sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@nicolo-ribaudo/semver-v6": "^6.3.3" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz", + "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "regexpu-core": "^5.3.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz", + "integrity": "sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dev": true, + "requires": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", + "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", + "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-replace-supers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", + "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", + "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", + "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "dev": true, + "requires": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + } + }, + "@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", + "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", + "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", + "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", + "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", + "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", + "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", + "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", + "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", + "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", + "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", + "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", + "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", + "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", + "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", + "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", + "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", + "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", + "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.5" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", + "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", + "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", + "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", + "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", + "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.1" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.5.tgz", + "integrity": "sha512-bg4Wxd1FWeFx3daHFTWk1pkSWK/AyQuiyAoeZAOkAOUBjnZPH6KT7eMxouV47tQ6hl6ax2zyAWBdWZXbrvXlaw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", + "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/preset-env": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", + "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.5", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-classes": "^7.22.5", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", + "@babel/plugin-transform-numeric-separator": "^7.22.5", + "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5", + "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.3", + "babel-plugin-polyfill-corejs3": "^0.8.1", + "babel-plugin-polyfill-regenerator": "^0.5.0", + "core-js-compat": "^3.30.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "requires": { + "@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" + } + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "@babel/runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, + "@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/traverse": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", + "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + } + } + }, + "@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + } + }, + "@cds/city": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@cds/city/-/city-1.1.0.tgz", + "integrity": "sha512-S9K+Q39BGOghyLHmR0Wdcmu1i1noSUk8HcvMj+3IaohZw02WFd99aPTQDHJeseXrXZP3CNovaSlePI0R11NcFg==", + "optional": true + }, + "@cds/core": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@cds/core/-/core-6.4.4.tgz", + "integrity": "sha512-DX02/KyCkECMvxuBeqrk/CmQGTynonQa9GDN8bK/Qje43esU4iYvoTfiuBSBGaNIQYv/0dFCY85QHcL68CCATg==", + "requires": { + "@cds/city": "^1.1.0", + "lit": "^2.1.3", + "modern-normalize": "1.1.0", + "ramda": "^0.29.0", + "tslib": "^2.3.1" + } + }, + "@clr/angular": { + "version": "13.18.2", + "resolved": "https://registry.npmjs.org/@clr/angular/-/angular-13.18.2.tgz", + "integrity": "sha512-LEvua9GItCheHNESey5yJb2oBBI0lvtgUJCgOJLqVsMM9BDtkE/l5R4rBcIFjwnHg+tnuM0xhnUqKaCJSDr0OA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@clr/icons": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@clr/icons/-/icons-13.0.2.tgz", + "integrity": "sha512-bdcSuFvQAbIIp8Q2Fm55BjHW5cawP4xEOkZf2IEIin0d9ViRcAJNjACBCOMDhx2up7nPZsXwN2gL8zJhL7TSZQ==" + }, + "@clr/ui": { + "version": "13.18.2", + "resolved": "https://registry.npmjs.org/@clr/ui/-/ui-13.18.2.tgz", + "integrity": "sha512-ippjTqG0FHMW3/3UPO3iskWh+g7mH4twSpgkAqL4oPTRlyCVFPtilW69FqTGAioVmO2gLxCyxIxZBDNcYoJwog==" + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true + }, + "@cypress/request": { + "version": "2.88.11", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", + "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", + "dev": true, + "requires": { + "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", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.10.3", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "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, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "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, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "@cypress/webpack-preprocessor": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.17.1.tgz", + "integrity": "sha512-FE/e8ikPc8z4EVopJCaior3RGy0jd2q9Xcp5NtiwNG4XnLfEnUFTZlAGwXe75sEh4fNMPrBJW1KIz77PX5vGAw==", + "dev": true, + "requires": { + "bluebird": "3.7.1", + "debug": "^4.3.4", + "lodash": "^4.17.20" + } + }, + "@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "dev": true, + "optional": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "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 + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "dev": true + }, + "@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" + } + } + }, + "@handsontable/angular": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@handsontable/angular/-/angular-13.0.0.tgz", + "integrity": "sha512-wbka5xCFdD9gdtceu7UuVac+0I4zg5RDlK/u6vv9ACmrgPbYTkR5W/KqhG2FLmpUfICGEqV1cyzmQRavdQH1UQ==", + "requires": { + "tslib": "^2.2.0" + } + }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@hpcc-js/wasm": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.5.0.tgz", + "integrity": "sha512-G26BamgaHW46f6P8bmkygapgNcy+tTDMwIvCzmMzdp39sxUS1u4gaT/vR2SSDc4x3SfL5RE4B2B8ef/wd429Hg==", + "requires": { + "yargs": "17.6.2" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + } + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "@lit-labs/ssr-dom-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz", + "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==" + }, + "@lit/reactive-element": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz", + "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==", + "requires": { + "@lit-labs/ssr-dom-shim": "^1.0.0" + } + }, + "@ngtools/webpack": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.1.3.tgz", + "integrity": "sha512-YTL1RzP7ErJqskx+ZwdC/nWsOSBfC4yYWmMyWL2J0d+oJ3N2XIzrKVoDcZ4IVzv3Du+3zoGp0ups/wWXvfzM/Q==", + "dev": true + }, + "@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + }, + "which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "@npmcli/installed-package-contents": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "dev": true, + "requires": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + } + }, + "@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true + }, + "@npmcli/promise-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "dev": true, + "requires": { + "which": "^3.0.0" + }, + "dependencies": { + "which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "@npmcli/run-script": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", + "dev": true, + "requires": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "dependencies": { + "which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "@nrwl/devkit": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.2.2.tgz", + "integrity": "sha512-R8OSh33HtGycSuu0KshpH/tsTdi6j4w7DuIb+Sa59UDIkchpvMeNAz8tj/05Z2tTntDZnYqPkmCs6rkZ4PvY4Q==", + "dev": true, + "requires": { + "@nx/devkit": "16.2.2" + } + }, + "@nrwl/tao": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-16.2.2.tgz", + "integrity": "sha512-cPj6b+wSWs2WNFQ0p1fMyrvSLjkKJo7vXQTtd7MXNJT2NWEZdCtRy+nidZzjs7gKvVXGdZ8zDBXmCHWorOieXw==", + "dev": true, + "requires": { + "nx": "16.2.2" + } + }, + "@nx/devkit": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-16.2.2.tgz", + "integrity": "sha512-MTYzetk4AQ9u2syEb9z+drDsu6U6NRAXVuUDMNg0tpZcbtE9bCSLH2ngfvTCqmLrAMBsJZRdv0twS1iepMhlAg==", + "dev": true, + "requires": { + "@nrwl/devkit": "16.2.2", + "ejs": "^3.1.7", + "ignore": "^5.0.4", + "semver": "7.3.4", + "tmp": "~0.2.1", + "tslib": "^2.3.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@nx/nx-darwin-arm64": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.2.2.tgz", + "integrity": "sha512-CKfyLl92mhWqpv1hRTj3WgjVBY6yj3Et5T31m1N0assNWdTfuSB4ycdWzdlxXHx3yptnTOD/FCymTpUQI0GZRQ==", + "dev": true, + "optional": true + }, + "@nx/nx-darwin-x64": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.2.2.tgz", + "integrity": "sha512-++uDfp/Oo8DDVU53DiJVkRNjNbOLzahDH6dINeA/3yTCU/IS0wXoaoclNZBReMWlDKTVvWgLF/eSbGINMqUHRg==", + "dev": true, + "optional": true + }, + "@nx/nx-linux-arm-gnueabihf": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.2.2.tgz", + "integrity": "sha512-A4XFk63Q7fxgZaHnigIeofp/xOT2ZGDoNUyzld+UTlyJyNcClcOcqrro74aKOCG7PH0D56oE06JW3g7GKszgsA==", + "dev": true, + "optional": true + }, + "@nx/nx-linux-arm64-gnu": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.2.2.tgz", + "integrity": "sha512-aQpTLVSawFVr33pBWjj8elqvjA5uWvzDW7hGaFQPgWgmjxrtJikIAkcLjfNOz8XYjRAP4OZkTVh4/E3GUch0kQ==", + "dev": true, + "optional": true + }, + "@nx/nx-linux-arm64-musl": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.2.2.tgz", + "integrity": "sha512-20vyNYQ2SYSaWdxORj9HdOyGxiqE8SauaFiBjjid6/e5mSyaSKu+HHGsvhDUqzlWn3OaABKBqx0iYa9Kmf3BOQ==", + "dev": true, + "optional": true + }, + "@nx/nx-linux-x64-gnu": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.2.2.tgz", + "integrity": "sha512-0G8kYpEmGHD+tT7RvUEvVXvPbvQD9GfEjeWEzZAdNAAMJu7JFjIo/oZDJYV7cMvXnC+tbpI9Gba5xfv8Al95eA==", + "dev": true, + "optional": true + }, + "@nx/nx-linux-x64-musl": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.2.2.tgz", + "integrity": "sha512-Incv7DbKLfh6kakzMBuy6GYRgI+jEdZBRiFw0GoN9EsknmrPT/URn+w6uuicGGEXOLYpO3HUO3E374+b5Wz2zg==", + "dev": true, + "optional": true + }, + "@nx/nx-win32-arm64-msvc": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.2.2.tgz", + "integrity": "sha512-8m+Usj9faCl0pdQLFeBGhbYUObT3/tno5oGMPtJLyRjITNvTZAaIS4FFctp/rwJPehDBRQsUxwMJ2JRaU4jQdA==", + "dev": true, + "optional": true + }, + "@nx/nx-win32-x64-msvc": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.2.2.tgz", + "integrity": "sha512-liHtyVVOttcqHIV3Xrg/1AJzEgfiOCeqJsleHXHGgPr1fxPx7SIZaa3/QnDY1lNMN+t6Gvj0/r2Ba3iuptYD3Q==", + "dev": true, + "optional": true + }, + "@parcel/watcher": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", + "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", + "dev": true, + "requires": { + "node-addon-api": "^3.2.1", + "node-gyp-build": "^4.3.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@sasjs/adapter": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.6.tgz", + "integrity": "sha512-l6BJNqWa4k0OpLgghED/BqTzUgWCgv7BGJpKheMTdHys3f5KgyKtEqXwwloXSvCTPVn441zsRT2Z0WsS7DNWrw==", + "requires": { + "@sasjs/utils": "2.52.0", + "axios": "0.27.2", + "axios-cookiejar-support": "1.0.1", + "form-data": "4.0.0", + "https": "1.0.0", + "tough-cookie": "4.0.0" + }, + "dependencies": { + "@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "requires": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "@sasjs/utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-3.3.0.tgz", + "integrity": "sha512-ZJ+c2d/rEoF340Ay3TZrXO4c2ain7AvSzkRuKG2H2qxwIlQQTk/9Rbknmy0mo3Y/QRScBYl0Fw5xSZ8SMHjljg==", + "requires": { + "@fast-csv/format": "4.3.5", + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "@schematics/angular": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.1.3.tgz", + "integrity": "sha512-bNSxCLf6f+/dsQ1k3PhcZhrC/qgJSCpM6h3m6ATpjR+tYW/v7WR1OyE5r3DQmDe7NJSazBvpbrRtg8xjRsMzvw==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.1.3", + "@angular-devkit/schematics": "16.1.3", + "jsonc-parser": "3.2.0" + } + }, + "@sheet/crypto": { + "version": "1.20211122.1", + "resolved": "https://pylon.sheetjs.com:54111/@sheet%2fcrypto/-/crypto-1.20211122.1.tgz", + "integrity": "sha512-G3/HWyzFUYbbVQoQIa+KSeMOhFnK492Ep595FXbzWN9IGZSwuvFl4saEyMl8R8pE2Al5YgSZuR9MpDpx3f7Izg==" + }, + "@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "@sigstore/protobuf-specs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz", + "integrity": "sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ==", + "dev": true + }, + "@sigstore/tuf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.2.tgz", + "integrity": "sha512-vjwcYePJzM01Ha6oWWZ9gNcdIgnzyFxfqfWzph483DPJTH8Tb7f7bQRRll3CYVkyH56j0AgcPAcl6Vg95DPF+Q==", + "dev": true, + "requires": { + "@sigstore/protobuf-specs": "^0.1.0", + "tuf-js": "^1.1.7" + } + }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, + "@tufjs/canonical-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", + "dev": true + }, + "@tufjs/models": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", + "dev": true, + "requires": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "@types/core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha512-C4vwOHrhsvxn7UFyk4NDQNUpgNKdWsT/bL39UWyD75KSEOObZSKa9mYDOCM5FGeJG2qtbG0XiEbUKND2+j0WOg==", + "dev": true + }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==", + "dev": true + }, + "@types/d3-color": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz", + "integrity": "sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA==" + }, + "@types/d3-graphviz": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/d3-graphviz/-/d3-graphviz-2.6.7.tgz", + "integrity": "sha512-dKJjD5HiFvAmC0FL/c70VB1diie8FCpyiCZfxMlf6TwYBqUyFvS4XJt6MoxjIuQTJhKDBGzrIvDOgM8gYMLSVA==", + "requires": { + "@types/d3-selection": "^1", + "@types/d3-transition": "^1", + "@types/d3-zoom": "^1" + } + }, + "@types/d3-interpolate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz", + "integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==", + "requires": { + "@types/d3-color": "^1" + } + }, + "@types/d3-selection": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.3.tgz", + "integrity": "sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==" + }, + "@types/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg==", + "requires": { + "@types/d3-selection": "^1" + } + }, + "@types/d3-zoom": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.4.tgz", + "integrity": "sha512-K+6jCM9llyC5U4WvkmiXbCoOIuUX03Wi72C/L9PMPVxymWDaxTHzDgHD/HYlEyDRGiVp7D77m7XPcD/m/TRDrw==", + "requires": { + "@types/d3-interpolate": "^1", + "@types/d3-selection": "^1" + } + }, + "@types/es6-shim": { + "version": "0.31.42", + "resolved": "https://registry.npmjs.org/@types/es6-shim/-/es6-shim-0.31.42.tgz", + "integrity": "sha512-GS3EuEgiGv/TP7bwPLOlkSiTfdSL4XHOj0jJuvz4/UbR89QrC4Py3lYlMlH/7w0dKfJ8fIori0rVIl2gQ7lb5A==", + "dev": true + }, + "@types/eslint": { + "version": "8.40.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", + "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "requires": { + "@types/node": "*" + } + }, + "@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/jasmine": { + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz", + "integrity": "sha512-S6pvzQDvMZHrkBz2Mcn/8Du7cpr76PlRJBAoHnSDNbulULsH5dp0Gns+WRyNX5LHejz/ljxK4/vIHK/caHt6SQ==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "@types/lodash-es": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz", + "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/marked": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.1.tgz", + "integrity": "sha512-vSSbKZFbNktrQ15v7o1EaH78EbWV+sPQbPjHG+Cp8CaNcPFUEfjZ0Iml/V0bFDwsTlYe8o6XC5Hfdp91cqPV2g==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/node": { + "version": "12.20.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.50.tgz", + "integrity": "sha512-+9axpWx2b2JCVovr7Ilgt96uc6C1zBKOQMpGtRbWT9IoR/8ue32GGMfGA4woP8QyP2gBs6GQWEVM3tCybGCxDA==" + }, + "@types/pikaday": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@types/pikaday/-/pikaday-1.7.4.tgz", + "integrity": "sha512-0KsHVyw5pTG829nqG4IRu7m+BFQlFEBdbE/1i3S5182HeKUKv1uEW0gyEmkJVp5i4IV+9pyh23O83+KpRkSQbw==", + "requires": { + "moment": ">=2.14.0" + } + }, + "@types/prompts": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.13.tgz", + "integrity": "sha512-jwMOIGy49VruR/gYehhJYgpVzB+EVpEE7t7j9m1oTo4HMpOe7KmsyqdBuoxAzA5B4caUgx0cKrWr7wUEqMXJ7Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true + }, + "@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/text-encoding": { + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/@types/text-encoding/-/text-encoding-0.0.35.tgz", + "integrity": "sha512-jfo/A88XIiAweUa8np+1mPbm3h2w0s425YrI8t3wk5QxhH6UI7w517MboNVnGDeMSuoFwA8Rwmklno+FicvV4g==" + }, + "@types/trusted-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" + }, + "@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", + "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/type-utils": "5.61.0", + "@typescript-eslint/utils": "5.61.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/type-utils": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", + "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/utils": "5.61.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", + "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", + "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", + "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + } + } + }, + "@typescript-eslint/types": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", + "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + } + }, + "@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@vitejs/plugin-basic-ssl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", + "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@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 + }, + "@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 + }, + "@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 + }, + "@yarnpkg/parsers": { + "version": "3.0.0-rc.48.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.48.1.tgz", + "integrity": "sha512-qEewJouhRvaecGjbkjz9kMKn96UASbDodNrE5MYy2TrXkHcisIkbMxZdGBYfAq+s1dFtCSx/5H4k5bEkfakM+A==", + "dev": true, + "requires": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + } + }, + "@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + } + } + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "ally.js": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/ally.js/-/ally.js-1.4.1.tgz", + "integrity": "sha512-ZewdfuwP6VewtMN36QY0gmiyvBfMnmEaNwbVu2nTS6zRt069viTgkYgaDiqu6vRJ1VJCriNqV0jGMu44R8zNbA==", + "dev": true, + "requires": { + "css.escape": "^1.5.0", + "platform": "1.3.3" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "dev": true + }, + "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, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true + }, + "are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "requires": { + "deep-equal": "^2.0.5" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true + }, + "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 + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "requires": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true + }, + "aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "requires": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + } + }, + "axobject-query": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "dev": true, + "requires": { + "deep-equal": "^2.0.5" + } + }, + "babel-loader": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", + "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.2", + "schema-utils": "^4.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", + "integrity": "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.1", + "@nicolo-ribaudo/semver-v6": "^6.3.3" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz", + "integrity": "sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.1", + "core-js-compat": "^3.31.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz", + "integrity": "sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "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 + }, + "bignumber.js": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz", + "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "bluebird": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "dev": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dev": true, + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "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" + } + }, + "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==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "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==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" + }, + "builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "dev": true, + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + } + } + }, + "cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "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, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true + }, + "chevrotain": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz", + "integrity": "sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg==", + "requires": { + "regexp-to-ast": "0.4.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "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==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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 + }, + "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, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true + }, + "cli-table": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", + "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "requires": { + "colors": "1.0.3" + } + }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, + "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, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "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, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "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 + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "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 + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true + }, + "consola": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.0.tgz", + "integrity": "sha512-vlcSGgdYS26mPf7qNi+dCisbhiyDnrN1zaRbw3CSuc2wGOMEGGPsp46PdRG5gqXwgtJfjxDkxRNAgRPr1B77vQ==" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "requires": { + "is-what": "^3.14.1" + } + }, + "copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dev": true, + "requires": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globby": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.1.tgz", + "integrity": "sha512-DPCBxctI7dN4EeIqjW2KGqgdcUMbrhJ9AzON+PlxCtvppWhubTLD4+a0GFxiym14ZvacUydTPjLPc2DlKz7EIg==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } + } + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "dev": true + }, + "core-js-compat": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.0.tgz", + "integrity": "sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==", + "dev": true, + "requires": { + "browserslist": "^4.21.5" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "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==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "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==", + "requires": { + "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" + } + }, + "critters": { + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.19.tgz", + "integrity": "sha512-Fm4ZAXsG0VzWy1U30rP4qxbaWGSsqXDgSupJW1OUJGDAs0KWC+j37v7p5a2kZ9BPJvhRzWm3be+Hc9WvQOBUOw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "css-select": "^5.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.2", + "htmlparser2": "^8.0.2", + "postcss": "^8.4.23", + "pretty-bytes": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "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==", + "requires": { + "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" + } + }, + "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==" + }, + "css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + } + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "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 + }, + "csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, + "cypress": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", + "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", + "dev": true, + "requires": { + "@cypress/request": "^2.88.10", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.6", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.3.2", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "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 + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "cypress-file-upload": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz", + "integrity": "sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==", + "dev": true + }, + "cypress-plugin-tab": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cypress-plugin-tab/-/cypress-plugin-tab-1.0.5.tgz", + "integrity": "sha512-QtTJcifOVwwbeMP3hsOzQOKf3EqKsLyjtg9ZAGlYDntrCRXrsQhe4ZQGIthRMRLKpnP6/tTk6G0gJ2sZUfRliQ==", + "dev": true, + "requires": { + "ally.js": "^1.4.1" + } + }, + "cypress-real-events": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/cypress-real-events/-/cypress-real-events-1.8.1.tgz", + "integrity": "sha512-8fFnA8EzS3EVbAmpSEUf3A8yZCmfU3IPOSGUDVFCdE1ke1gYL1A+gvXXV6HKUbTPRuvKKt2vpaMbUwYLpDRswQ==", + "dev": true + }, + "d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + }, + "d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" + }, + "d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + } + }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, + "d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" + }, + "d3-graphviz": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.0.2.tgz", + "integrity": "sha512-EVRow9rnFgm/L1trbbnu2PGOND11IcSEdWXbrDbz9hH0/Kj3YM2AqMkkTN/EAWgawD5/zryyCy+3Vm05oSJ1Kg==", + "requires": { + "@hpcc-js/wasm": "2.5.0", + "d3-dispatch": "^3.0.1", + "d3-format": "^3.1.0", + "d3-interpolate": "^3.0.1", + "d3-path": "^3.1.0", + "d3-timer": "^3.0.1", + "d3-transition": "^3.0.1", + "d3-zoom": "^3.0.0" + } + }, + "d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "requires": { + "d3-color": "1 - 3" + } + }, + "d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" + }, + "d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" + }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, + "d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "requires": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true + }, + "dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true + }, + "dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "dev": true + }, + "deep-equal": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", + "integrity": "sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.0", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + }, + "dependencies": { + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + } + } + }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, + "define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "dompurify": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.5.tgz", + "integrity": "sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA==" + }, + "domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "requires": { + "jake": "^10.8.5" + } + }, + "electron-to-chromium": { + "version": "1.4.450", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", + "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "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==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "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, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.1.tgz", + "integrity": "sha512-mGqhI+D7YxS9KJMppR6Iuo37Ed3abhU8NdfgSvJSDUafQutrN+sPTncJYTyM9+tkhSmWodKtVYGPPHyXJEwEQA==", + "dev": true, + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.1.0", + "ws": "~8.11.0" + } + }, + "engine.io-parser": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.1.0.tgz", + "integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "dev": true + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "devOptional": true + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, + "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, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + } + }, + "es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "dev": true + }, + "es6-shim": { + "version": "0.35.8", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.8.tgz", + "integrity": "sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg==", + "dev": true + }, + "esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, + "esbuild-wasm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.19.tgz", + "integrity": "sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "eslint": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "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 + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "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 + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true + }, + "espree": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "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 + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eventemitter-asyncresource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", + "dev": true + }, + "eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "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==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "dev": true, + "requires": { + "merge": "^1.2.0" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + } + } + }, + "exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "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, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "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 + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "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, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "find": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "requires": { + "traverse-chain": "~0.1.0" + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "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, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", + "integrity": "sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==", + "dev": true, + "requires": { + "minipass": "^5.0.0" + } + }, + "fs-monkey": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fsu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", + "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "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==" + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "requires": { + "async": "^3.2.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-describe": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-describe/-/git-describe-4.1.1.tgz", + "integrity": "sha512-JC8ganO5kO80G8+XE98TDDjnMXQN3Estk3qdJuG2EGRF/l6zuMTMcN+8OSfQZ5FWpqIRLB015anWX4aSRgnxAQ==", + "dev": true, + "requires": { + "@types/semver": "^7.3.8", + "lodash": "^4.17.21", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.1.tgz", + "integrity": "sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.10.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "requires": { + "ini": "2.0.0" + }, + "dependencies": { + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + } + } + }, + "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 + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "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 + }, + "handsontable": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-13.0.0.tgz", + "integrity": "sha512-qjfUQCJCeD5OJbUnXpEaruJJ8MfI2/yZI6q0wAGd+85tCAcpknJODR9FqRHpcTrKf+Mc9HO/CJ6qBAJHiXSrhA==", + "requires": { + "@types/pikaday": "1.7.4", + "core-js": "^3.0.0", + "dompurify": "^2.1.1", + "hyperformula": "^2.4.0", + "moment": "2.29.4", + "numbro": "2.1.2", + "pikaday": "1.8.2" + }, + "dependencies": { + "core-js": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz", + "integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==" + }, + "numbro": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/numbro/-/numbro-2.1.2.tgz", + "integrity": "sha512-7w833BxZmKGLE9HI0aREtNVRVH6WTYUUlWf4qgA5gKNhPQ4F/MRZ14sc0v8eoLORprk9ZTVwYaLwj8N3Zgxwiw==", + "requires": { + "bignumber.js": "^8.0.1" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "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==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hdr-histogram-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", + "dev": true, + "requires": { + "@assemblyscript/loader": "^0.10.1", + "base64-js": "^1.2.0", + "pako": "^1.0.3" + } + }, + "hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "requires": { + "lru-cache": "^7.5.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + } + } + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true + }, + "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 + }, + "htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + } + }, + "https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "hyperformula": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hyperformula/-/hyperformula-2.5.0.tgz", + "integrity": "sha512-HkP7JZAmG7EQFF5XAhB3aGtTHvafblSRITTMYUsVoT9czIvYY7CvMQFfK1JNHJUVS844t8bnJpKEOqwcgBcHZg==", + "requires": { + "chevrotain": "^6.5.0", + "tiny-emitter": "^2.1.0", + "unorm": "^1.6.0" + } + }, + "iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "ignore-walk": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz", + "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==", + "dev": true, + "requires": { + "minimatch": "^9.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true + }, + "immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "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 + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true + }, + "inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "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, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "requires": { + "ci-info": "^3.2.0" + } + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "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==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "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 + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true + }, + "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 + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "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, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true + }, + "is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "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, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "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 + } + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jackspeak": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", + "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jasmine-core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz", + "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==", + "dev": true + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "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 + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jiti": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", + "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", + "dev": true + }, + "joi": { + "version": "17.9.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz", + "integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.3", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "jquery": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" + }, + "jquery-datetimepicker": { + "version": "2.5.21", + "resolved": "https://registry.npmjs.org/jquery-datetimepicker/-/jquery-datetimepicker-2.5.21.tgz", + "integrity": "sha512-wDTpZ4f1PWd1XGaIIE0n6jLynlm+akBJ7/NjaB1bk2UJSS593CHJPZ3+FNEXoyvNVUeBlBC0oX6WTfCyfUhX/w==", + "requires": { + "jquery": ">= 1.7.2", + "jquery-mousewheel": ">= 3.1.13", + "php-date-formatter": "^1.3.4" + } + }, + "jquery-mousewheel": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", + "integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg==" + }, + "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 + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true + }, + "jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "jsrsasign": { + "version": "10.8.6", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.8.6.tgz", + "integrity": "sha512-bQmbVtsfbgaKBTWCKiDCPlUPbdlRIK/FzSwT3BzIgZl/cU6TqXu6pZJsCI/dJVrZ9Gir5GC4woqw9shH/v7MBw==" + }, + "jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, + "karma": { + "version": "6.3.20", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.20.tgz", + "integrity": "sha512-HRNQhMuKOwKpjYlWiJP0DUrJOh+QjaI/DTaD8b9rEm4Il3tJ8MijutVZH4ts10LuUFst/CedwTS6vieCN8yTSw==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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 + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "karma-chrome-launcher": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", + "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "dev": true, + "requires": { + "which": "^1.2.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "karma-coverage": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.1.1.tgz", + "integrity": "sha512-oxeOSBVK/jdZsiX03LhHQkO4eISSQb5GbHi6Nsw3Mw7G4u6yUgacBAftnO7q+emPBLMsrNbz1pGIrj+Jb3z17A==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "dependencies": { + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "karma-jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.2.tgz", + "integrity": "sha512-ggi84RMNQffSDmWSyyt4zxzh2CQGwsxvYYsprgyR1j8ikzIduEdOlcLvXjZGwXG/0j41KUXOWsUCBfbEHPWP9g==", + "dev": true, + "requires": { + "jasmine-core": "^3.6.0" + } + }, + "karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==", + "dev": true + }, + "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, + "requires": { + "source-map-support": "^0.5.5" + } + }, + "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 + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true + }, + "launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true + }, + "less": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", + "dev": true, + "requires": { + "copy-anything": "^2.0.1", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "parse-node-version": "^1.0.1", + "source-map": "~0.6.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "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, + "optional": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + }, + "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 + } + } + }, + "less-loader": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", + "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", + "dev": true, + "requires": { + "klona": "^2.0.4" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "requires": { + "webpack-sources": "^3.0.0" + } + }, + "lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true + }, + "listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "lit": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz", + "integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==", + "requires": { + "@lit/reactive-element": "^1.6.0", + "lit-element": "^3.3.0", + "lit-html": "^2.7.0" + } + }, + "lit-element": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz", + "integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==", + "requires": { + "@lit-labs/ssr-dom-shim": "^1.1.0", + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.7.0" + } + }, + "lit-html": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz", + "integrity": "sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==", + "requires": { + "@types/trusted-types": "^2.0.2" + } + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, + "loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "dev": true + }, + "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, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "requires": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + } + }, + "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, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "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, + "requires": { + "yallist": "^3.0.2" + } + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "magic-string": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + }, + "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, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "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 + }, + "make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + } + } + }, + "marked": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.0.tgz", + "integrity": "sha512-z3/nBe7aTI8JDszlYLk7dDVNpngjw0o1ZJtrA9kIfkkHcIF+xH7mO23aISl4WxP83elU+MFROgahqdpd05lMEQ==" + }, + "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==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "requires": { + "fs-monkey": "^1.0.4" + } + }, + "merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "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 + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "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 + }, + "mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "requires": { + "schema-utils": "^4.0.0" + } + }, + "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==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true + }, + "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, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-fetch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^5.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "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, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mochawesome": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz", + "integrity": "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "diff": "^5.0.0", + "json-stringify-safe": "^5.0.1", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isobject": "^3.0.2", + "lodash.isstring": "^4.0.1", + "mochawesome-report-generator": "^6.2.0", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "mochawesome-report-generator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz", + "integrity": "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "dateformat": "^4.5.1", + "escape-html": "^1.0.3", + "fs-extra": "^10.0.0", + "fsu": "^1.1.1", + "lodash.isfunction": "^3.0.9", + "opener": "^1.5.2", + "prop-types": "^15.7.2", + "tcomb": "^3.2.17", + "tcomb-validation": "^3.3.0", + "validator": "^13.6.0", + "yargs": "^17.2.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "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 + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==", + "optional": true + }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, + "mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true + }, + "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 + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "mutationobserver-shim": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/mutationobserver-shim/-/mutationobserver-shim-0.3.7.tgz", + "integrity": "sha512-oRIDTyZQU96nAiz2AQyngwx1e89iApl2hN5AOYwyxLUB47UYsU3Wv9lJWqH5y/QdiYkc5HQLi23ZNB3fELdHcQ==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "needle": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "ngx-clipboard": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-16.0.0.tgz", + "integrity": "sha512-rZ/Eo1PqiKMiyF8tdjhmUkoUu68f7OzBJ7YH1YFeh2RAaNrerTaW8XfFOzppSckjFQqA1fwGSYuTTJlDhDag5w==", + "requires": { + "ngx-window-token": ">=7.0.0", + "tslib": "^2.0.0" + } + }, + "ngx-json-viewer": { + "version": "file:libraries/ngx-json-viewer-3.2.1.tgz", + "integrity": "sha512-Qa24rEXam1gNr3pAg31Xb/ycs+yFcF0Y+woCcPET3XKaxQthpZ9T5VM7tPRRDWUFEWsTZuOQARsAdN9DAIPp8A==", + "requires": { + "tslib": "^2.3.0" + } + }, + "ngx-window-token": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ngx-window-token/-/ngx-window-token-7.0.0.tgz", + "integrity": "sha512-5+XfRVSY7Dciu8xyCNMkOlH2UfwR9W2P1Pirz7caaZgOZDjFbL8aEO2stjfJJm2FFf1D6dlVHNzhLWGk9HGkqA==", + "requires": { + "tslib": "^2.0.0" + } + }, + "nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "dev": true, + "optional": true, + "requires": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true + }, + "node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "requires": { + "abbrev": "^1.0.0" + } + } + } + }, + "node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "dev": true + }, + "node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "dev": true + }, + "nodejs": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/nodejs/-/nodejs-0.0.0.tgz", + "integrity": "sha512-1V+0HwaB/dhxzidEFc4uJ3k52gLI4B6YBZgJIofjwYCSAkD6CI0me6TDBT2QM2nbGWNxCHcq9/wVynzQYZOhUg==" + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "requires": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "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 + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true + }, + "npm-bundled": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^3.0.0" + } + }, + "npm-install-checks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz", + "integrity": "sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==", + "dev": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true + }, + "npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "requires": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + } + }, + "npm-packlist": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "requires": { + "ignore-walk": "^6.0.0" + } + }, + "npm-pick-manifest": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", + "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", + "dev": true, + "requires": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + } + }, + "npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "requires": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "numbro": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/numbro/-/numbro-2.3.6.tgz", + "integrity": "sha512-pxpoTT3hVxQGaOA2RTzXR/muonQNd1K1HPJbWo7QOmxPwiPmoFCFfsG9XXgW3uqjyzezJ0P9IvCPDXUtJexjwg==", + "requires": { + "bignumber.js": "^8.1.1" + } + }, + "nx": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-16.2.2.tgz", + "integrity": "sha512-gOcpqs6wf8YdFIq6P0IlMxBGr2c27pM55zpqO7epSlN6NqW6SOFKnZa+6z4NV9qmifMqzWPx2VF0BY54ARuqYg==", + "dev": true, + "requires": { + "@nrwl/tao": "16.2.2", + "@nx/nx-darwin-arm64": "16.2.2", + "@nx/nx-darwin-x64": "16.2.2", + "@nx/nx-linux-arm-gnueabihf": "16.2.2", + "@nx/nx-linux-arm64-gnu": "16.2.2", + "@nx/nx-linux-arm64-musl": "16.2.2", + "@nx/nx-linux-x64-gnu": "16.2.2", + "@nx/nx-linux-x64-musl": "16.2.2", + "@nx/nx-win32-arm64-msvc": "16.2.2", + "@nx/nx-win32-x64-msvc": "16.2.2", + "@parcel/watcher": "2.0.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "^3.0.0-rc.18", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.0.0", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^7.0.2", + "dotenv": "~10.0.0", + "enquirer": "~2.3.6", + "fast-glob": "3.2.7", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.3.4", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "v8-compile-cache": "2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "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" + } + }, + "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 + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "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 + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "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, + "requires": { + "p-try": "^2.0.0" + } + }, + "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, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "dependencies": { + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true + } + } + }, + "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 + }, + "pacote": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dev": true, + "requires": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + } + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "dependencies": { + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + } + } + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "devOptional": true, + "requires": { + "entities": "^4.4.0" + } + }, + "parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "requires": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + } + }, + "parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "requires": { + "parse5": "^7.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "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 + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz", + "integrity": "sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2" + }, + "dependencies": { + "lru-cache": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", + "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "dev": true + } + } + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "php-date-formatter": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/php-date-formatter/-/php-date-formatter-1.3.6.tgz", + "integrity": "sha512-/CKsZYmAwXeNh8KpD/CF9hcJDZNhdb2ICN8+qgqOt5sUu9liZIxZ1R284TNj5MtPt8RjG5X0xn6WSqL0kcKMBg==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" + }, + "pikaday": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/pikaday/-/pikaday-1.8.2.tgz", + "integrity": "sha512-TNtsE+34BIax3WtkB/qqu5uepV1McKYEgvL3kWzU7aqPCpMEN6rBF3AOwu4WCwAealWlBGobXny/9kJb49C1ew==" + }, + "piscina": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", + "dev": true, + "requires": { + "eventemitter-asyncresource": "^1.0.0", + "hdr-histogram-js": "^2.0.1", + "hdr-histogram-percentiles-obj": "^3.0.0", + "nice-napi": "^1.0.2" + } + }, + "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, + "requires": { + "find-up": "^4.0.0" + } + }, + "platform": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz", + "integrity": "sha512-VJK1SRmXBpjwsB4YOHYSturx48rLKMzHgCqDH2ZDa6ZbMS/N5huoNqyQdK5Fj/xayu3fqbXckn5SeCS1EbMDZg==", + "dev": true + }, + "postcss": { + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "dev": true, + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-loader": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.2.tgz", + "integrity": "sha512-c7qDlXErX6n0VT+LUsW+nwefVtTu3ORtVvK8EXuUIDcxo+b/euYqpuHlJAvePb0Af5e8uMjR/13e0lTuYifaig==", + "dev": true, + "requires": { + "cosmiconfig": "^8.1.3", + "jiti": "^1.18.2", + "klona": "^2.0.6", + "semver": "^7.3.8" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true + }, + "postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true + }, + "proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true + }, + "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 + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "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 + } + } + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "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" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "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, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "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 + }, + "qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "ramda": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", + "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "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 + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "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, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "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 + }, + "read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-package-json": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "dev": true, + "requires": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "dependencies": { + "json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true + } + } + }, + "read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "requires": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "dependencies": { + "json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "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, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "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 + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true + }, + "regexp-to-ast": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz", + "integrity": "sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw==" + }, + "regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + } + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "requires": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true + } + } + }, + "replace-in-file": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.3.5.tgz", + "integrity": "sha512-arB9d3ENdKva2fxRnSjwBEXfK1npgyci7ZZuwysgAp7ORjHSyxz6oqIjTEv8R0Ydl4Ll7uOAZXL4vbkhGIizCg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "glob": "^7.2.0", + "yargs": "^17.2.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "requires": { + "throttleit": "^1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "requires": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "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, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.1.tgz", + "integrity": "sha512-I5gJCSpSMr3U9wv4D5YA8g7w7cj3eaSDeo7t+JcaFQOmoOUBgu4K9iMp8k3EZnwbJrjQxUMSKxMyB8qEQzzaSg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "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 + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sass": { + "version": "1.63.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.2.tgz", + "integrity": "sha512-u56TU0AIFqMtauKl/OJ1AeFsXqRHkgO7nCWmHaDwfxDo9GUMSqBA4NEh6GMuh1CYVM7zuROYtZrHzPc2ixK+ww==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "sass-loader": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.1.tgz", + "integrity": "sha512-cBTxmgyVA1nXPvIK4brjJMXOMJ2v2YrQEuHqLw3LylGb3gsR6jAvdjHMcy/+JGTmmIF9SauTrLLR7bsWDMWqgg==", + "dev": true, + "requires": { + "klona": "^2.0.6", + "neo-async": "^2.6.2" + } + }, + "save-svg-as-png": { + "version": "1.4.17", + "resolved": "https://registry.npmjs.org/save-svg-as-png/-/save-svg-as-png-1.4.17.tgz", + "integrity": "sha512-7QDaqJsVhdFPwviCxkgHiGm9omeaMBe1VKbHySWU6oFB2LtnGCcYS13eVoslUgq6VZC6Tjq/HddBd1K6p2PGpA==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, + "optional": true + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "selfsigned": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "dev": true, + "requires": { + "node-forge": "^1" + } + }, + "semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "shiki": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", + "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", + "dev": true, + "requires": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sigstore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.7.0.tgz", + "integrity": "sha512-KP7QULhWdlu3hlp+jw2EvgWKlOGOY9McLj/jrchLjHNlNPK0KWIwF919cbmOp6QiKXLmPijR2qH/5KYWlbtG9Q==", + "dev": true, + "requires": { + "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.1", + "make-fetch-happen": "^11.0.1" + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + } + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true + }, + "socket.io": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.1.tgz", + "integrity": "sha512-W+utHys2w//dhFjy7iQQu9sGd3eokCjGbl2r59tyLqNiJJBdIebn3GAKEXBr3osqHTObJi2die/25bCx2zsaaw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + } + }, + "socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "requires": { + "ws": "~8.11.0" + } + }, + "socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dev": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "requires": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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 + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "requires": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "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, + "requires": { + "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" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "requires": { + "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" + } + }, + "ssri": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", + "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", + "dev": true, + "requires": { + "minipass": "^5.0.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true + }, + "stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "requires": { + "internal-slot": "^1.0.4" + } + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "requires": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "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, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + } + }, + "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, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "tar": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "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, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "tcomb": { + "version": "3.2.29", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", + "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", + "dev": true + }, + "tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "dev": true, + "requires": { + "tcomb": "^3.0.0" + } + }, + "terser": { + "version": "5.17.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", + "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "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 + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==" + }, + "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 + }, + "treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true + }, + "ts-loader": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ts-node": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", + "integrity": "sha512-S87fS5QGinpnvi6I1aW8PnEEwJbkQsr2o+9C3qdAkmaYQn33PKVkXowI2/wggr8FzAwKhvCaomB0EX60LW3/Fw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "chalk": "^2.0.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.0", + "tsconfig": "^6.0.0", + "v8flags": "^3.0.0", + "yn": "^2.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + }, + "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, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "tsconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", + "integrity": "sha512-n3i8c4BOozElBHYMVkEyF9AudHRvvq6NTc6sVRVmLBQM2A02JKjLoICxRtKkoGu3gROOnRZ85KxiTAcmhWgR0w==", + "dev": true, + "requires": { + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "requires": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "tuf-js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "requires": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "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, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true + }, + "typedoc": { + "version": "0.23.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", + "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", + "dev": true, + "requires": { + "lunr": "^2.3.9", + "marked": "^4.2.12", + "minimatch": "^7.1.3", + "shiki": "^0.14.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true + }, + "minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", + "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true + }, + "unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "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, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "requires": { + "builtins": "^5.0.0" + } + }, + "validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vite": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "dev": true, + "requires": { + "esbuild": "^0.17.5", + "fsevents": "~2.3.2", + "postcss": "^8.4.23", + "rollup": "^3.21.0" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true + }, + "vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "wait-on": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", + "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", + "dev": true, + "requires": { + "axios": "^0.25.0", + "joi": "^17.6.0", + "lodash": "^4.17.21", + "minimist": "^1.2.5", + "rxjs": "^7.5.4" + }, + "dependencies": { + "axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dev": true, + "requires": { + "follow-redirects": "^1.14.7" + } + } + } + }, + "watch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz", + "integrity": "sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==", + "dev": true, + "requires": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + } + }, + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webpack": { + "version": "5.86.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", + "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "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 + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "webpack-dev-middleware": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz", + "integrity": "sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + } + }, + "webpack-dev-server": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", + "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "dependencies": { + "webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + } + }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, + "webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "requires": { + "typed-assert": "^1.0.8" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "requires": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + } + }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + } + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zone.js": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.1.tgz", + "integrity": "sha512-+bIeDAFEBYuXRuU3qGQvzdPap+N1zjM4KkBAiiQuVVCrHrhjDuY6VkUhNa5+U27+9w0q3fbKiMCbpJ0XzMmSWA==", + "requires": { + "tslib": "^2.3.0" + } + } + } +} diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..7005629 --- /dev/null +++ b/client/package.json @@ -0,0 +1,128 @@ +{ + "name": "dc-client", + "description": "dc-client", + "angular-cli": {}, + "scripts": { + "start": "node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng serve", + "prestart": "npm run generate-eula", + "generate-eula": "node ./src/eula.ts", + "license-checker": "node licenseChecker.js", + "prebuild": "node ./src/version.ts && npm run generate-eula && npm run license-checker", + "build": "node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration production", + "postbuild": "rimraf dist/3rdpartylicenses.txt", + "build-dev": "node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration development", + "build-watch": "node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration development --watch", + "sync": "./node_modules/.bin/watch --wait=3 \"echo Account: ${npm_config_account} && npm run deploy_${npm_config_server} --account=${npm_config_account} && notify-send 'Data Controller' 'App is synced!' ; echo 'App is synced!'\" dist", + "deploy_sas9": "rsync -avhe ssh ./dist/* --delete ${npm_config_account}@sas.4gl.io:/opt/sas/sas9/config/Lev1/Web/WebServer/htdocs/${npm_config_account}/dc/dev", + "deploy_viya": "rsync -avhe ssh ./dist/* --delete ${npm_config_account}@sas.4gl.io:/var/www/html/${npm_config_account}/dc/dev", + "deploy_sasjs": "rsync -avhe ssh ./dist/* --delete root@${npm_config_account}.4gl.io:/var/www/html/dc/dev", + "viyabuild": "cd build; ./viyabuild.sh", + "lint": "cd .. && npm run lint", + "test": "ng test", + "test:headless": "ng test --browsers ChromeHeadless", + "watch": "ng test watch=true", + "pree2e": "webdriver-manager update", + "e2e": "protractor protractor.config.js", + "postinstall": "node ./src/version.ts && npm run add-githook", + "add-githook": "[ -d ../.git ] && git config core.hooksPath ./.git-hooks || true", + "cypress": "cypress open", + "cy:run": "cypress run", + "audit:prod": "npm audit --omit=dev", + "sasdocs": "sasjs doc && ./sasjs/utils/deploydocs.sh", + "typedoc": "typedoc --options typedoc.json && cd ../dc-devdocs" + }, + "private": true, + "dependencies": { + "@angular/animations": "^16.1.2", + "@angular/cdk": "^15.2.0", + "@angular/common": "^16.1.2", + "@angular/compiler": "^16.1.2", + "@angular/core": "^16.1.2", + "@angular/forms": "^16.1.2", + "@angular/platform-browser": "^16.1.2", + "@angular/platform-browser-dynamic": "^16.1.2", + "@angular/router": "^16.1.2", + "@cds/core": "^6.4.2", + "@clr/angular": "^13.17.0", + "@clr/icons": "^13.0.2", + "@clr/ui": "^13.17.0", + "@handsontable/angular": "^13.0.0", + "@sasjs/adapter": "4.3.6", + "@sasjs/utils": "^3.3.0", + "@sheet/crypto": "1.20211122.1", + "@types/d3-graphviz": "^2.6.7", + "@types/text-encoding": "0.0.35", + "base64-arraybuffer": "^0.2.0", + "buffer": "^5.4.3", + "crypto-browserify": "3.12.0", + "crypto-js": "^3.3.0", + "d3-graphviz": "^5.0.2", + "fs-extra": "^7.0.1", + "handsontable": "^13.0.0", + "https-browserify": "1.0.0", + "hyperformula": "^2.5.0", + "iconv-lite": "^0.5.0", + "jquery-datetimepicker": "^2.5.21", + "jsrsasign": "^10.2.0", + "marked": "^5.0.0", + "moment": "^2.26.0", + "ngx-clipboard": "^16.0.0", + "ngx-json-viewer": "file:libraries/ngx-json-viewer-3.2.1.tgz", + "nodejs": "0.0.0", + "numbro": "^2.1.1", + "os-browserify": "0.3.0", + "rxjs": "^7.8.0", + "save-svg-as-png": "^1.4.17", + "stream-browserify": "3.0.0", + "stream-http": "3.2.0", + "text-encoding": "^0.7.0", + "tslib": "^2.3.0", + "zone.js": "~0.13.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^16.1.0", + "@angular-eslint/builder": "16.0.3", + "@angular-eslint/eslint-plugin": "16.0.3", + "@angular-eslint/eslint-plugin-template": "16.0.3", + "@angular-eslint/schematics": "16.0.3", + "@angular-eslint/template-parser": "16.0.3", + "@angular/cli": "^16.1.0", + "@angular/compiler-cli": "^16.1.2", + "@cypress/webpack-preprocessor": "^5.11.1", + "@types/core-js": "^2.5.5", + "@types/crypto-js": "^4.0.1", + "@types/es6-shim": "^0.31.39", + "@types/jasmine": "~3.6.0", + "@types/lodash-es": "^4.17.3", + "@types/marked": "^4.3.0", + "@types/node": "12.20.50", + "@typescript-eslint/eslint-plugin": "^5.29.0", + "@typescript-eslint/parser": "^5.29.0", + "core-js": "^2.5.4", + "cypress": "^9.5.3", + "cypress-file-upload": "^5.0.8", + "cypress-plugin-tab": "^1.0.5", + "cypress-real-events": "^1.7.6", + "es6-shim": "^0.35.5", + "eslint": "^8.33.0", + "git-describe": "^4.0.4", + "jasmine-core": "~3.6.0", + "karma": "~6.3.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "~1.7.0", + "license-checker": "25.0.1", + "lodash-es": "^4.17.21", + "mochawesome": "^7.1.3", + "mutationobserver-shim": "^0.3.3", + "replace-in-file": "^6.3.5", + "rimraf": "3.0.2", + "ts-loader": "^9.2.8", + "ts-node": "^3.3.0", + "typedoc": "^0.23.24", + "typescript": "~4.9.4", + "wait-on": "^6.0.1", + "watch": "^1.0.2" + } +} \ No newline at end of file diff --git a/client/run-cypress-tests.sh b/client/run-cypress-tests.sh new file mode 100755 index 0000000..70e1f64 --- /dev/null +++ b/client/run-cypress-tests.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +npm run cy:run -- --browser chrome --spec "cypress/integration/liveness.tests.ts" +npm run cy:run -- --browser chrome --spec "cypress/integration/editor.tests.ts" +npm run cy:run -- --browser chrome --spec "cypress/integration/excel.tests.ts" +npm run cy:run -- --browser chrome --spec "cypress/integration/filtering.tests.ts" +npm run cy:run -- --browser chrome --spec "cypress/integration/licensing.tests.ts" \ No newline at end of file diff --git a/client/src/app/_globals.ts b/client/src/app/_globals.ts new file mode 100644 index 0000000..5c95c35 --- /dev/null +++ b/client/src/app/_globals.ts @@ -0,0 +1,118 @@ +import { QueryClause } from './models/TableData' + +interface FilterCache { + cols: any[] + vals: any[] + groupLogic: string + whereClause: string + libds: string + clauses: any[] + query: QueryClause[] +} + +interface ViewboxCache { + [key: number]: { + filter: FilterCache + } +} + +export const initFilter: { filter: FilterCache } = { + filter: { + cols: [], + vals: [], + groupLogic: '', + whereClause: '', + libds: '', + clauses: [], + query: [] + } +} + +export const globals: { + rootParam: string + editor: any + viewer: any + viewboxes: ViewboxCache + lineage: any + metadata: any + viyaApi: any + usernav: any + operators: any + [key: string]: any +} = { + rootParam: '', + editor: { + startupSet: false, + treeNodeLibraries: [], + libsAndTables: [], + libraries: [], + library: '', + table: '', + filter: { + cols: [], + vals: [], + groupLogic: '', + whereClause: '', + libds: '', + clauses: [], + query: [] + } + }, + viewer: { + startupSet: false, + tablesSet: false, + libraries: [], + tables: null, + library: '', + table: '', + libinfo: [], + librariesSearch: '', + filter: { + cols: [], + vals: [], + groupLogic: '', + whereClause: '', + libds: '', + clauses: [], + query: [] + }, + currentSelection: '' + }, + viewboxes: {}, + lineage: { + libraryList: [], + tablesList: [], + columnsList: [], + librariesSearch: '', + lib: '', + table: '', + column: '', + currentLineagePathLibTable: '', + currentLineagePathColumn: '' + }, + metadata: { + metaDataList: undefined, + metaDataSearch: '', + metaObjectList: [], + metaObjectSearch: '', + metaRepositories: undefined, + selectedRepository: '' + }, + viyaApi: { + collectionsList: undefined, + collectionsSearch: '', + selectedRepository: '' + }, + usernav: { + userList: undefined, + userSearch: '', + groupList: undefined, + groupSearch: '', + roleList: undefined, + roleSearch: '' + }, + operators: { + numOperators: ['=', '<', '>', '<=', '>=', 'BETWEEN', 'IN', 'NOT IN', 'NE'], + charOperators: ['=', '<', '>', '<=', '>=', 'CONTAINS', 'IN', 'NOT IN', 'NE'] + } +} diff --git a/client/src/app/actions/actions.component.html b/client/src/app/actions/actions.component.html new file mode 100644 index 0000000..9b5bc8c --- /dev/null +++ b/client/src/app/actions/actions.component.html @@ -0,0 +1,40 @@ +
+
+
+

+ You succesfully edited table + {{ libds }} +

+

+ Please choose from the following actions +

+
+ + + + +
+
+
+
diff --git a/client/src/app/actions/actions.component.scss b/client/src/app/actions/actions.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/actions/actions.component.ts b/client/src/app/actions/actions.component.ts new file mode 100644 index 0000000..d8f4caa --- /dev/null +++ b/client/src/app/actions/actions.component.ts @@ -0,0 +1,50 @@ +import { AfterViewInit, Component, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' + +@Component({ + selector: 'app-actions', + templateUrl: './actions.component.html', + styleUrls: ['./actions.component.scss'], + host: { + class: 'content-container' + } +}) +export class ActionsComponent implements OnInit, AfterViewInit { + public dsid: any + public libds: string | undefined + + constructor( + private route: ActivatedRoute, + private router: Router + ) {} + + public submittedTableScreen() { + this.router.navigateByUrl('/stage/' + this.dsid) + } + + public approveTableScreen() { + this.router.navigateByUrl('/approve/approveDet/' + this.dsid) + } + + public viewerTableScreen() { + this.router.navigateByUrl('/view/data/' + this.libds) + } + + public goBack() { + this.router.navigateByUrl('/editor/' + this.libds) + } + + async ngOnInit() { + this.dsid = this.route.snapshot.params['dsid'] + this.libds = this.route.snapshot.params['libds'] + } + + ngAfterViewInit() { + setTimeout(() => { + let approvalBtn: any = window.document.getElementById('approvalBtn') + if (!!approvalBtn) { + approvalBtn.focus() + } + }, 700) + } +} diff --git a/client/src/app/app-shared.module.ts b/client/src/app/app-shared.module.ts new file mode 100644 index 0000000..198e3d6 --- /dev/null +++ b/client/src/app/app-shared.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { SidebarComponent } from './shared/sidebar/sidebar.component' +import { SoftSelectComponent } from './shared/soft-select/soft-select.component' +import { ClarityModule } from '@clr/angular' +import { RouterModule } from '@angular/router' +import { SharedModule } from './shared/shared.module' +import { FormsModule } from '@angular/forms' +import { PipesModule } from './pipes/pipes.module' +import { DirectivesModule } from './directives/directives.module' +import { AutocompleteModule } from './shared/autocomplete/autocomplete.module' + +@NgModule({ + declarations: [SidebarComponent, SoftSelectComponent], + imports: [ + CommonModule, + FormsModule, + ClarityModule, + RouterModule, + SharedModule, + PipesModule, + DirectivesModule, + AutocompleteModule + ], + exports: [SidebarComponent, SoftSelectComponent] +}) +export class AppSharedModule {} diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html new file mode 100644 index 0000000..f254b1b --- /dev/null +++ b/client/src/app/app.component.html @@ -0,0 +1,299 @@ +
+ + + + + + + + +
+ + +
+ +
+ + + + +
+ + + + VIEW + EDIT + REVIEW + + +
+ +
+ VIEW + EDIT + REVIEW +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+
+
+
+
+
+ diff --git a/client/src/app/app.component.scss b/client/src/app/app.component.scss new file mode 100644 index 0000000..3dc3406 --- /dev/null +++ b/client/src/app/app.component.scss @@ -0,0 +1,461 @@ +// Copyright (c) 2016 VMware, Inc. All Rights Reserved. +// This software is released under MIT license. +// The full license information can be found in LICENSE in the root directory of this project. +app-requests-modal { + z-index: 10000; +} + +header.app-header { + background: #314351 !important; + color: #fff; +} + +.logo img.without-text { + width: 30px; +} + +.logo img.with-text { + width: 210px; +} + +.header-hamburger-trigger { + display: block; + background: transparent; + border: 0; + margin-left: 10px; +} + +.demo-expired-notice { + display: flex; + justify-content: center; + align-items: center; + position: fixed; + left: 0; + top: 0; + height: 100vh !important; + width: 100vw !important; + z-index: 105; + background: rgba(33, 33, 33, .5); + + .expired-details { + flex-direction: column; + align-items: center; + padding: 30px; + z-index: 110; + background: #314351; + + .expired-notice { + color: #e0e0e0; + font-size: 16px; + + .mailto { + color: #8dc53e; + } + } + } +} + +.main-container .update-key { + display: flex; + align-items: center; + color: white; + padding: 0px 10px; + background: #00000026; +} + +.alert-icon-wrapper { + margin-top: 0 !important; +} + +.nav-text { + margin-right: 20px; +} + +.sidebar-toggle { + display: flex; + height: 100%; + align-items: center; + padding-left: 10px; + + clr-icon { + cursor: pointer; + width: 30px; + height: 30px; + } +} + +header { + .header-actions { + .dropdown { + position: unset; //without it, when opening user dropdown scrollbar was displaying without reason + } + } + + .nav + .nav-link { + color: #fafafa; + opacity: .9; + line-height: 1.45rem; + } + + .nav .nav-link:hover { + box-shadow: inset 0 -3px 0 transparent; + transition: box-shadow .2s ease-in; + } + + .nav + .nav-link:hover { + color: #fafafa; + opacity: 1; + } + + .nav .nav-link.active { + background: #61717D; + opacity: 1; + box-shadow: inset 0 -3px transparent; + // padding: 0 1rem 0 1rem; + } + + .nav .nav-item { + margin-right: 1rem; + } +} + +.notf { + background: #16a57a; + color: #fffcfc; + font-size: 12px; +} + +.btn.btn-success { + border-color: #62a420; + background-color: #16a57a!important; + color: #fff; +} +.btn.btn-success:hover { + background-color: #2add39; + color: #fff; +} + +.toggle-switch input[type=checkbox]:checked+label:before { + border-color: #61717D; + background-color: #61717D; + transition: .15s ease-in; + transition-property: border-color,background-color; +} + +.main-container { + min-height: 100vh !important; +} + +.main-container .content-container .content-area { + padding: 0rem 1rem 1rem 1rem; +} + +.content-container { + z-index: 0!important; +} + +.navBarResp { + display: flex; + justify-content: center; + background: #495A67; + color: #fff; +} + +@media screen and (max-width: 768px) { + .navBarResp { + display: flex; + justify-content: flex-start; + background: #495A67; + color: #fff; + } + + .main-container .sub-nav.clr-nav-level-1 .nav .nav-link, .main-container .sub-nav.clr-nav-level-2 .nav .nav-link, .main-container .subnav.clr-nav-level-1 .nav .nav-link, .main-container .subnav.clr-nav-level-2 .nav .nav-link { + padding: 0 .5rem 0 1rem; + width: 100%; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + border-radius: .125rem 0 0 .125rem; + color: #95c84b; + } + + + + .card-block, .card-footer { + padding: 10px 0px 0px 0px; + } + + .main-container[_ngcontent-c0] .content-container[_ngcontent-c0] .content-area[_ngcontent-c0] { + padding: 0rem 0rem 0rem 0rem; + } + +} +::ng-deep { + .htInvalid { + background: black!important; +} + + @media screen and (max-width:480px) { + h2 { + font-size: .7rem!important; + + } + h3 { + font-size: .7rem; + } +} + + .nav-link { + padding: 0rem 1rem 0rem 1rem; + } + + .btn-primary .btn, .btn.btn-primary { + border-color: #314351; + background-color: #314351; + color: #fff; + } + .btn { + cursor: pointer; + display: inline-block; + -webkit-appearance: none!important; + border-radius: .125rem; + border: 1px solid; + min-width: 3rem; + max-width: 15rem; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: center; + text-transform: uppercase; + vertical-align: middle; + line-height: 1.5rem; + letter-spacing: .12em; + font-size: .5rem; + font-weight: 500; + height: 1.5rem; + padding: 0 .5rem; + border-color: #314351; + background-color: transparent; + color: #314351; + } + + .btn.btn-outline { + border-color: #314351; + background-color: transparent; + color: #314351; + } + + .btn.btn-outline:hover { + border-color: #314351; + background-color: #495A67; + color: #fff; + } + + .btn.btn-success-outline:hover { + background-color: #5ea71f; + color: #fff7f7; + border-color: #9a9696; +} +// .btn.btn-success-outline { +// border-color: #266900; +// background-color: transparent; +// color: #318700; +// } + // .wtSpreader { + + // } + + .htMobileEditorContainer .inputs textarea { + font-size: 13pt; + border: 2px solid #485967; + border-radius: 4px; + -webkit-appearance: none; + box-shadow: none; + position: absolute; + left: 14px; + right: 0px; + top: 0; + bottom: 0; + padding: 7pt; + width: 290px; +} + +.htMobileEditorContainer .positionControls { + width: 333px; + position: absolute; + right: 5pt; + top: 50px; + bottom: 0; + display: flex; + justify-content: center; +} + +.htMobileEditorContainer.active { + display: block; + height: 120px; + width: 350px; +} + + .handsontable { + background-color: #ffffff; + // border: 1px solid #ccc; + border-radius: 3px; + } + .handsontable th { + background-color: #fafafa; + } + + /* Left and right */ + .ht_clone_left th { + border-right: 1px solid #ccc; + border-left: 1px solid #ccc; + } + + /* Column headers */ + .ht_clone_top th { + border-top: 1px solid #ccc; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + } + + .ht_clone_top_left_corner th { + border-right: 1px solid #ccc; + } + + .ht_master tr:nth-of-type(odd) > td { + background-color: #f3f3f3; + border: 1px solid rgb(197, 197, 197); + border-bottom: 1px solid rgb(236, 235, 235); + // padding: 1px 1px; + } + + .ht_master tr:nth-of-type(even) > td { + background-color: white; + border: 1px solid rgb(197, 197, 197); + border-bottom: 1px solid rgb(236, 235, 235); + // padding: 1px 1px; + } + + .wtBorder { + background-color: #495A67!important; + } + + .handsontable .handsontable.ht_clone_top .wtHider { + padding: 0 0 0px 0!important; + margin: 0px; + border-bottom: 3px solid #d6d3d3; +} + + .content-container { + background: #F5F6FF; + } + + .card { + box-shadow: 0 0.125rem 0 0 #d7d7d7; + border-radius: .0rem; + border: 1px solid transparent; + // min-height: calc(100vh - 150px); + } + + .datagrid-compact, .datagrid-history{ + .datagrid { + border-collapse: separate; + border: 1px solid transparent; + border-radius: .125rem; + background-color: #fff; + color: #565656; + margin: 0; + margin-top: 1rem; + max-width: 100%; + width: 100%; + padding: 15px 15px 50px 15px; + } + .datagrid-foot { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + height: 1.5rem; + padding: 0 .5rem; + line-height: calc(1.5rem - 3px); + font-size: .45833rem; + background-color: #fff; + border-top: 1px solid #ccc; + border-radius: 0px; + // border-radius: 0 0 .125rem .125rem; + } + .datagrid-footer { + position: absolute; + right: 15px; + top: 2px; + } + .datagrid .datagrid-head { + background-color: #fff; + border-bottom: 1px solid #ccc; + } + } + + .dropdown-menu { + position: absolute; + top: 100%; + left: 0; + margin-top: .083333rem; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + background: #f5f6ff; + padding: .5rem 0; + border: 1px solid #ccc; + box-shadow: 0 1px 0.125rem hsla(0,0%,45%,.25); + min-width: 5rem; + max-width: 15rem; + border-radius: .125rem; + visibility: hidden; + z-index: 1000; + } + + .table { + border-collapse: separate; + border: 1px solid transparent; + border-radius: 0px; + background-color: #fff; + color: #565656; + margin: 0; + margin-top: 1rem; + max-width: 100%; + width: 100%; + } + + .table th { + font-size: .45833rem; + font-weight: 600; + letter-spacing: .03em; + background-color: #fff; + vertical-align: bottom; + border-bottom: 1px solid #ccc; + text-transform: uppercase; + } + + .modal-header { + border-bottom: 2px solid #e4e4e4; + padding: 0 0 .5rem 0; + margin-bottom: 1rem; + } + + .main-container .content-container { + min-height: 0px; + position: relative; + } +} + +.app-loading { + .loading-logo { + max-width: 400px; + width: 100%; + } +} \ No newline at end of file diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts new file mode 100644 index 0000000..63758f3 --- /dev/null +++ b/client/src/app/app.component.ts @@ -0,0 +1,279 @@ +import { ChangeDetectorRef, Component, ElementRef } from '@angular/core' +import { Router } from '@angular/router' +import { VERSION } from '../environments/version' +import { ActivatedRoute } from '@angular/router' +import { Location } from '@angular/common' +import '@clr/icons' +import '@clr/icons/shapes/all-shapes' +import { globals } from './_globals' +import * as moment from 'moment' +import { EventService } from './services/event.service' +import { AppService } from './services/app.service' +import { InfoModal } from './models/InfoModal' +import { DcAdapterSettings } from './models/DcAdapterSettings' +import { AppStoreService } from './services/app-store.service' +import { LicenceService } from './services/licence.service' + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { + private dcAdapterSettings: DcAdapterSettings | undefined + public commitVer: string + public version: any + public routeUrl: any + public errTop: boolean | undefined + public licenseExpiringDays: number | null = null + public sasjsAborts: InfoModal[] = [] + + public editorActive: boolean = false + public approveActive: boolean = false + public freeTierBanner: boolean = this.licenceService.isAppFreeTier.value + public licenceProblem = this.licenceService.licenceProblem + public appOverCapacity: boolean = false + public appActive: boolean | null = null + public requestsModal: boolean = false + public showRegistration: boolean = true + public startupDataLoaded: boolean = false + public demoLimitNotice: { open: boolean; featureName: string } = { + open: false, + featureName: '' + } + + public syssite = this.appService.syssite + public licenceState = this.licenceService.licenceState + + constructor( + private appService: AppService, + private licenceService: LicenceService, + public router: Router, + private route: ActivatedRoute, + private location: Location, + private eventService: EventService, + private appStoreService: AppStoreService, + private cdr: ChangeDetectorRef, + private elementRef: ElementRef + ) { + this.parseDcAdapterSettings() + ;(window as any).appinfo = () => { + const licenseKeyData = this.licenceService.getLicenseKeyData() + + if (licenseKeyData) { + const expiry_date = moment( + licenseKeyData.valid_until, + 'YYYY-MM-DD' + ).startOf('day') + const current_date = moment().startOf('day') + const daysToExpiry = expiry_date.diff(current_date, 'days') + + licenseKeyData.valid_until += ` (${daysToExpiry} ${ + daysToExpiry === 1 ? 'day' : 'days' + } remaining)` + + if (isNaN(daysToExpiry)) licenseKeyData.valid_until = 'Unlimited' + } + + console.table({ + 'Adapter version': VERSION.adapterVersion || 'n/a', + 'App version': (VERSION.tag || '').replace('v', ''), + 'Build timestamp': moment(parseInt(VERSION.timestamp)).format( + 'DD-MMM-YYYY HH:MM' + ), + '...': '...' + }) + } + + this.subscribeToLicenseEvents() + + this.commitVer = (VERSION.tag || '').replace('v', '') + '.' + VERSION.hash + router.events.subscribe((val) => { + this.routeUrl = this.router.url + + if (typeof this.routeUrl !== 'undefined' && this.routeUrl.length > 4) { + let rootParam = this.routeUrl.split('/')[1] + + if (rootParam === 'editor') { + this.errTop = true + this.editorActive = true + this.approveActive = false + } else if (rootParam === 'home') { + this.errTop = false + this.editorActive = true + this.approveActive = false + } else { + this.errTop = true + this.editorActive = false + } + + globals.rootParam = rootParam + } + + if (typeof this.routeUrl !== 'undefined' && this.routeUrl.length > 6) { + if (this.routeUrl.includes('approveDet')) { + this.approveActive = true + } else if (this.routeUrl.includes('toapprove')) { + this.approveActive = true + } else { + this.approveActive = false + } + } + }) + + this.subscribeToShowAbortModal() + this.subscribeToRequestsModal() + this.subscribeToStartupData() + this.subscribeToAppActive() + this.subscribeToDemoLimitModal() + + /* In Viya streaming apps, content is served within an iframe. This code + makes that iframe "full screen" so it looks like a regular window. */ + if (window.frameElement) { + window.frameElement.setAttribute( + 'style', + 'height:100%;width:100%;position:absolute' + ) + window.frameElement.setAttribute('allowfullscreen', '') + window.frameElement.setAttribute('frameborder', '0') + window.frameElement.setAttribute('marginheight', '0') + window.frameElement.setAttribute('marginwidth', '0') + window.frameElement.setAttribute('scrolling', 'auto') + window.focus() + } + } + + private parseDcAdapterSettings() { + const sasjsElement = document.querySelector('sasjs') + + if (!sasjsElement) { + this.licenceService.deactivateApp() + setTimeout(() => { + this.eventService.showAbortModal( + null, + "Please make sure 'SASJS' tag with config attributes is added to index.html", + null, + 'SASjs Config not found' + ) + }) + return + } + + const getAppAttribute = (attribute: string) => + sasjsElement.getAttribute(attribute) || undefined + + const dcAdapterSettings = { + serverUrl: getAppAttribute('serverUrl') || '', + appLoc: getAppAttribute('appLoc') || '', + serverType: getAppAttribute('serverType'), + loginMechanism: getAppAttribute('loginMechanism') || '', + adminGroup: getAppAttribute('adminGroup') || '', + dcPath: getAppAttribute('dcPath') || '', + debug: getAppAttribute('debug') === 'true' || false, + useComputeApi: this.parseComputeApi(getAppAttribute('useComputeApi')), + contextName: getAppAttribute('contextName') || '', + hotLicenceKey: getAppAttribute('hotLicenceKey') || '' + } + + this.dcAdapterSettings = dcAdapterSettings as any + this.appStoreService.setDcAdapterSettings(dcAdapterSettings as any) + this.appService.sasServiceInit() + } + + public licenceProblemDetails(url: string) { + this.router.navigateByUrl(url) + } + /** + * Based on string provided we return true, false or null + * True -> Compute API + * False -> JES API + * Null -> JES WEB + * @param value provided in the html tag + * @returns true, false or null + */ + private parseComputeApi(value: string | undefined): boolean | null { + if (value === undefined) return null + + if (value === 'undefined' || value === 'null') return null + + return value === 'true' || false + } + + public subscribeToDemoLimitModal() { + this.eventService.onDemoLimitModalShow.subscribe((featureName: string) => { + this.demoLimitNotice = { + open: true, + featureName + } + }) + } + + public subscribeToLicenseEvents() { + this.licenceService.isAppFreeTier.subscribe((isAppFreeTier: boolean) => { + this.freeTierBanner = isAppFreeTier + }) + + this.licenceService.licenseExpiresInDays.subscribe( + (licenseExpiringDays: number | null) => { + if (licenseExpiringDays && licenseExpiringDays <= 14) + this.licenseExpiringDays = licenseExpiringDays + } + ) + + this.licenceService.isAppOverCapacity.subscribe( + (isAppOverAppCapacity: boolean) => { + this.appOverCapacity = isAppOverAppCapacity + } + ) + } + + public subscribeToAppActive() { + this.licenceService.isAppActivated.subscribe((value: any) => { + this.appActive = value + }) + } + + /** + * Listnes to an event that is fired when showing abort modal + * Then pushes object to array and modal is displayed + * `abortId` is calculated and assigned so that modal can be removed and closed + * it's an incrementing number + */ + public subscribeToShowAbortModal() { + this.eventService.onShowAbortModal.subscribe((sasjsAbort: InfoModal) => { + let abortId = this.sasjsAborts.length + 1 + sasjsAbort.id = abortId + this.sasjsAborts.push(sasjsAbort) + this.cdr.detectChanges() //Changes were not triggered while hot is focused + }) + } + + public subscribeToStartupData() { + this.eventService.onStartupDataLoaded.subscribe(() => { + this.startupDataLoaded = true + }) + } + + public subscribeToRequestsModal() { + this.eventService.onRequestsModalOpen.subscribe((value: boolean) => { + this.requestsModal = true + }) + } + + public closeAbortModal(abortId: number) { + let abortIndex = this.sasjsAborts.findIndex((abort) => abort.id === abortId) + this.sasjsAborts.splice(abortIndex, 1) + } + + public toggleSidebar() { + this.eventService.toggleSidebar() + } + + public isMainRoute(route: string): boolean { + return this.router.url.includes(route) + } + + public openLicencingPage() { + this.router.navigateByUrl('/licensing/update') + } +} diff --git a/client/src/app/app.d.ts b/client/src/app/app.d.ts new file mode 100644 index 0000000..fa54acf --- /dev/null +++ b/client/src/app/app.d.ts @@ -0,0 +1,5 @@ +declare module 'save-svg-as-png' + +declare interface Navigator { + msSaveBlob: (blob: any, defaultName?: string) => boolean +} diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts new file mode 100644 index 0000000..53757b2 --- /dev/null +++ b/client/src/app/app.module.ts @@ -0,0 +1,90 @@ +import { HttpClientModule } from '@angular/common/http' +import { NgModule } from '@angular/core' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { BrowserModule } from '@angular/platform-browser' +import { BrowserAnimationsModule } from '@angular/platform-browser/animations' +import { ClarityModule } from '@clr/angular' + +import { AppComponent } from './app.component' +import { ROUTING } from './app.routing' +import { NotFoundComponent } from './not-found/not-found.component' + +import { SasStoreService } from './services/sas-store.service' +import { SharedModule } from './shared/shared.module' +// import { EditorComponent } from './editor/editor.component' +import { ActionsComponent } from './actions/actions.component' +import { AppSharedModule } from './app-shared.module' +import { ApproveDetailsComponent } from './approve-details/approve-details.component' +import { ApproveComponent } from './approve/approve.component' +import { DeployComponent } from './deploy/deploy.component' +import { AutomaticComponent } from './deploy/sections/automatic/automatic.component' +import { ManualComponent } from './deploy/sections/manual/manual.component' +import { SasjsConfiguratorComponent } from './deploy/sections/sasjs-configurator/sasjs-configurator.component' +import { GroupComponent } from './group/group.component' +import { HistoryComponent } from './history/history.component' +import { LicensingComponent } from './licensing/licensing.component' +import { LineageComponent } from './lineage/lineage.component' +import { MetadataComponent } from './metadata/metadata.component' +import { PipesModule } from './pipes/pipes.module' +import { RoleComponent } from './role/role.component' +import { ApproveRouteComponent } from './routes/approve-route/approve-route.component' +import { HistoryRouteComponent } from './routes/history-route/history-route.component' +import { LicensingGuard } from './routes/licensing.guard' +import { UsernavRouteComponent } from './routes/usernav-route/usernav-route.component' +import { AppService } from './services/app.service' +import { InfoModalComponent } from './shared/abort-modal/info-modal.component' +import { RequestsModalComponent } from './shared/requests-modal/requests-modal.component' +import { SubmitterComponent } from './submitter/submitter.component' +import { UserComponent } from './user/user.component' +import { HomeModule } from './home/home.module' +import { SystemComponent } from './system/system.component' +import { DirectivesModule } from './directives/directives.module' +import { ViyaApiExplorerComponent } from './viya-api-explorer/viya-api-explorer.component' +import { NgxJsonViewerModule } from 'ngx-json-viewer' + +@NgModule({ + declarations: [ + AppComponent, + NotFoundComponent, + ApproveComponent, + ApproveDetailsComponent, + ActionsComponent, + HistoryComponent, + LineageComponent, + SubmitterComponent, + ApproveRouteComponent, + HistoryRouteComponent, + MetadataComponent, + UsernavRouteComponent, + UserComponent, + GroupComponent, + RoleComponent, + RequestsModalComponent, + DeployComponent, + InfoModalComponent, + LicensingComponent, + ManualComponent, + AutomaticComponent, + SasjsConfiguratorComponent, + SystemComponent, + ViyaApiExplorerComponent + ], + imports: [ + BrowserAnimationsModule, + BrowserModule, + FormsModule, + ReactiveFormsModule, + HttpClientModule, + ROUTING, + SharedModule, + ClarityModule, + AppSharedModule, + HomeModule, + PipesModule, + DirectivesModule, + NgxJsonViewerModule + ], + providers: [AppService, SasStoreService, ApproveComponent, LicensingGuard], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/client/src/app/app.routing.ts b/client/src/app/app.routing.ts new file mode 100644 index 0000000..1b06bd0 --- /dev/null +++ b/client/src/app/app.routing.ts @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 VMware, Inc. All Rights Reserved. + * This software is released under MIT license. + * The full license information can be found in LICENSE in the root directory of this project. + */ +import { ModuleWithProviders } from '@angular/core' +import { Routes, RouterModule } from '@angular/router' + +import { HomeComponent } from './home/home.component' +import { ApproveComponent } from './approve/approve.component' +import { ApproveDetailsComponent } from './approve-details/approve-details.component' +import { ActionsComponent } from './actions/actions.component' +import { HistoryComponent } from './history/history.component' +import { NotFoundComponent } from './not-found/not-found.component' +import { SubmitterComponent } from './submitter/submitter.component' + +import { ApproveRouteComponent } from './routes/approve-route/approve-route.component' +import { DeployComponent } from './deploy/deploy.component' +import { LicensingComponent } from './licensing/licensing.component' +import { LicensingGuard } from './routes/licensing.guard' +import { StageModule } from './stage/stage.module' +import { EditorModule } from './editor/editor.module' +import { ViewerModule } from './viewer/viewer.module' +import { SystemComponent } from './system/system.component' + +export const ROUTES: Routes = [ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { + path: 'view', + loadChildren: () => ViewerModule + }, + { + path: 'approve', + component: ApproveRouteComponent, + children: [ + { path: '', pathMatch: 'full', redirectTo: 'toapprove' }, + { path: 'toapprove', component: ApproveComponent }, + { path: 'approveDet/:tableId', component: ApproveDetailsComponent }, + { path: 'submitted', component: SubmitterComponent } + ] + }, + { + path: 'licensing/:action', + component: LicensingComponent, + canActivate: [LicensingGuard], + canDeactivate: [LicensingGuard] + }, + { path: 'home', component: HomeComponent }, + { + path: 'editor', + loadChildren: () => EditorModule + }, + { + path: 'stage', + loadChildren: () => StageModule + }, + { path: 'system', component: SystemComponent }, + { path: 'actions/:libds/:dsid', component: ActionsComponent }, + { path: 'history', component: HistoryComponent }, + { path: 'submitted', component: SubmitterComponent }, + { path: 'submitted/:tableId', component: SubmitterComponent }, + { path: 'deploy', component: DeployComponent }, + { path: 'deploy/manualdeploy', component: DeployComponent }, + { path: '**', component: NotFoundComponent } +] + +export const ROUTING: ModuleWithProviders = RouterModule.forRoot( + ROUTES, + { useHash: true } +) diff --git a/client/src/app/approve-details/approve-details.component.html b/client/src/app/approve-details/approve-details.component.html new file mode 100644 index 0000000..33a498c --- /dev/null +++ b/client/src/app/approve-details/approve-details.component.html @@ -0,0 +1,588 @@ + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + Back to + approvals list + +
+
+

+ {{ jsParams?.TABLE_NM }} +

+
+ +
+

+ {{ jsParams?.TABLE_DESC }} +

+
+
+
+
+
+

+ There are no details to show +

+ + +
+ Table Id: + + {{ tableDetails?.TABLE_ID }} + +
+
+ Submitter: + + {{ tableDetails?.SUBMITTED_BY_NM }} + +
+
+ Submitted on: + + {{ tableDetails?.SUBMITTED_ON_DTTM }} + +
+
+ Submitted Reason: + + {{ tableDetails?.SUBMITTED_REASON_TXT }} + +
+
+
+
+
+
+
+ + + +
+
+
+
+ + + + + + + + + +
+ +
+ + + Only the first 100 inserts, updates or deletes are displayed + +
+
+ + Changed Rows + {{ + lens.updated + }} + + + Added Rows + {{ lens.new }} + + + Deleted Rows + {{ + lens.deleted + }} + +
+
+
+
+
+
+
+ +
+ Loading... +
+

Loading table

+
+
+ +
+

+ There are no changes to show +

+ + + + + + + + + + + + + + + + + +
{{ col }}
+ {{ diffTable.data[i][col] }} + Original value is: {{ arrOfChanges[i][chIndex] }} + + {{ diffTable.data[i][col] }} +
+
+
+
+
+
+ Loading... +
+

Loading preview

+
+
+
+
+ + + +
+
+
+
+
+
+ + Back to + submitted list + +
+
+

+ {{ subObj.base }} +

+
+
+ + + +
+
+

+ {{ tableDescription }} +

+
+
+
+
+ Table Id: + + {{ subObj.tableId }} + +
+
+ Submitted on: + + {{ subObj.submitted }} + +
+
+ Submit Message: + + {{ subObj.submitReason }} + +
+
+
+
+
+
+ + + +
+
+
+ +
+ + + Only the first 100 inserts, updates or deletes are displayed + +
+
+ + Changed Rows + {{ lens.updated }} + + + Added Rows + {{ lens.new }} + + + Deleted Rows + {{ lens.deleted }} + +
+
+
+ +
+ + + + + + +
+
+
+ +
+
+
+ +
+ Loading... +
+

Loading table

+
+
+
+ + + + + + + + + + + + + + + + +
{{ col }}
+ {{ diffTable.data[i][col] }} + Original value is: {{ arrOfChanges[i][chIndex] }} + + {{ diffTable.data[i][col] }} +
+
+
+
+
+
+ Loading... +
+

Loading submitted table

+
+
+
+
+
diff --git a/client/src/app/approve-details/approve-details.component.scss b/client/src/app/approve-details/approve-details.component.scss new file mode 100644 index 0000000..ce13bdc --- /dev/null +++ b/client/src/app/approve-details/approve-details.component.scss @@ -0,0 +1,179 @@ +.loader { + display:flex; + justify-content: center; + height:75vh; + align-items:center; + flex-direction:column +} +.modalLarge { + width: 50rem!important; +} + +.addedRow { + background: rgb(146, 208, 154); + border: 1px solid rgba(9, 77, 117, 0.2); + border-radius: 5px; +} + +.deletedRow { + background: rgb(230, 179, 179); + border: 1px solid rgba(70, 71, 70, 0.2); + border-radius: 5px; +} + +.updatedRow { + background: #fafda8; + border: 1px solid rgba(9, 117, 9, 0.2); + border-radius: 5px; +} + +.table { + border: 0px solid; +} + +.ch { + background: rgba(0,0,0,.1); + border: 1px solid rgba(104, 100, 0, 0.4); + border-radius: 5px; +} + +.ch:hover { +background: rgba(252, 135, 120, 0.4); +} + +.tooltip .tooltip-content.tooltip-top-right, .tooltip.tooltip-top-right>.tooltip-content, .tooltip>.tooltip-content { + font-size: .54167rem; + font-weight: 400; + letter-spacing: normal; + background: #314351; + border-radius: .125rem; + color: #f0f1ec;; + line-height: .75rem; + margin: 0; + padding: .375rem .5rem; + width: 235px; + position: absolute; + top: auto; + bottom: 100%; + left: 12px; + right: auto; + border-bottom-left-radius: 0; + margin-bottom: .66667rem; +} + +.tooltip .tooltip-content.tooltip-top-right:before, .tooltip.tooltip-top-right>.tooltip-content:before, .tooltip>.tooltip-content:before { + position: absolute; + bottom: -.375rem; + left: 0; + top: auto; + right: auto; + content: ""; + border-left: .25rem solid #314351; + border-top: .20833rem solid #314351; + border-right: .25rem solid transparent; + border-bottom: .20833rem solid transparent; +} + +.table { +border: 0px solid; +} + +.toggle-switch input[type=checkbox]:checked+label:before { + border-color: #314351; + background-color: #314351!important; + transition: .15s ease-in; + transition-property: border-color,background-color; +} + +.tableCont { + overflow:auto; + margin: 15px 10px 10px 10px; + + td { + word-break: break-word; + } +} + +.approvalInfo { + display: flex; + justify-content: flex-end +} + +.approvalBack { + display: flex; + justify-content: flex-start; +} + +@media screen and (max-width:768px) { + .approvalInfo { + display: flex; + justify-content: center; + margin-top: 15px; + + } + + .approvalBack { + display: flex; + justify-content: center; + margin-bottom: 15px; + } + + .card { + margin-top:0rem!important; + min-height: calc(100vh - 0px)!important; + } + + .table td.left, .table th.left { + text-align: left; + width: 150px!important; + flex: 0 + } +} + +.table td.left, .table th.left { + text-align: left; + flex: 1; + width: 300px!important; +} + + +.tooll { + position: absolute; + background: #e6b3b3; + color: #314351; + top: 0px; + height: 36px; + width: 100%; + left: 0px; + justify-content: center; + align-items: center; + display: flex; +} + +#acceptBtn, #rejectBtn { + width: 175px +} + +.formatted-values-toggle { + min-width: 75px +} + +clr-modal { + ::ng-deep { + .modal-body-wrapper { + overflow: auto; + } + } +} + +.rows-notice { + display: flex; + align-items: center; + margin-right: 10px; + color: #6a6a6a; + font-size: 15px; + + clr-icon { + margin: 0; + } +} \ No newline at end of file diff --git a/client/src/app/approve-details/approve-details.component.ts b/client/src/app/approve-details/approve-details.component.ts new file mode 100644 index 0000000..7d3dfa6 --- /dev/null +++ b/client/src/app/approve-details/approve-details.component.ts @@ -0,0 +1,407 @@ +import { ActivatedRoute } from '@angular/router' +import { SasStoreService } from '../services/sas-store.service' +import { Component, AfterViewInit, OnDestroy } from '@angular/core' +import { Subscription } from 'rxjs' +import { Router } from '@angular/router' +import { EventService } from '../services/event.service' +import { + AuditorsPostdataSASResponse, + Param +} from '../models/sas/auditors-postdata.model' + +interface ChangesObj { + ind: any + field: any + prop: any + original: any +} + +@Component({ + selector: 'app-approve-details', + templateUrl: './approve-details.component.html', + styleUrls: ['./approve-details.component.scss'], + host: { + class: 'content-container' + } +}) +export class ApproveDetailsComponent implements AfterViewInit, OnDestroy { + private _detailsSub: Subscription | undefined + public tableId: any + public detailsOpen: any = false + public rejectOpen: any = false + public jsParams: any + public keysArray!: Array + public submitArr!: Array + public hotSelection: any + public lens: { new: number; updated: number; deleted: number } = { + new: 0, + updated: 0, + deleted: 0 + } + public loaded: boolean = false + public loadingTable: boolean = false + public submitReason: string = '' + public instance: string = 'hotInstance' + public params: Param | undefined + public subObj: any + public submitDetails: any + public acceptLoading: boolean = false + public rejectLoading: boolean = false + public submitted: boolean = false + public tableFlag: boolean = false + public originals: any + public rowKeys: any = [] + public rowHeader!: Array + public arrChanged!: Array + public arrOfChanges!: Array + public chArr: Array = [] + public tableDetails: any + public secondOpen: boolean = false + public addCount: number | undefined + public tableDescription: string | undefined + public formattedValues: boolean = true + private response: AuditorsPostdataSASResponse | undefined + + public changesArr: Array = [] + + public diffTable: any = { + data: [] + } + + public diffsLimit: boolean = false + public recordsLimit: number = 100 + + constructor( + private sasStoreService: SasStoreService, + private eventService: EventService, + private router: ActivatedRoute, + private route: Router + ) {} + + get noChanges() { + return ( + this.lens.new === 0 && this.lens.updated === 0 && this.lens.deleted === 0 + ) + } + + public goToBase(base: any) { + this.route.navigateByUrl('/view/data/' + base) + } + + public goToApprovalsList() { + this.route.navigateByUrl('/approve') + } + + public getTable(tableId: any) { + this.route.navigateByUrl('/stage/' + tableId) + } + + public goBack(base: any) { + this.route.navigateByUrl('/editor/' + base) + } + + public goToViewer() { + this.route.navigateByUrl('/view/data') + } + + public showDetailsSelect($event: Event) { + $event.preventDefault() + this.tableFlag = !this.tableFlag + } + + public getDetails() { + this.detailsOpen = true + } + + public onHotSelection(evt: any) { + this.hotSelection = evt.slice(0, 4) + } + + public onHotDeselect() { + setTimeout(() => { + this.hotSelection = null + }, 100) + } + + public async rejecting() { + this.rejectLoading = true + this.submitReason = this.submitReason.replace(/\n/g, '. ') + + let rejParams = { + STP_ACTION: 'REJECT_TABLE', + TABLE: this.tableId, + STP_REASON: this.submitReason + } + + await this.sasStoreService + .rejecting(rejParams, 'BrowserParams', 'approvers/rejection') + .then((res: any) => { + this.route.navigateByUrl('/history') + }) + .catch((err: any) => { + this.acceptLoading = false + this.rejectLoading = false + }) + } + + public async approveTable() { + this.acceptLoading = true + let approveParams = { + ACTION: 'APPROVE_TABLE', + TABLE: this.tableId, + DIFFTIME: this.params?.DIFFTIME, + LIBDS: this.params?.LIBDS + } + + await this.sasStoreService + .approveTable(approveParams, 'SASControlTable', 'auditors/postdata') + .then((res: any) => { + this.route.navigateByUrl('/history') + }) + .catch((err: any) => { + this.acceptLoading = false + }) + } + + public goToSubmitList() { + this.route.navigateByUrl('/submitted') + } + + public async callChangesInfo(tableId: any) { + await this.sasStoreService + .getChangeInfo(tableId) + .then((res: any) => { + this.tableDetails = res.jsparams[0] + this.jsParams = res.jsparams[0] + + let keysArray: Array = [] + + for (const key in this.jsParams) { + if (this.jsParams.hasOwnProperty(key)) { + keysArray.push(key) + } + } + + this.keysArray = keysArray + }) + .catch((err: any) => { + this.acceptLoading = false + }) + .finally(() => { + this.loaded = true + }) + } + + public formattingChanged() { + this.calcDiff() + } + + public calcDiff() { + if (!this.response) return + + let news = this.response.new + let updates = this.response.updates + let deleted = this.response.deleted + let originals = this.response.originals + + if (this.formattedValues) { + news = this.response.fmt_new + updates = this.response.fmt_updates + deleted = this.response.fmt_deleted + originals = this.response.fmt_originals + } + + let delLen = deleted.length + let upLen = updates.length + let newLen = news.length + this.originals = originals + this.rowKeys = [] + + for (let index = 0; index < updates.length; index++) { + let keys = Object.keys(updates[index]) + for (let ind = 0; ind < keys.length; ind++) { + if (updates[index][keys[ind]] !== originals[index][keys[ind]]) { + this.changesArr.push({ + ind: index, + field: keys[ind], + prop: updates[index][keys[ind]], + original: originals[index][keys[ind]] + }) + } + } + } + + this.lens = { + new: this.params?.NUM_ADDED || 0, + updated: this.params?.NUM_UPDATED || 0, + deleted: this.params?.NUM_DELETED || 0 + } + + let columns: Array = [] + let all = updates.concat(news, deleted) + + for (let index = 0; index < this.response.cols.length; index++) { + const element = this.response.cols[index].NAME + columns.push(element) + } + + // We need to limit lens in following calculation + // since actual data returned is limited to 100 rows + let added = + this.lens.new > this.recordsLimit ? this.recordsLimit : this.lens.new + let changed = + this.lens.updated > this.recordsLimit + ? this.recordsLimit + : this.lens.updated + let del = + this.lens.deleted > this.recordsLimit + ? this.recordsLimit + : this.lens.deleted + + if ( + this.lens.new > this.recordsLimit || + this.lens.updated > this.recordsLimit || + this.lens.deleted > this.recordsLimit + ) { + this.diffsLimit = true + } else { + this.diffsLimit = false + } + + this.addCount = added + let chArr: Array = [] + + let cols: Array = [] + for (let ind = 0; ind < columns.length; ind++) { + const element = columns[ind] + cols.push({ + data: element, + readOnly: true + // implement custom rendering + }) + } + this.diffTable.data = all + for (let index = 0; index < all.length; index++) { + const element = all[index] + let rowKey = Object.keys(element) + this.rowKeys.push(rowKey) + } + let arrChanged: Array = [] + let arrOfChanges: Array = [] + for (let index = 0; index < this.diffTable.data.length; index++) { + if (index < changed && changed !== 0) { + arrChanged.push([]) + arrOfChanges.push([]) + // if (index >= added && index < added + changed) { + chArr.push('updated') + let diffTableKeys = Object.keys(this.diffTable.data[index]) + for (let j = 0; j < diffTableKeys.length; j++) { + let currColumn = diffTableKeys[j] + if (originals[index][currColumn] !== updates[index][currColumn]) { + arrChanged[index].push(true) + arrOfChanges[index].push(originals[index][currColumn]) + } else { + arrChanged[index].push(false) + arrOfChanges[index].push(null) + } + } + this.arrChanged = arrChanged + this.arrOfChanges = arrOfChanges + } + if (index >= changed && index < changed + added) { + chArr.push('added') + } + if (index > added + changed - 1) { + chArr.push('deleted') + } + } + this.chArr = chArr + this.rowHeader = this.rowKeys[0] + this.diffTable.data = all + } + + async ngAfterViewInit() { + // submitted page + this._detailsSub = this.sasStoreService.submittDetail.subscribe( + async (allData: any) => { + this.subObj = allData.viewData + this.tableId = allData.viewData.tableId + + this.submitted = allData.viewData.sub + this.submitDetails = allData.data + this.submitArr = [] + for (let item in this.submitDetails) { + if (item !== 'sub') { + this.submitArr.push(item) + } + } + + let diffs = { + ACTION: 'SHOW_DIFFS', + TABLE: this.tableId, + DIFFTIME: new Date().toUTCString() + } + // show diffs and changes info in a same call + this.sasStoreService + .showDiffs(diffs, 'SASControlTable', 'auditors/postdata') + .then((res: AuditorsPostdataSASResponse) => { + let param = res.params[0] + this.params = param + this.response = res + this.calcDiff() + }) + .catch((err: any) => err) + .finally(() => { + this.loadingTable = true + }) + + this.callChangesInfo(this.tableId) + } + ) + if (typeof this.router.snapshot.params['tableId'] === 'undefined') { + return + } else { + this.tableId = this.router.snapshot.params['tableId'] + } + + let params = { + ACTION: 'SHOW_DIFFS', + TABLE: this.tableId, + DIFFTIME: new Date().toUTCString() + } + + // show diffs call and changes info both + this.sasStoreService + .showDiffs(params, 'SASControlTable', 'auditors/postdata') + .then((res: AuditorsPostdataSASResponse) => { + let param = res.params[0] + this.params = param + this.response = res + this.calcDiff() + }) + .catch((err: any) => { + this.acceptLoading = false + }) + .finally(() => { + this.loadingTable = true + this.setFocus() + }) + + this.callChangesInfo(this.tableId) + } + + ngOnDestroy() { + if (this._detailsSub) { + this._detailsSub.unsubscribe() + } + } + + private setFocus() { + setTimeout(() => { + let acceptBtn: any = window.document.getElementById('acceptBtn') + if (!!acceptBtn) { + acceptBtn.focus() + } + }, 200) + } +} diff --git a/client/src/app/approve/approve.component.html b/client/src/app/approve/approve.component.html new file mode 100644 index 0000000..5c3520b --- /dev/null +++ b/client/src/app/approve/approve.component.html @@ -0,0 +1,123 @@ +
+
+
+
+ +

There are no approvals remaining

+
+
+
+

+ REVIEW +

+

+ You have {{ remained }} approvals remaining +

+
+
+ Loading... +
+

Loading approvals list

+
+
+
+
+ + SUBMITTER + BASE TABLE + SUBMITTED + SUBMIT REASON + ACTION + DOWNLOAD + + + {{ approveItem.submitter }} + {{ approveItem.baseTable }} + {{ approveItem.submitted }} + {{ approveItem.submitReason }} + + + + + + + + + + items per page + + + {{ pagination.firstItem + 1 }} - {{ pagination.lastItem + 1 }} of + {{ pagination.totalItems }} approvals + + + +
+
+
+
diff --git a/client/src/app/approve/approve.component.scss b/client/src/app/approve/approve.component.scss new file mode 100644 index 0000000..8aa016c --- /dev/null +++ b/client/src/app/approve/approve.component.scss @@ -0,0 +1,41 @@ +.column-center { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.datagrid .datagrid-column .datagrid-column-title{ + outline: none!important; +} + +.links { + font-weight: 700;cursor: pointer; +} + +.tooltip.tooltip-bottom-left>.tooltip-content, .tooltip .tooltip-content.tooltip-bottom-left { + background: #314351!important; +} +.tooltip.tooltip-bottom-left>.tooltip-content:before, .tooltip .tooltip-content.tooltip-bottom-left:before { + border-right: .25rem solid #314351; + border-bottom: .20833rem solid #314351; +} + +.noBorder { + border-bottom: 1px solid transparent!important; +} + +.approvals-list-wrapper { + height: 70vh; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; +} + +.noapprovals-info-wrapper { + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + height: calc(100vh - 200px); +} \ No newline at end of file diff --git a/client/src/app/approve/approve.component.ts b/client/src/app/approve/approve.component.ts new file mode 100644 index 0000000..1899dff --- /dev/null +++ b/client/src/app/approve/approve.component.ts @@ -0,0 +1,129 @@ +import { Component, OnInit, ChangeDetectorRef } from '@angular/core' +import { SasStoreService } from '../services/sas-store.service' +import { Router } from '@angular/router' +import { SasService } from '../services/sas.service' +import { EventService } from '../services/event.service' + +interface ApproveData { + tableId: string + submitter: string + baseTable: string + submitted: string + submitReason: string + approver: string + rejectLoading?: boolean +} + +@Component({ + selector: 'app-approve', + templateUrl: './approve.component.html', + styleUrls: ['./approve.component.scss'], + host: { + class: 'content-container' + } +}) +export class ApproveComponent implements OnInit { + public approveList: Array | undefined + public remained: any + public tableId: any + public loaded: boolean = false + public itemsNum: number = 10 + + constructor( + private sasStoreService: SasStoreService, + private eventService: EventService, + private route: Router, + private sasService: SasService, + private cdr: ChangeDetectorRef + ) {} + + public getTable(table_id: any) { + this.route.navigateByUrl('/stage/' + table_id) + } + + public getClicked(ind: any) { + if (this.approveList !== undefined) { + this.tableId = this.approveList[ind].tableId + this.route.navigateByUrl( + 'approve/approveDet/' + this.approveList[ind].tableId + ) + } + } + + public async rejecting(ind: any) { + if (this.approveList !== undefined) { + this.tableId = this.approveList[ind].tableId + } + let rejParams = { + STP_ACTION: 'REJECT_TABLE', + TABLE: this.tableId, + STP_REASON: 'quick rejection' + } + try { + ;(this.approveList || [])[ind].rejectLoading = true + + let res = await this.sasStoreService.rejecting( + rejParams, + 'BrowserParams', + 'approvers/rejection' + ) + + if (res.fromsas[0].RESPONSE.includes('SUCCESS')) { + ;(this.approveList || [])[ind].rejectLoading = false + this.approveList?.splice(ind, 1) + this.remained-- + this.cdr.detectChanges() + } + } catch (error) { + this.eventService.catchResponseError('approvers/rejection', error) + } + } + + async ngOnInit() { + this.fetchApprovals() + } + + private async fetchApprovals() { + this.itemsNum = 10 + let myJsParams: any = {} + myJsParams.STP_ACTION = 'OPEN_APPROVALS' + + try { + let res = await this.sasStoreService.getApprovals( + myJsParams, + 'BrowserParams', + 'approvers/getapprovals' + ) + + this.remained = res.fromsas.length + let approveList: ApproveData[] = res.fromsas.map(function (item: any) { + return { + tableId: item.TABLE_ID, + submitter: item.SUBMITTED_BY_NM, + submitted: item.SUBMITTED_ON_DTTM, + baseTable: item.BASE_TABLE, + submitReason: item.SUBMITTED_REASON_TXT + } + }) + this.approveList = approveList + this.loaded = true + } catch (error) { + this.eventService.catchResponseError('approvers/getapprovals', error) + } + } + + public download(id: any) { + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = this.sasService.getExecutionPath() + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/auditors/getauditfile&table=' + + id + window.open(downUrl) + } +} diff --git a/client/src/app/deploy/deploy.component.html b/client/src/app/deploy/deploy.component.html new file mode 100644 index 0000000..7d158d3 --- /dev/null +++ b/client/src/app/deploy/deploy.component.html @@ -0,0 +1,100 @@ +
+
+ +
+
Terms and Conditions
+
+
+

+ The Demo version of Data Controller is free for EVALUATION purposes + only. Before proceeding with configuration, please confirm that you + have read, understood, and agreed to the + Data Controller for SAS© Evaluation Agreement. +

+
+ +
+ + + + + + + +
+
+
+ + + + +
+ +
+ +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+
+
diff --git a/client/src/app/deploy/deploy.component.scss b/client/src/app/deploy/deploy.component.scss new file mode 100644 index 0000000..354803e --- /dev/null +++ b/client/src/app/deploy/deploy.component.scss @@ -0,0 +1,50 @@ +.card { + margin-top: 0; +} + +.btn { + margin-top: 10px; +} + +.log-wrapper { + width: 100%; + background: #f0f0f0; + border: 1px solid #c9c9c9; + padding: 10px; + overflow: auto; + white-space: pre-wrap; +} + +#contexts-btn { + padding: 0; + min-width: 30px; + margin-left: 10px; + height: 30px; + display: inline-flex; + justify-content: center; + align-items: center; + padding-top: 3px; +} + +.validation-bar { + display: flex; + margin-top: 20px; + align-items: center; + + clr-icon { + margin-right: 5px; + } +} + +.autodeploy-section { + padding: 0px 15px; + + .clr-checkbox-wrapper { + margin: 20px 0 20px 0; + } + + .btn-autodeploy { + display: block; + margin: 15px 0 15px 0; + } +} \ No newline at end of file diff --git a/client/src/app/deploy/deploy.component.ts b/client/src/app/deploy/deploy.component.ts new file mode 100644 index 0000000..85cfbc7 --- /dev/null +++ b/client/src/app/deploy/deploy.component.ts @@ -0,0 +1,128 @@ +import { Component, OnInit } from '@angular/core' +import { SasService } from '../services/sas.service' +import { SASjsConfig } from '@sasjs/adapter' +import { Router } from '@angular/router' +import { LoggerService } from '../services/logger.service' +import { ServerType } from '@sasjs/utils/types/serverType' +import { AppStoreService } from '../services/app-store.service' +import { DcAdapterSettings } from '../models/DcAdapterSettings' + +@Component({ + selector: 'app-deploy', + templateUrl: './deploy.component.html', + styleUrls: ['./deploy.component.scss'], + host: { + class: 'content-container' + } +}) +export class DeployComponent implements OnInit { + public step: number = 0 + public adminGroups: any = [] + + public client_id: string = '' + public client_secret: string = '' + public appLoc: string = '' + public dcPath: string = '' + public selectedAdminGroup: string = '' + + public autodeploy: boolean = true + public jsonFile: any = null + + public sasJs: any + public sasJsConfig: SASjsConfig = new SASjsConfig() + + public dcAdapterSettings: DcAdapterSettings | undefined + + ServerType = ServerType + + constructor( + private appStoreService: AppStoreService, + private sasService: SasService, + private loggerService: LoggerService, + private router: Router + ) { + this.dcAdapterSettings = this.appStoreService.getDcAdapterSettings() + + if (this.router.url.includes('manualdeploy')) { + this.autodeploy = false + } + + this.sasJs = this.sasService.getSasjsInstance() + this.sasJsConfig = this.sasService.getSasjsConfig() + this.appLoc = this.dcAdapterSettings?.appLoc || '' + this.client_id = localStorage.getItem('deploy_client_id') || '' + this.client_secret = localStorage.getItem('deploy_secret_key') || '' + this.dcPath = localStorage.getItem('deploy_dc_loc') || '' + } + + ngOnInit() { + if (this.sasJsConfig.serverType === ServerType.SasViya) { + fetch('sasbuild/viya.json') + .then((res) => res.text()) + .then((res) => { + let initJsonFile: any = null + + try { + initJsonFile = JSON.parse(res) + } catch (err) { + console.error(err) + } + + if (initJsonFile) { + this.jsonFile = initJsonFile + this.loggerService.log(this.jsonFile) + } + }) + } + + this.setDeployDefaults() + } + + public setDeployDefaults() { + this.dcPath = this.dcAdapterSettings?.dcPath || '' + this.selectedAdminGroup = this.dcAdapterSettings?.adminGroup || '' + if (!this.selectedAdminGroup) { + this.selectedAdminGroup = 'SASAdministrators' + } + } + + public termsAgreeChange() { + if (!this.autodeploy) { + this.getAdminGroups() + } + + this.step++ + } + + public getAdminGroups() { + fetch( + this.sasJsConfig.serverUrl + '/identities/groups?sortBy=name&limit=5000', + { + headers: { + Accept: 'application/json' + } + } + ) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes + + try { + jsonRes = JSON.parse(res) + } catch (err: any) { + console.error(err) + } + + if (jsonRes) { + this.adminGroups = jsonRes.items + this.selectedAdminGroup = this.adminGroups[0].id + } + }) + } + + public onNavigateToHome() { + window.open(location.href.split('#')[0], '_blank') + } +} diff --git a/client/src/app/deploy/sections/automatic/automatic.component.html b/client/src/app/deploy/sections/automatic/automatic.component.html new file mode 100644 index 0000000..440ef0e --- /dev/null +++ b/client/src/app/deploy/sections/automatic/automatic.component.html @@ -0,0 +1,169 @@ +
+
+ + Loading... +

Deploying...

+
+ + +

Done

+
+ +
+ + +

Deploy SAS Jobs

+
+ +
+ + +

Create database

+
+ +
+ +
+ + + +
+ +
+ +
+ + + +
+
+
+
+ +

Viya Deploy

+
+ +
+
+

{{ appLoc }}

+
+
+ + +
+
+

{{ dcPath }}

+
+
+ + +
+
+

{{ selectedAdminGroup }}

+
+
+ + + + + + +
+ + + + + + + + + + + diff --git a/client/src/app/deploy/sections/automatic/automatic.component.scss b/client/src/app/deploy/sections/automatic/automatic.component.scss new file mode 100644 index 0000000..128d32b --- /dev/null +++ b/client/src/app/deploy/sections/automatic/automatic.component.scss @@ -0,0 +1,61 @@ +.auto-deploy { + display: flex; + justify-content: center; + align-items: center; + + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.4); + + z-index: 100; +} + +.spinner-box { + width: 400px; + padding: 20px; + border-radius: 3px; + background: #fff; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + box-shadow: 1px 1px 8px 0px #00000082; + + .buttons { + display: flex; + justify-content: space-between; + width: 100%; + } +} + +.deploy-status-row { + display: flex; + align-items: center; + align-self: flex-start; + + p { + margin: 0 0 0 10px; + } +} + +.deploy-success { + color: #6ECF44; +} + +.deploy-error { + color: #E74C3C; + // width: 20px; + // height: 20px; +} + +.deploy-undeterminated { + color: #cacaca; +} + +hr { + border: 0; + border-bottom: 1px solid #00000045; +} \ No newline at end of file diff --git a/client/src/app/deploy/sections/automatic/automatic.component.ts b/client/src/app/deploy/sections/automatic/automatic.component.ts new file mode 100644 index 0000000..167ce02 --- /dev/null +++ b/client/src/app/deploy/sections/automatic/automatic.component.ts @@ -0,0 +1,185 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import SASjs, { SASjsConfig } from '@sasjs/adapter' +import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' +import { DeployService } from 'src/app/services/deploy.service' +import { EventService } from 'src/app/services/event.service' +import { LoggerService } from 'src/app/services/logger.service' +import { SasService } from 'src/app/services/sas.service' + +@Component({ + selector: 'app-automatic-deploy', + templateUrl: './automatic.component.html', + styleUrls: ['./automatic.component.scss'] +}) +export class AutomaticComponent implements OnInit { + @Input() sasJs!: SASjs + @Input() sasJsConfig: SASjsConfig = new SASjsConfig() + @Input() dcAdapterSettings: DcAdapterSettings | undefined + @Input() appLoc: string = '' + @Input() dcPath: string = '' + @Input() selectedAdminGroup: string = '' + + @Output() onNavigateToHome: EventEmitter = new EventEmitter() + + public makeDataResponse: string = '' + public jsonFile: any = null + public autodeploying: boolean = false + public autodeployDone: boolean = false + public recreateDatabaseModal: boolean = false + public isSubmittingJson: boolean = false + public isJsonSubmitted: boolean = false + public recreateDatabase: boolean = false + public createDatabaseLoading: boolean = false + + /** autoDeployStatus + * This object presents the status for two steps that we have for deploy. + * `deployServicePack` - Creating services based on `viya.json` + * `runMakeData` - Running `makedata` service + * If any of them is `null` or `false` that means step failed + * and will be shown to user on deploy done modal. + */ + public autoDeployStatus: { + deployServicePack: any + runMakeData: any + } = { + deployServicePack: null, + runMakeData: null + } + + constructor( + private eventService: EventService, + private deployService: DeployService, + private sasService: SasService, + private loggerService: LoggerService + ) {} + + ngOnInit(): void {} + + public async executeJson() { + this.autodeploying = true + this.isSubmittingJson = true + + try { + let uploadJsonFile = await this.sasJs.deployServicePack( + this.jsonFile, + this.dcAdapterSettings?.appLoc, + undefined, + undefined, + true + ) + + this.autoDeployStatus.deployServicePack = true + this.isJsonSubmitted = true + } catch (ex: any) { + let textEx = '' + + if (typeof ex.message !== 'string') { + textEx = JSON.stringify(ex).replace(/\\/gm, '') + } else { + textEx = ex.message + } + + this.autoDeployStatus.deployServicePack = false + this.eventService.showInfoModal( + 'Deploy error', + `Exception: \n ${textEx !== '' ? textEx : ex}` + ) + this.autodeploying = false + this.autodeployDone = false + + return + } + + this.isSubmittingJson = false + + if (this.recreateDatabase) { + this.createDatabase() + } else { + this.autodeployDone = true + } + } + + public createDatabase() { + let data = { + fromjs: [ + { + ADMIN: this.selectedAdminGroup, + DCPATH: this.dcPath + } + ] + } + + /** + * We are overriding default `sasjsConfig` object fields with this object fields. + * Here we want to run this request using original WEB method. + * contextName: null is the MUST field for it. + */ + let overrideConfig = { + useComputeApi: false, + contextName: this.sasJsConfig.contextName, + debug: true + } + + this.sasJs + .request(`services/admin/makedata`, data, overrideConfig, () => { + this.sasService.shouldLogin.next(true) + }) + .then((res: any) => { + this.autodeployDone = true + + try { + this.makeDataResponse = JSON.stringify(res) + } catch { + this.makeDataResponse = res + } + + if (res.result && res.result.length > 0) { + this.autoDeployStatus.runMakeData = true + } else { + this.autoDeployStatus.runMakeData = false + } + }) + .catch((err: any) => { + this.autoDeployStatus.runMakeData = false + this.autodeployDone = true + + try { + this.makeDataResponse = JSON.stringify(err) + } catch { + this.makeDataResponse = err + } + }) + } + + public downloadFile( + content: any, + filename: string, + extension: string = 'txt' + ) { + this.deployService.downloadFile(content, filename, extension) + } + + public async onJsonFileChange(event: any) { + let file = event.target.files[0] + + this.jsonFile = await this.deployService.readFile(file) + } + + public recreateDatabaseClicked(event: Event) { + ;(event.target).checked === true + ? (this.recreateDatabaseModal = true) + : '' + } + + public clearUploadInput(event: Event) { + this.deployService.clearUploadInput(event) + } + + public openSasRequestsModal() { + this.eventService.openRequestsModal() + } + + public navigateToHome() { + this.onNavigateToHome.emit() + } +} diff --git a/client/src/app/deploy/sections/manual/manual.component.html b/client/src/app/deploy/sections/manual/manual.component.html new file mode 100644 index 0000000..8bd776a --- /dev/null +++ b/client/src/app/deploy/sections/manual/manual.component.html @@ -0,0 +1,247 @@ +
+ Configurator +

App Location: {{ appLoc }}

+ +
+
+ + +
+

Please log in first

+ +
+
+ +
+
+ + +
+
+ +
+
+ + +
+ + +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ + Loading contexts... + + Loading contexts... +
+ + +
+
+ +
+
+ +

+ Select JSON file to upload (json build file preloaded): +

+
+ + +
+ +
+ + JSON Submitted Successfully + + +
+ +

Select SAS file to upload:

+
+ + +
+ +
+ + + +
+
+ + +

File execute completed

+
+ +
+ +
+
+ + + + +

Create Database Completed

+
+ +
+ {{ makeDataResponse }} +
+ + + + + + + +
+ + + Validating deploy... + + Validating deploy... + + + + + Validation failed + + + + + Validation succeeded + +
+
+
+
+
diff --git a/client/src/app/deploy/sections/manual/manual.component.scss b/client/src/app/deploy/sections/manual/manual.component.scss new file mode 100644 index 0000000..ec07a61 --- /dev/null +++ b/client/src/app/deploy/sections/manual/manual.component.scss @@ -0,0 +1,4 @@ +.clear-memory-button { + right: 10px; + top: 2px; +} \ No newline at end of file diff --git a/client/src/app/deploy/sections/manual/manual.component.ts b/client/src/app/deploy/sections/manual/manual.component.ts new file mode 100644 index 0000000..0def16c --- /dev/null +++ b/client/src/app/deploy/sections/manual/manual.component.ts @@ -0,0 +1,291 @@ +import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core' +import SASjs, { SASjsConfig } from '@sasjs/adapter' +import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' +import { DeployService } from 'src/app/services/deploy.service' +import { EventService } from 'src/app/services/event.service' +import { LoggerService } from 'src/app/services/logger.service' +import { SasService } from 'src/app/services/sas.service' + +@Component({ + selector: 'app-manual-deploy', + templateUrl: './manual.component.html', + styleUrls: ['./manual.component.scss'] +}) +export class ManualComponent implements OnInit { + @Input() sasJs!: SASjs + @Input() sasJsConfig: SASjsConfig = new SASjsConfig() + @Input() dcAdapterSettings: DcAdapterSettings | undefined + + @Output() onNavigateToHome: EventEmitter = new EventEmitter() + + public needsLogin: boolean = false + public adminGroups: any = [] + public allContexts: any = [] + + public appLoc: string = '' + public dcPath: string = '' + public selectedAdminGroup: string = '' + public selectedContext: string = '' + public jobLog: string = '' + public makeDataResponse: string = '' + public linesOfCode: any = [] + public fileName: string = '' + public preloadedFile: boolean = true + public executeSASEnabled: boolean = false + + public contextsLoading: boolean = false + public createDatabaseLoading: boolean = false + public executingScript: boolean = false + public downloadFileBtn: boolean = false + public isValidating: boolean = false + public jsonFile: any = null + public isSubmittingJson: boolean = false + public isJsonSubmitted: boolean = false + public validationState: string = 'none' + + constructor( + private sasService: SasService, + private eventService: EventService, + private loggerService: LoggerService, + private deployService: DeployService + ) {} + + ngOnInit(): void {} + + public async executableContext() { + // getExecutableContexts now need AuthConfig parameter which we don't have on web + // this.contextsLoading = true + // let contexts = await this.sasJs.getExecutableContexts() + // this.allContexts = contexts + // if (contexts.length === 0) { + // this.selectedContext = '' + // } else { + // this.selectedContext = this.allContexts[0].name + // } + // this.contextsLoading = false + } + + public clearUploadInput(event: Event) { + this.deployService.clearUploadInput(event) + } + + public onSasFileChange(event: any) { + this.preloadedFile = false + + let file = event.target.files[0] + this.fileName = file.name + + let fileReader = new FileReader() + + fileReader.onload = () => { + if (fileReader.result) { + this.linesOfCode = (fileReader.result as string).split('\n') + this.linesOfCode = this.linesOfCode.filter((el: string) => { + return el !== '' && el !== null + }) + + this.executeSASEnabled = true + + this.addPrecodeLines() + } + } + + fileReader.readAsText(file) + } + + public async onJsonFileChange(event: any) { + let file = event.target.files[0] + + this.jsonFile = await this.deployService.readFile(file) + } + + public addPrecodeLines() { + let headerLines = [ + `%let context=${this.selectedContext};`, + `%let appLoc=${this.appLoc};`, + `%let admin=${this.selectedAdminGroup};`, + `%let dcpath=${this.dcPath};` + ] + + this.linesOfCode.unshift(...headerLines) + } + + public downloadSasPrecodeFile() { + let linesAsText = this.linesOfCode.join('\n') + let filename = this.fileName.split('.')[0] + + this.downloadFile(linesAsText, filename, 'sas') + } + + public downloadFile( + content: any, + filename: string, + extension: string = 'txt' + ) { + this.deployService.downloadFile(content, filename, extension) + } + + public saveDcPath() { + localStorage.setItem('deploy_dc_loc', this.dcPath) + } + + public async executeJson() { + this.isSubmittingJson = true + + try { + let uploadJsonFile = await this.sasJs.deployServicePack( + this.jsonFile, + this.dcAdapterSettings?.appLoc || '', + undefined, + undefined, + true + ) + + this.isJsonSubmitted = true + } catch (ex: any) { + let textEx = '' + + if (typeof ex.message !== 'string') { + textEx = JSON.stringify(ex).replace(/\\/gm, '') + } else { + textEx = ex.message + } + + this.eventService.showInfoModal( + 'Deploy error', + `Exception: \n ${textEx !== '' ? textEx : ex}` + ) + + return + } + + this.isSubmittingJson = false + } + + public async executeSAS() { + this.executingScript = true + this.jobLog = '' + this.makeDataResponse = '' + + try { + let executeResponse = await this.sasJs.executeScript({ + fileName: this.fileName, + linesOfCode: this.linesOfCode, + contextName: this.selectedContext + }) + + this.loggerService.log(executeResponse) + + if (typeof executeResponse.log === 'string') { + executeResponse.log = JSON.parse(executeResponse.log) + } + + if (executeResponse.jobStatus === 'error') { + alert('Error!') + } else { + this.jobLog = executeResponse.log.items + ? executeResponse.log.items.map((i: any) => i.line).join('\n') + : JSON.stringify(executeResponse.log) + } + + this.executingScript = false + } catch (err) { + this.executingScript = false + } + } + + public createDatabase(newTab: boolean = true) { + if (newTab) { + let url = + this.sasService.getSasjsConfig().serverUrl + + '/SASJobExecution/?_program=' + + this.dcAdapterSettings?.appLoc || + '' + + '/admin/makedata' + + '&ADMIN=' + + this.selectedAdminGroup + + '&DCPATH=' + + this.dcPath + + '&_debug=131' + + window.open(url, '_blank') + + return + } + + this.createDatabaseLoading = true + + let data = { + fromjs: [ + { + ADMIN: this.selectedAdminGroup, + DCPATH: this.dcPath + } + ] + } + + /** + * We are overriding default `sasjsConfig` object fields with this object fields. + * Here we want to run this request using original WEB method. + * contextName: null is the MUST field for it. + */ + let overrideConfig = { + useComputeApi: false, + contextName: this.sasJsConfig.contextName, + debug: true + } + + this.sasJs + .request(`services/admin/makedata`, data, overrideConfig, () => { + this.sasService.shouldLogin.next(true) + }) + .then((res: any) => { + try { + this.makeDataResponse = JSON.stringify(res) + } catch { + this.makeDataResponse = res + } + + this.createDatabaseLoading = false + }) + .catch((err: any) => { + this.createDatabaseLoading = false + + try { + this.makeDataResponse = JSON.stringify(err) + } catch { + this.makeDataResponse = err + } + }) + } + + public navigateToHome() { + this.onNavigateToHome.emit() + } + + public validateDeploy() { + this.isValidating = true + + this.sasService + .request('public/startupservice', null) + .then((res: any) => { + this.loggerService.log(res) + + if (res.saslibs) { + this.validationState = 'success' + } else { + this.validationState = 'error' + } + + this.isValidating = false + }) + .catch((err: any) => { + this.isValidating = false + this.validationState = 'error' + }) + } + + public deleteKeys() { + localStorage.removeItem('deploy_dc_loc') + } +} diff --git a/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.html b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.html new file mode 100644 index 0000000..059cad4 --- /dev/null +++ b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.html @@ -0,0 +1,76 @@ +
+ +
+ +

Sasjs Deploy

+
+ +

+ To configure Data Controller for SAS©, please provide the following details: +

+ +

+ Please specify a physical directory below, to which user + {{ SYSUSERID }} can write, on behalf of Data Controller: +

+ + +
+
+ +
+ + +
+ +

+ Below are the list of groups to which you belong. The group you select will + become the Data Controller Admin Group, and everyone in it will have + unrestricted access to Data Controller. +

+ + + + + + +

+ Now, create the target directory and deploy the control library using the + admin group selected above: +

+ +
+ +
+ +
+ +
+

You are connected with the following credentials:

+
    +
  • METAPERSON: {{ METAPERSON }}
  • +
  • SYSUSERID: {{ SYSUSERID }}
  • +
  • SYSHOSTNAME: {{ SYSHOSTNAME }}
  • +
  • SYSVLONG: {{ SYSVLONG }}
  • +
+
diff --git a/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.scss b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.scss new file mode 100644 index 0000000..47957ba --- /dev/null +++ b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.scss @@ -0,0 +1,23 @@ +.clr-control-container { + width: 50vw; +} + +.clr-input-wrapper { + width: 100%; + + input { + width: 100%; + } +} + +.thinProgress { + left: 0px; + right: 0; + width: unset; + height: 1px; + margin-top: 0 !important; + + &::after { + top: 0; + } +} \ No newline at end of file diff --git a/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.ts b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.ts new file mode 100644 index 0000000..f0b6970 --- /dev/null +++ b/client/src/app/deploy/sections/sasjs-configurator/sasjs-configurator.component.ts @@ -0,0 +1,136 @@ +import { Location } from '@angular/common' +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import SASjs, { SASjsConfig } from '@sasjs/adapter' +import { ServerType } from '@sasjs/utils/types/serverType' +import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' +import { SASGroup } from 'src/app/models/sas/public-getgroups.model' +import { SASjsApiServerInfo } from 'src/app/models/sasjs-api/SASjsApiServerInfo.model' +import { HelperService } from 'src/app/services/helper.service' +import { SasService } from 'src/app/services/sas.service' +import { SasjsService } from 'src/app/services/sasjs.service' + +@Component({ + selector: 'app-sasjs-configurator', + templateUrl: './sasjs-configurator.component.html', + styleUrls: ['./sasjs-configurator.component.scss'] +}) +export class SasjsConfiguratorComponent implements OnInit { + @Input() sasJs!: SASjs + @Input() sasJsConfig: SASjsConfig = new SASjsConfig() + @Input() dcAdapterSettings: DcAdapterSettings | undefined + + @Output() onNavigateToHome: EventEmitter = new EventEmitter() + + dcDirectory: string = '' + dcAdminGroup: string = 'DCDEFAULT' + + METAPERSON: string = 'n/a' + METAUSER: string = 'n/a' + SYSUSERID: string = 'n/a' + SYSHOSTNAME: string = 'n/a' + SYSVLONG: string = 'n/a' + + dcAdminGroupList: SASGroup[] = [] + + loading: boolean = false + showLogout: boolean = false + + tmpDirectories = { + linux: '/tmp/DataController', + windows: 'C:\\DataController' + } + + constructor( + private sasService: SasService, + private sasjsService: SasjsService, + private location: Location + ) {} + + ngOnInit(): void { + this.getUserGroups() + this.getServerInfo() + } + + getServerInfo() { + this.sasjsService + .getServerInfo() + .subscribe((serverInfo: SASjsApiServerInfo) => { + if (serverInfo.mode !== 'desktop') this.showLogout = true + }) + } + + getUserGroups() { + this.loading = true + + this.sasService.request('usernav/usergroupsbymember', null).then( + (res: any) => { + this.METAPERSON = res.MF_GETUSER + this.SYSUSERID = res.SYSUSERID + this.SYSHOSTNAME = res.SYSHOSTNAME + this.SYSVLONG = res.SYSVLONG + + /* + We would like to present a default DCPATH (deployment path) to the + user who is installing Data Controller. This path should be + appropriate to the server type, ie windows or linux. + We can use the SYSSCPL variable from the service response above, and + derive the OS based on the first letter. + + The list of values is available here: + + https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/mcrolref/n0e7s8lf147kazn17u45trpwb6sw.htm + + */ + this.dcDirectory = + this.tmpDirectories[ + ['L', 'H', 'A', 'S'].includes(res.SYSSCPL.substring(0, 1)) + ? 'linux' + : 'windows' + ] + + this.dcAdminGroupList = res.groups + this.dcAdminGroup = this.dcAdminGroupList[0].GROUPNAME + + this.loading = false + }, + (err: any) => { + this.loading = false + } + ) + } + + makeData() { + // const _debug = "&_debug=131"; //debug on + const _debug = ' ' //debug off + + let executor = this.sasService.getExecutionPath() + const root = this.sasJsConfig.appLoc + let serverUrl = this.sasJsConfig.serverUrl + let dcDirectory = this.dcDirectory + + if (this.sasJsConfig.serverType === ServerType.Sasjs) { + this.sasService.sasjsMakedataChecking().then((success: boolean) => { + if (!!success) { + this.location.replaceState('/') + location.reload() + } + }) + } else if (this.sasJsConfig.serverType === ServerType.Sas9) { + serverUrl = '' + executor = window.location.origin + executor + '/' + dcDirectory = encodeURIComponent(this.dcDirectory) + } + + const url = `${ + serverUrl ? serverUrl : '' + }${executor}?_program=${root}/services/admin/makedata&admin=${ + this.dcAdminGroup + }&path=${dcDirectory}${_debug}` + + window.open(url, '_blank') + } + + logout() { + this.sasService.logout() + } +} diff --git a/client/src/app/directives/directives.module.ts b/client/src/app/directives/directives.module.ts new file mode 100644 index 0000000..c919ee0 --- /dev/null +++ b/client/src/app/directives/directives.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { NgVarDirective } from './ng-var.directive' +import { DragNdropDirective } from './drag-ndrop.directive' +import { FileDropDirective } from './file-drop.directive' +import { FileSelectDirective } from './file-select.directive' + +@NgModule({ + declarations: [ + NgVarDirective, + DragNdropDirective, + FileDropDirective, + FileSelectDirective + ], + imports: [CommonModule], + exports: [ + NgVarDirective, + DragNdropDirective, + FileDropDirective, + FileSelectDirective + ] +}) +export class DirectivesModule {} diff --git a/client/src/app/directives/drag-ndrop.directive.ts b/client/src/app/directives/drag-ndrop.directive.ts new file mode 100644 index 0000000..24926d9 --- /dev/null +++ b/client/src/app/directives/drag-ndrop.directive.ts @@ -0,0 +1,60 @@ +import { + Directive, + HostBinding, + Output, + EventEmitter, + HostListener +} from '@angular/core' + +@Directive({ + selector: '[appDragNdrop]' +}) +export class DragNdropDirective { + @HostBinding('class.fileover') fileOver: boolean = false + @Output() fileDropped = new EventEmitter() + @Output() fileDraggedOver = new EventEmitter() + + // Dragover listener + @HostListener('dragover', ['$event']) + onDragOver(event: any) { + event.preventDefault() + event.stopPropagation() + + if (this.containsFiles(event) && !this.fileOver) { + this.fileOver = true + this.fileDraggedOver.emit() + } + } + + // Dragleave listener + @HostListener('dragleave', ['$event']) + public onDragLeave(event: any) { + event.preventDefault() + event.stopPropagation() + this.fileOver = false + } + + // Drop listener + @HostListener('drop', ['$event']) + public ondrop(event: any) { + event.preventDefault() + event.stopPropagation() + this.fileOver = false + + const files = event.dataTransfer.files + + if (files.length > 0) { + this.fileDropped.emit(files) + } + } + + private containsFiles(event: any) { + if (event && event.dataTransfer && event.dataTransfer.types) { + for (let i = 0; i < event.dataTransfer.types.length; i++) { + if (event.dataTransfer.types[i] == 'Files') { + return true + } + } + } + } +} diff --git a/client/src/app/directives/file-drop.directive.ts b/client/src/app/directives/file-drop.directive.ts new file mode 100644 index 0000000..056501a --- /dev/null +++ b/client/src/app/directives/file-drop.directive.ts @@ -0,0 +1,66 @@ +import { + Directive, + EventEmitter, + ElementRef, + HostListener, + Input, + Output +} from '@angular/core' +import { FileUploader } from '../models/FileUploader.class' + +@Directive({ + selector: '[appFileDrop]' +}) +export class FileDropDirective { + @Input() uploader?: FileUploader + @Output() fileOver: EventEmitter = new EventEmitter() + @Output() fileDrop: EventEmitter = new EventEmitter() + + protected element: ElementRef + + constructor(element: ElementRef) { + this.element = element + } + + @HostListener('drop', ['$event']) + onDrop(event: DragEvent): void { + this._preventAndStop(event) + const files = event.dataTransfer?.files + const fileList: File[] = [] + + if (files) { + for (let i = 0; i < files.length; i++) { + fileList.push(files[i]) + } + } + + this.uploader?.addToQueue(fileList) + this.fileOver.emit(false) + this.fileDrop.emit(fileList) + } + + @HostListener('dragover', ['$event']) + onDragOver(event: DragEvent): void { + this._preventAndStop(event) + + const transfer = event.dataTransfer + if (transfer) { + if (transfer.types.indexOf('Files') === -1) return + + transfer.dropEffect = 'copy' + } + + this.fileOver.emit(true) + } + + @HostListener('dragleave', ['$event']) + onDragLeave(event: DragEvent): void { + this._preventAndStop(event) + this.fileOver.emit(false) + } + + protected _preventAndStop(event: MouseEvent): void { + event.preventDefault() + event.stopPropagation() + } +} diff --git a/client/src/app/directives/file-select.directive.ts b/client/src/app/directives/file-select.directive.ts new file mode 100644 index 0000000..acf20ef --- /dev/null +++ b/client/src/app/directives/file-select.directive.ts @@ -0,0 +1,39 @@ +import { + Directive, + EventEmitter, + ElementRef, + Input, + HostListener, + Output +} from '@angular/core' +import { FileUploader } from '../models/FileUploader.class' + +@Directive({ + selector: '[appFileSelect]' +}) +export class FileSelectDirective { + @Input() uploader?: FileUploader + @Output() fileSelected: EventEmitter = new EventEmitter() + + protected element: ElementRef + + constructor(element: ElementRef) { + this.element = element + } + + isEmptyAfterSelection(): boolean { + return !!this.element.nativeElement.attributes.multiple + } + + @HostListener('change') + onChange(): void { + const files = this.element.nativeElement.files + + this.uploader?.addToQueue(files) + + this.fileSelected.emit(files) + if (this.isEmptyAfterSelection()) { + this.element.nativeElement.value = '' + } + } +} diff --git a/client/src/app/directives/ng-var.directive.ts b/client/src/app/directives/ng-var.directive.ts new file mode 100644 index 0000000..7a50ad0 --- /dev/null +++ b/client/src/app/directives/ng-var.directive.ts @@ -0,0 +1,36 @@ +import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core' + +/** + * Purpose of this directive is ability to declare variables in html. + * It helps writing cleaner code and prevents us from calling function is html + * Calling functions in html is bad for performance + */ +@Directive({ + selector: '[ngVar]' +}) +export class NgVarDirective { + @Input() + set ngVar(context: unknown) { + this.context.$implicit = this.context.ngVar = context + + if (!this.hasView) { + this.vcRef.createEmbeddedView(this.templateRef, this.context) + this.hasView = true + } + } + + private context: { + $implicit: unknown + ngVar: unknown + } = { + $implicit: null, + ngVar: null + } + + private hasView: boolean = false + + constructor( + private templateRef: TemplateRef, + private vcRef: ViewContainerRef + ) {} +} diff --git a/client/src/app/editor/RowValidation.ts b/client/src/app/editor/RowValidation.ts new file mode 100644 index 0000000..a213603 --- /dev/null +++ b/client/src/app/editor/RowValidation.ts @@ -0,0 +1,7 @@ +export interface RowValidation { + valid: boolean + invalidError: string + rowNumber?: number + colName?: string + value?: string +} diff --git a/client/src/app/editor/components/edit-record/edit-record.component.html b/client/src/app/editor/components/edit-record/edit-record.component.html new file mode 100644 index 0000000..9770463 --- /dev/null +++ b/client/src/app/editor/components/edit-record/edit-record.component.html @@ -0,0 +1,339 @@ + + + + + + + +
+ + + +
+ + + +
+
diff --git a/client/src/app/editor/components/edit-record/edit-record.component.scss b/client/src/app/editor/components/edit-record/edit-record.component.scss new file mode 100644 index 0000000..e4bd4c9 --- /dev/null +++ b/client/src/app/editor/components/edit-record/edit-record.component.scss @@ -0,0 +1,241 @@ +.record-edit-modal { + .column-entry { + display: flex; + justify-content: space-between; + .name-input-row { + width: 100%; + max-width: 260px; + + .cell-desc { + margin-right: 30px; + margin-top: 10px; + } + } + + .inputs-wrapper { + flex: 1; + display: flex; + align-items: center; + + ::ng-deep >*:not(.date-field):not(clr-select-container) { + flex: 1; + } + } + + p { + margin-top: 0px; + } + + ::ng-deep { + .clr-textarea-wrapper { + margin-top: 0 !important; + } + + .clr-form-control { + margin-top: 0px !important; + } + + app-soft-select { + display: block; + width: 224px; + background: #fff; + border: 1px solid #999; + color: #000; + padding: calc(.25rem + 2px) .5rem; + border-radius: .125rem; + font-size: .541667rem; + margin-right: 6px; + + input { + width: 100%; + border: 0; + background-color: #fff; + + &:focus { + background: none; + border: 0 !important; + } + + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + } + } + } + + &:first-child p:first-child { + margin-top: 0; + } + } + + .date-field { + position: relative; + display: inline-block; + + textarea { + width: 230px; + } + + .date-picker { + position: absolute; + right: 0; + top: 4px; + + ::ng-deep { + // clr-datepicker-view-manager { + // transform: unset !important; + // left: unset !important; + // right: 70px !important; + // } + .clr-input-group { + border: 0 !important; + } + } + } + } + + .modal-body { + padding-bottom: 10px; + } + + ::ng-deep { + clr-select-container { + border: 1px solid #999; + color: #000; + border-radius: .125rem; + margin-right: 5px; + + .clr-select-wrapper { + max-height: unset; + + &::after { + top: 15px; + } + } + + select { + height: auto; + padding: 10px; + padding-right: 20px; + border: 0 !important; + + &:focus { + background: 0 0 !important; + } + &:hover { + background: transparent; + } + } + } + + clr-input-container { + width: 224px; + background: #fff; + border: 1px solid #999; + color: #000; + padding: calc(.25rem + 2px) .5rem; + border-radius: .125rem; + font-size: .541667rem; + margin-right: 6px; + + input { + width: 100%; + border: 0; + + &:focus { + background: none; + border: 0 !important; + } + + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + } + + &.invalid-data { + border-color: red; + } + } + + .modal-dialog { + width: 80vw; + } + + .clr-control-container { + width: 100%; + + textarea { + width: 100%; + resize: none; + border-color: #999; + + &.invalid-data { + border-color: red; + outline: 0; + } + + &.not-char { + font-family: "Lucida Console", Monaco, monospace; + } + } + } + + .generate-record-url { + right: 40px; + top: 40px; + font-size: 12px; + } + + .generate-record-url-button { + right: 25px; + top: 5px; + } + + .modal-header { + padding: 0 0 1rem 0; + } + + .modal-footer { + display: flex; + align-items: center; + justify-content: space-between; + + // height: 65px; + + .alert { + margin: 0; + } + } + } +} + +.prev-next { + display: flex; + align-items: center; + + p { + margin: 0; + } + + button { + margin: 0px 10px; + } +} + +.focusable { + &:focus { + box-shadow: 0 0 3px 0px #5aa220; + } +} + +.entry-input-left-offset { + left: -30px; +} + +.validation-info-alert { + width: 310px +} \ No newline at end of file diff --git a/client/src/app/editor/components/edit-record/edit-record.component.ts b/client/src/app/editor/components/edit-record/edit-record.component.ts new file mode 100644 index 0000000..63a4784 --- /dev/null +++ b/client/src/app/editor/components/edit-record/edit-record.component.ts @@ -0,0 +1,242 @@ +import { KeyValue } from '@angular/common' +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import moment from 'moment' +import { ValidateFilterSASResponse } from 'src/app/models/sas/validate-filter.model' +import { QueryClause } from 'src/app/models/TableData' +import { HelperService } from 'src/app/services/helper.service' +import { SasStoreService } from 'src/app/services/sas-store.service' +import { DcValidator } from 'src/app/shared/dc-validator/dc-validator' +import { DcValidation } from 'src/app/shared/dc-validator/models/dc-validation.model' +import { + EditRecordDropdownChangeEvent, + EditRecordInputFocusedEvent +} from '../../models/edit-record/edit-record-events' +import { EditRecordModal } from '../../models/EditRecordModal' + +@Component({ + selector: 'app-edit-record', + templateUrl: './edit-record.component.html', + styleUrls: ['./edit-record.component.scss'] +}) +export class EditRecordComponent implements OnInit { + @Input() currentRecord!: EditRecordModal + @Input() recordAction: string | null = null + @Input() libds: string | undefined + @Input() queryFilter: any + @Input() filter: boolean = false + @Input() submitLoading: boolean = false + @Input() headerPks: string[] = [] + @Input() cellValidation: DcValidation[] = [] + @Input() currentRecordIndex: number = -1 + @Input() currentRecordLoadings: number[] = [] + @Input() currentRecordErrors: number[] = [] + @Input() currentRecordValidator: DcValidator | undefined + + @Output() onRecordChange: EventEmitter = + new EventEmitter() + @Output() onRecordInputFocused: EventEmitter = + new EventEmitter() + @Output() + onRecordDropdownChanged: EventEmitter = + new EventEmitter() + @Output() onRecordEditClose: EventEmitter = new EventEmitter() + @Output() onRecordEditConfirm: EventEmitter = new EventEmitter() + @Output() onNextRecord: EventEmitter = new EventEmitter() + @Output() onPreviousRecord: EventEmitter = new EventEmitter() + + public currentRecordInvalidCols: string[] = [] + public generateEditRecordUrlLoading: boolean = false + public generatedRecordUrl: string | null = null + public addRecordUrl: string | null = null + public recordNewOrPkModified: boolean = false + public addRecordLoading: boolean = false + public validatorTimeout: any + + constructor( + private sasStoreService: SasStoreService, + private helperService: HelperService + ) {} + + ngOnInit(): void {} + + async validateRecordCol( + cellValidation: any, + cellValue: any + ): Promise { + return new Promise((resolve, reject) => { + this.currentRecordValidator?.executeHotValidator( + cellValidation, + cellValue, + (valid: boolean) => { + resolve(valid) + } + ) + }) + } + + recordDateChange(date: Date, colKey: string) { + let cellValidation = this.currentRecordValidator?.getRule(colKey) + let format = cellValidation ? cellValidation.dateFormat : '' + + if (this.currentRecord) + this.currentRecord[colKey] = moment(date).format(format) + } + + isRecordModalInvalid(): boolean { + return this.currentRecordInvalidCols.length > 0 + } + + confirmRecordEdit() { + if (this.currentRecordInvalidCols.length < 1) { + this.onRecordChange.emit(this.currentRecord) + } + } + + closeRecordEdit() { + this.onRecordEditClose.emit() + } + + onRecordDropdownChange(colName: string, col: number) { + this.onRecordDropdownChanged.emit({ colName, col }) + } + + onRecordInputFocus(event: any, colName: number) { + this.onRecordInputFocused.emit({ event, colName }) + } + + recordInputPaste(event: any) { + setTimeout(() => { + //Trim space at the end + event.target.value = event.target.value.replace(/\s+$/, '') + }, 0) + } + + async recordInputChange(event: any, colName: string) { + const colRules = this.currentRecordValidator?.getRule(colName) + const value = event.target.value + + this.helperService.debounceCall(300, () => { + this.validateRecordCol(colRules, value).then((valid: boolean) => { + const index = this.currentRecordInvalidCols.indexOf(colName) + + if (valid) { + if (index > -1) this.currentRecordInvalidCols.splice(index, 1) + } else { + if (index < 0) this.currentRecordInvalidCols.push(colName) + } + }) + }) + } + + onNextRecordClick() { + this.onNextRecord.emit() + } + + onPreviousRecordClick() { + this.onPreviousRecord.emit() + } + + public copyToClip(text: string) { + const modalElement = document.querySelector('#recordModalRef .modal-title') + + if (modalElement) { + const selBox = document.createElement('textarea') + selBox.style.position = 'fixed' + selBox.style.left = '0' + selBox.style.top = '0' + selBox.style.opacity = '0' + selBox.style.zIndex = '5000' + selBox.value = text + modalElement.appendChild(selBox) + selBox.focus() + selBox.select() + document.execCommand('copy') + modalElement.removeChild(selBox) + this.generatedRecordUrl = text + } + } + + async generateEditRecordUrl() { + if (this.generatedRecordUrl) { + this.copyToClip(this.generatedRecordUrl) + } else { + this.generateEditRecordUrlLoading = true + + const filterQueryClauseTable: QueryClause[] = [] + + this.headerPks.forEach((key: string) => { + let type = 'C' + let rawValue = '' + for (let i = 0; i < this.cellValidation.length; i++) { + const obj = this.cellValidation[i] + if (obj.data === key) { + if ( + obj.type === 'numeric' || + obj.type === 'date' || + obj.type === 'time' + ) { + type = 'N' + } + break + } + } + + if (type === 'C') { + rawValue = `'${this.currentRecord[key]}'` + } else { + rawValue = this.currentRecord[key].toString() + } + + filterQueryClauseTable.push({ + GROUP_LOGIC: 'AND', + SUBGROUP_LOGIC: 'AND', + SUBGROUP_ID: 0, + VARIABLE_NM: key, + OPERATOR_NM: '=', + RAW_VALUE: rawValue + }) + }) + + if (filterQueryClauseTable.length > 0 && this.libds) { + await this.sasStoreService + .saveQuery(this.libds, filterQueryClauseTable) + .then((res: ValidateFilterSASResponse) => { + const id = res.result[0].FILTER_RK + const table = res.result[0].FILTER_TABLE + this.queryFilter = { id: id, table: table } + + //copy to clipboard + const editLink = + location.href.split('#')[0] + + '#/editor/edit-record/' + + this.queryFilter.table + + '/' + + this.queryFilter.id + + this.copyToClip(editLink) + + this.generateEditRecordUrlLoading = false + this.filter = false + }) + .catch((err: any) => { + this.submitLoading = false + }) + } + } + } + + isColPk(col: string) { + return this.headerPks.indexOf(col) > -1 + } + + originalOrder = ( + a: KeyValue, + b: KeyValue + ): number => { + return 0 + } + + trackByFn(index: number, item: any): number { + return index + } +} diff --git a/client/src/app/editor/components/upload-stater/upload-stater.component.html b/client/src/app/editor/components/upload-stater/upload-stater.component.html new file mode 100644 index 0000000..cdd8519 --- /dev/null +++ b/client/src/app/editor/components/upload-stater/upload-stater.component.html @@ -0,0 +1,8 @@ +
+

+ {{ state }} +

+
+
+ Loading... +
diff --git a/client/src/app/editor/components/upload-stater/upload-stater.component.scss b/client/src/app/editor/components/upload-stater/upload-stater.component.scss new file mode 100644 index 0000000..9584e7b --- /dev/null +++ b/client/src/app/editor/components/upload-stater/upload-stater.component.scss @@ -0,0 +1,8 @@ +:host { + display: block; +} + +p { + margin: 0; + text-align: center; +} \ No newline at end of file diff --git a/client/src/app/editor/components/upload-stater/upload-stater.component.ts b/client/src/app/editor/components/upload-stater/upload-stater.component.ts new file mode 100644 index 0000000..d27e45b --- /dev/null +++ b/client/src/app/editor/components/upload-stater/upload-stater.component.ts @@ -0,0 +1,77 @@ +import { Component, OnInit } from '@angular/core' + +/** + * Goal of this component is to recieve array of strings where every element is one state + * and to append them in html while showing the loading spinner. + * Even if states change quickly, this component will keep every state for at least miliseconds + * that are defines in `minDelay` variable. + */ + +@Component({ + selector: 'app-upload-stater', + templateUrl: './upload-stater.component.html', + styleUrls: ['./upload-stater.component.scss'] +}) +export class UploadStaterComponent implements OnInit { + public statesList: string[] = [] //States appended to be displayed + public processedStates: string[] = [] //States that has been displayed and processed + + /** + * Stater config + */ + public staterInProgress: boolean = false + private stateInterval: any + private minDelay: number = 1000 + + constructor() {} + + ngOnInit(): void {} + + public appendState(state: string) { + if (state === '{finish}') { + /** + * Stop the stater progress + */ + this.staterInProgress = false + clearInterval(this.stateInterval) + + return + } + + this.statesList.push(state) + this.processedStates.push(state) + + // We are disabling delaying functionality for now + // if (!this.staterInProgress) { + // this.startStater() + // } + } + + public replaceLastState(state: string) { + if (this.statesList.length > 0) { + this.statesList.pop() + this.statesList.push(state) + } else { + this.processedStates[this.processedStates.length - 1] = state + } + } + + public clearStates() { + this.processedStates = [] + } + + private startStater() { + this.staterInProgress = true + + //First run + if (this.statesList.length > 0) { + this.processedStates.push(this.statesList.shift() || '') + } + + this.stateInterval = setInterval(() => { + if (this.statesList.length > 0) { + this.processedStates.push(this.statesList.shift() || '') + } + }, this.minDelay) + } +} diff --git a/client/src/app/editor/editor-routing.module.ts b/client/src/app/editor/editor-routing.module.ts new file mode 100644 index 0000000..8a00d49 --- /dev/null +++ b/client/src/app/editor/editor-routing.module.ts @@ -0,0 +1,18 @@ +import { CommonModule } from '@angular/common' +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { EditorComponent } from './editor.component' + +const ROUTES: Routes = [ + { path: ':libMem', component: EditorComponent }, + { path: ':libMem/:filterId', component: EditorComponent }, + { path: 'edit-record/:libMem', component: EditorComponent }, + { path: 'edit-record/:libMem/:filterId', component: EditorComponent } +] + +@NgModule({ + declarations: [], + imports: [CommonModule, RouterModule.forChild(ROUTES)], + exports: [RouterModule] +}) +export class EditorRoutingModule {} diff --git a/client/src/app/editor/editor.component.html b/client/src/app/editor/editor.component.html new file mode 100644 index 0000000..99bd66c --- /dev/null +++ b/client/src/app/editor/editor.component.html @@ -0,0 +1,836 @@ +
+ + + + + + + + +
+
+ +
+ +
+
+
+ + Back to + table selection + + + + Viewboxes + +
+ +
+

+ + + + + {{ libdsParsed.libName }}.{{ libdsParsed.tableName.replace('-FC', '') }} + + + ({{ dataSource.length | thousandSeparator: ',' }} + {{ dataSource.length === 1 ? 'row' : 'rows' }}, {{ cols.length + }}{{ cols.length === 1 ? ' col' : ' cols' }}) + + + (0 rows) + +

+
+
+ + + + + + + + + + + + + + + + To unlock more than + {{ licenceState.value.editor_rows_allowed }} + {{ + licenceState.value.editor_rows_allowed === 1 + ? 'row' + : 'rows' + }}, contact support@datacontroller.io + + + + + + + + + + + + + +
+
+ FILTER : + {{ queryText }} + +
+
+
+
+
+ + Loading... + +
+

Loading table

+
+
+ + + + + + +
+

Loading table error

+
+
+
+
+ +
+ + + + + + +
+ + + +
+ +
+ + + + + To unlock more than + {{ licenceState.value.editor_rows_allowed }} + {{ + licenceState.value.editor_rows_allowed === 1 + ? 'row' + : 'rows' + }}, contact support@datacontroller.io + + +

+ To display more than + {{ licenceState.value.editor_rows_allowed }} rows, contact + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/app/editor/editor.component.scss b/client/src/app/editor/editor.component.scss new file mode 100644 index 0000000..24641f8 --- /dev/null +++ b/client/src/app/editor/editor.component.scss @@ -0,0 +1,223 @@ +.card { + margin-top: 0; + border: 0; +} + +.buttonBar { + padding: 2px 10px 2px 10px; + align-items: center; +} + +.testRed { + color: white; + background: rgba(255,0,0, 0.8) !important; +} + +hot-table { + ::ng-deep { + .firstColumnHeaderStyle button.changeType { + display: none; + } + + .handsontable tbody th.ht__highlight, .handsontable thead th.ht__highlight { + &.primaryKeyHeaderStyle { + background: #306b00b0; + } + } + + .primaryKeyHeaderStyle { + background: #306b006e; + } + + th.readonlyCell { + div { + opacity: 0.4; + } + } + + td.readonlyCell { + opacity: 0.5 + } + } +} + +.infoBar { + margin-top:14px; + background: #495967; + color: white; + text-align:center; + padding: 3px; + font-size: 16px; + + height: 30px; + + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + + span { + width: 80%; + } + + &:hover { + height: unset; + white-space: normal; + + span { + width: unset; + } + } +} + +.pkHeader { + background: #687682; + color: #fff; + margin: -1px -1px -1px -1px; +} + +.headerBar { + // padding: 13px 0px 14px 0px; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background: #ffffff; + background: #f5f6fe; +} + +.error-icon { + width: 30px; + height: 30px; + color: red; +} + +.btnCtrl { + display:flex; + justify-content:flex-end; +} + +.card-header { + border-bottom: 1px solid transparent; +} + +.hidden { + visibility: hidden; +} + +.my-drop-zone { + border: solid 1px lightgray; + border-radius: 10px; + background: whitesmoke; + box-shadow: inset 0px 0px 4px 2px #a7a5a52b; + height: 50vh; +} +.nv-file-over { + border: solid 2px green; +} /* Default class applied to drop zones on over */ + +.file-drop-text{ + text-align: center; +} + +.nv-file-over { + border: solid 2px green; +} /* Default class applied to drop zones on over */ + +.file-drop-text{ + text-align: center; +} + +@media screen and (max-width: 768px) { + + .progresStatic { + margin-top:9px!important; + } + + .progress, .progress-static { + width: calc(100% - 14px); + } +} + +.hotEditor { + position: relative; +} + +.excel-parsing { + display: flex; + flex-direction: column; + align-items: center; + + position: relative; + + .details { + margin: 0; + position: absolute; + top: -45px; + } +} + +.edit-record-spinner { + display: flex; + justify-content: center; + align-items: center; + background: rgba(255, 255, 255, 0.6); + position: absolute; + top: 0px; + bottom: 0px; + width: 100%; + z-index: 500; +} + +@media screen and (max-width: 480px) { + + .progresStatic { + margin-top:32px!important; + } + + .card-block, .card-footer { + padding: 10px 0px 0px 0px; + } +} + +.content-area { + padding: 0 0.8rem 0.8rem 0.8rem !important; + padding-top: 0; + + // .card { + // min-height: calc(100vh - 160px); + // } +} + +.drop-area { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + + display: flex; + justify-content: center; + + margin: 1px; + + border: 2px dashed #fff; + + z-index: -1; + + span { + font-size: 20px; + margin-top: 20px; + color: #fff; + } +} + +#submitBtn, #cancelSubmitBtn { + width: 150px; +} + +// FIXME +// Let's leave it here for a reference if there +// is an issue with viewboxes/filter modal overlaying +// we will remove it if no issues found +// .filter-modal { +// z-index: 1210; +// } \ No newline at end of file diff --git a/client/src/app/editor/editor.component.ts b/client/src/app/editor/editor.component.ts new file mode 100644 index 0000000..df91daf --- /dev/null +++ b/client/src/app/editor/editor.component.ts @@ -0,0 +1,3335 @@ +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + OnInit, + QueryList, + ViewChild, + ViewChildren, + ViewEncapsulation +} from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import Handsontable from 'handsontable' +import { Subject, Subscription } from 'rxjs' +import { SasStoreService } from '../services/sas-store.service' + +import * as XLSX from '@sheet/crypto' +const iconv = require('iconv-lite') +const Buffer = require('buffer/').Buffer +type AOA = any[][] + +import { HotTableRegisterer } from '@handsontable/angular' +import { UploadFile } from '@sasjs/adapter' +import { isSpecialMissing } from '@sasjs/utils/input/validators' +import CellRange from 'handsontable/3rdparty/walkontable/src/cell/range' +import { CellValidationSource } from '../models/CellValidationSource' +import { FileUploader } from '../models/FileUploader.class' +import { FilterGroup, FilterQuery } from '../models/FilterQuery' +import { HotTableInterface } from '../models/HotTable.interface' +import { + $DataFormats, + DSMeta, + EditorsGetdataServiceResponse +} from '../models/sas/editors-getdata.model' +import { DataFormat } from '../models/sas/common/DateFormat' +import SheetInfo from '../models/SheetInfo' +import { Approver, ExcelRule } from '../models/TableData' +import { QueryComponent } from '../query/query.component' +import { EventService } from '../services/event.service' +import { HelperService } from '../services/helper.service' +import { LoggerService } from '../services/logger.service' +import { SasService } from '../services/sas.service' +import { DcValidator } from '../shared/dc-validator/dc-validator' +import { Col } from '../shared/dc-validator/models/col.model' +import { DcValidation } from '../shared/dc-validator/models/dc-validation.model' +import { DQRule } from '../shared/dc-validator/models/dq-rules.model' +import { getHotDataSchema } from '../shared/dc-validator/utils/getHotDataSchema' +import { globals } from '../_globals' +import { UploadStaterComponent } from './components/upload-stater/upload-stater.component' +import { DynamicExtendedCellValidation } from './models/dynamicExtendedCellValidation' +import { EditRecordInputFocusedEvent } from './models/edit-record/edit-record-events' +import { EditorRestrictions } from './models/editor-restrictions.model' +import { dateFormat, dateToTime, dateToUtcTime } from './utils/date.utils' +import { + excelDateToJSDate, + getMissingHeaders, + parseTableColumns +} from './utils/grid.utils' +import { + errorRenderer, + noSpinnerRenderer, + spinnerRenderer +} from './utils/renderers.utils' +import { isStringDecimal, isStringNumber } from './utils/types.utils' +import { LicenceService } from '../services/licence.service' + +@Component({ + selector: 'app-editor', + templateUrl: './editor.component.html', + styleUrls: ['./editor.component.scss'], + host: { + class: 'content-container' + }, + encapsulation: ViewEncapsulation.Emulated +}) +export class EditorComponent implements OnInit, AfterViewInit { + @ViewChildren('uploadStater') + uploadStaterCompList: QueryList = new QueryList() + @ViewChildren('queryFilter') + queryFilterCompList: QueryList = new QueryList() + @ViewChildren('hotInstance') + hotInstanceCompList: QueryList = new QueryList() + @ViewChildren('fileUploadInput') + fileUploadInputCompList: QueryList = new QueryList() + + public static cnt: number = 0 + public static nonPkCnt: number = 0 + public static lastCell: number = 0 + private _tableSub: Subscription | undefined + public message: string = '' + public $dataFormats: $DataFormats | null = null + public submit: boolean | undefined + public cols: Col[] = [] + + @ViewChild('ht', { static: true }) ht!: ElementRef + + /** Feature restrictions + * + * What can be restricted + * - Add Row button + * - Insert rows above/below + * - Add record button + * - Edit record button + * + * Types of limitations ordered by priority of enforcement (Restrictions upper on the list cannot be un-restricted by lower types) + * - Restrict edit record feature with config in startupservice (comes from appService) + * - Restrict `edit record feature` and `add row` if demo and demo limits set as such - since demo is limited to less rows, and buttons which adds rows triggers error + * - Restrict `add record feature` and `add row` based on configuration of `Column Level Security` + */ + restrictions: EditorRestrictions = {} + + datasetInfo: boolean = false + dsmeta: DSMeta[] = [] + + viewboxes: boolean = false + + Infinity = Infinity + + public hotInstance!: Handsontable + public dcValidator: DcValidator | undefined + + public hotTable: HotTableInterface = { + data: [], + colHeaders: [], + hidden: true, + columns: [], + height: '100%', + minSpareRows: 1, + licenseKey: undefined, + readOnly: true, + copyPaste: { + copyColumnHeaders: true, + copyColumnHeadersOnly: true + }, + settings: { + contextMenu: { + items: { + edit_row: { + name: 'Edit row', + hidden() { + const hot: Handsontable.Core = this + + const fullCellRange: CellRange[] | undefined = + hot.getSelectedRange() + + if (!fullCellRange) return false + + const cellRange = fullCellRange[0] + + return cellRange.from.row !== cellRange.to.row + }, + callback: ( + key: string, + selection: any[], + clickEvent: MouseEvent + ) => { + let firstSelection = selection[0] + + if (firstSelection.start.row === firstSelection.end.row) { + this.editRecord(null, firstSelection.start.row) + } + } + }, + row_above: { + name: 'Insert Row above' + }, + row_below: { + name: 'Insert Row below' + }, + remove_row: { + name: 'Ignore row' + }, + copy: { + name: 'Copy without headers' + }, + copy_with_column_headers: { + name: 'Copy with headers' + }, + copy_column_headers_only: { + name: 'Copy headers only' + }, + sp1: { + name: '---------' + }, + undo: { + name: 'Undo' + }, + redo: { + name: 'Redo' + } + } + } + } + } + + public hotCellsPropRow: number | null = null + + public filter: boolean = false + public submitLoading: boolean = false + public uploadLoading: boolean = false + public rowsChanged: any = { + rowsUpdated: 0, + rowsDeleted: 0, + rowsAdded: 0 + } + public modifedRowsIndexes: number[] = [] + public queryErr: boolean = false + public queryErrMessage: string | undefined + public successEnable: boolean = false + public libTab: string | undefined + public queryFilter: any + public _query: Subscription | undefined + + public whereString: string | undefined + public clauses: any + public nullVariables: boolean = false + + public tableId: string | undefined + public pkFields: any = [] + + public libds: string | undefined + public filter_pk: string | undefined + public table: any + public filename: string = '' + public selectedColumn: any + public hotSelection: Array | null | undefined + public submitLimitNotice: boolean = false + public badEdit: boolean = false + public badEditCause: string | undefined + public badEditTitle: string | undefined + public tableTrue: boolean | undefined + public saveLoading: boolean = false + public approvers: string[] = [] + public approver: any + public readOnlyFields!: number + public errValidation: boolean = false + public dataObj: any + public disableSubmit: boolean | undefined + public pkNull: boolean = false + public noPkNull: boolean = false + public tableData: Array = [] + public queryText: string = '' + public queryTextSaved: string = '' + public showApprovers: boolean = false + public pkDups: boolean = false + public validationDone: number = 0 + public duplicatePkIndexes: any = [] + public columnHeader: string[] = [] + public specInfo: { col: string; len: number; type: number }[] = [] + public tooLong: boolean = false + public exceedCells: { + col: string + len: number + val: string + }[] = [] + public uploader: FileUploader = new FileUploader() + public uploadUrl: string = '' + public excelFileReady: boolean = false + public uploadPreview: boolean = false + public excelFileParsing: boolean = false + public excelUploadState: string | null = null + public data: AOA = [] + public headerArray: string[] = [] + public hotDataSchema: any = {} + public headerShow: string[] = [] + public headerVisible: boolean = false + public hasBaseDropZoneOver: boolean = false + public hasAnotherDropZoneOver: boolean = false + public headerPks: string[] = [] + public columnLevelSecurityFlag: boolean = false + public dateTimeHeaders: string[] = [] + public timeHeaders: string[] = [] + public dateHeaders: string[] = [] + + public xlRules: ExcelRule[] = [] + public encoding: string = 'UTF-8' + + // header column names + headerColumns: Array = [] + cellValidation: DcValidation[] = [] + // hot table data source + dataSource!: any[] + prevDataSource!: any[] + dataSourceUnchanged!: any[] + dataSourceBeforeSubmit!: any[] + dataModified!: any[] + + public filePasswordSubject: Subject = new Subject() + public fileUnlockError: boolean = false + + public filePasswordModal: boolean = false + public showUploadModal: boolean = false + public discardSourceFile: boolean = false + public manualFileEditModal: boolean = false + + public recordAction: string | null = null + + public currentEditRecord: any + public currentEditRecordValidator: DcValidator | undefined + public currentEditRecordLoadings: number[] = [] + public currentEditRecordErrors: number[] = [] + public currentEditRecordIndex: number = -1 + + public generateEditRecordUrlLoading: boolean = false + public generatedRecordUrl: string | null = null + public addRecordUrl: string | null = null + public recordNewOrPkModified: boolean = false + public addRecordLoading: boolean = false + public singleRowSelected: boolean = false + public addingNewRow: boolean = false + public getdataError: boolean = false + public zeroFilterRows: boolean = false + + public tableFileDragOver: boolean = false + + /** + * Hash/values table used for dynamic cell validation + */ + public cellValidationSource: CellValidationSource[] = [] + public validationTableLimit: number = 20 + public extendedCellValidationFields: { + DISPLAY_INDEX: number + EXTRA_COL_NAME: number + DISPLAY_VALUE: number + DISPLAY_TYPE: number + RAW_VALUE_NUM: number + RAW_VALUE_CHAR: number + FORCE_FLAG: number + } = { + DISPLAY_INDEX: 0, + EXTRA_COL_NAME: 1, + DISPLAY_VALUE: 2, + DISPLAY_TYPE: 3, + RAW_VALUE_NUM: 4, + RAW_VALUE_CHAR: 5, + FORCE_FLAG: 6 + } + + public cellValidationFields: { + DISPLAY_INDEX: number + DISPLAY_VALUE: number + RAW_VALUE: number + } = { DISPLAY_INDEX: 0, DISPLAY_VALUE: 1, RAW_VALUE: 2 } + + public disabledBasicDynamicCellValidationMap: { + row: number + col: number + active: boolean + }[] = [] + + public licenceState = this.licenceService.licenceState + + constructor( + private licenceService: LicenceService, + private eventService: EventService, + private loggerService: LoggerService, + private sasStoreService: SasStoreService, + private helperService: HelperService, + private router: Router, + private route: ActivatedRoute, + private sasService: SasService, + private cdf: ChangeDetectorRef, + private hotRegisterer: HotTableRegisterer + ) { + this.hotRegisterer = new HotTableRegisterer() + + this.parseRestrictions() + this.setRestrictions() + } + + private parseRestrictions() { + this.restrictions.restrictAddRecord = + this.licenceState.value.addRecord === false + this.restrictions.restrictEditRecord = + this.licenceState.value.editRecord === false + this.restrictions.restrictFileUpload = + this.licenceState.value.fileUpload === false + } + + private setRestrictions(overrideRestrictions?: EditorRestrictions) { + if (overrideRestrictions) { + this.restrictions = { + ...this.restrictions, + ...overrideRestrictions + } + } + + if (this.restrictions.removeEditRecordButton) { + delete (this.hotTable?.settings?.contextMenu as any).items.edit_row + } + + if (this.restrictions.restrictAddRow) { + delete (this.hotTable?.settings?.contextMenu as any).items.row_above + delete (this.hotTable?.settings?.contextMenu as any).items.row_below + delete (this.hotTable?.settings?.contextMenu as any).items.remove_row + } + } + + private checkRowLimit() { + if (this.columnLevelSecurityFlag) return + + if (this.licenceState.value.editor_rows_allowed !== Infinity) { + if ( + this.dataSource?.length >= this.licenceState.value.editor_rows_allowed + ) { + this.restrictions.restrictAddRow = true + } else { + this.restrictions.restrictAddRow = false + } + } + } + + public resetFilter() { + if (this.queryFilterCompList.first) { + this.queryFilterCompList.first.resetFilter() + } + } + + public onShowUploadModal() { + if (this.restrictions.restrictFileUpload) { + this.eventService.showDemoLimitModal('File Upload') + return + } + + if (this.columnLevelSecurityFlag) { + this.eventService.showInfoModal( + 'Information', + 'Upload feature is disabled while Column Level Security rules are active' + ) + return + } + + if (!this.uploadPreview) this.showUploadModal = true + } + + public fileOverBase(e: boolean): void { + this.hasBaseDropZoneOver = e + } + + /** + * Function that updates the !ref range value provided in official docs. + * @param ws worksheet to be updated + */ + private update_sheet_range(ws: XLSX.WorkSheet) { + var range = { s: { r: Infinity, c: Infinity }, e: { r: 0, c: 0 } } + Object.keys(ws) + .filter(function (x) { + return x.charAt(0) != '!' + }) + .map(XLSX.utils.decode_cell) + .forEach(function (x: any) { + range.s.c = Math.min(range.s.c, x.c) + range.s.r = Math.min(range.s.r, x.r) + range.e.c = Math.max(range.e.c, x.c) + range.e.r = Math.max(range.e.r, x.r) + }) + + ws['!ref'] = XLSX.utils.encode_range(range) + } + + /** + * Function that gives the sheet name which contains data and range of data in that sheet, if some headers are missing then also gives the info about those missing headers + * @param wb Excel workbook + * @returns {object: SheetInfo} an object which contains necessary information about workbook that which sheet contains required data and what's the range + */ + public getRangeAndSheet(wb: XLSX.WorkBook): SheetInfo { + let rangeStartRow: number = 0 + let rangeStartCol: number = 0 + let startRow: number = -1 + let endRow: number = -1 + let sheetName: string = '' + let isComplete = false + let missingHeaders: string[] = [] + let csvArrayHeaders: string[] = [ + '_____DELETE__THIS__RECORD_____', + ...this.headerArray + ] + let csvArrayHeadersLower = csvArrayHeaders.map((x) => x.toLowerCase()) + let csvArrayHeadersMap = csvArrayHeadersLower.reduce( + (map: any, obj: string) => { + map[obj] = -1 + return map + }, + {} + ) + + wb.SheetNames.forEach((element: string) => { + // Checking for required data in each sheet in workbook/ + if (isComplete) { + return + } + + missingHeaders = [] + sheetName = element + const ws: XLSX.WorkSheet = wb.Sheets[sheetName] + + this.data = XLSX.utils.sheet_to_json(ws, { + header: 1, + blankrows: false, + defval: '' + }) + + if (this.data.length <= 1) { + return + } + + let tempArr: string[] = [] + this.headerArray.forEach(() => tempArr.push('')) + this.data.push(tempArr) + + let foundHeaders = false + + this.data.forEach((row: any, index: number) => { + if (isComplete) { + return + } + + if (foundHeaders) { + let isDataEnd = true + let isPkNull = false + + csvArrayHeadersLower.forEach((x) => { + const col = csvArrayHeadersMap[x] + + if (row[col] !== '' && row[col] !== undefined) { + isDataEnd = false + } else { + if (this.headerPks.indexOf(x.toUpperCase()) !== -1) { + isPkNull = true + } + } + }) + + if (isDataEnd || isPkNull) { + endRow = index + isComplete = true + } else { + if (startRow === -1) { + startRow = index + } + } + } else { + const rowLowerCase: string[] = row.map((x: any) => + x.toString().toLowerCase() + ) + + // If in file there is no delete column, remove it from search of missing. + // This way delete column will be optional to provide in file + if (!rowLowerCase.includes('_____delete__this__record_____')) { + const deleteIndex = csvArrayHeadersLower.indexOf( + '_____delete__this__record_____' + ) + + if (deleteIndex > -1) csvArrayHeadersLower.splice(deleteIndex, 1) + } + + foundHeaders = true + + csvArrayHeadersLower.forEach((x) => { + if (rowLowerCase.indexOf(x) === -1) { + foundHeaders = false + } + }) + + let result = [] + + result = this.findValidHeaders( + rowLowerCase, + csvArrayHeadersLower, + index, + sheetName + ) + + if (result[0] === false) { + foundHeaders = false + + if (result[1].length > 0) { + result[1].forEach((data: string) => { + missingHeaders.push(data) + }) + } + } else { + csvArrayHeadersMap = result[1] + } + } + }) + + if (isComplete) { + this.update_sheet_range(ws) + const worksheetSel = ws['!ref'] + + if (worksheetSel) { + const range = XLSX.utils.decode_range(ws['!ref'] || '') + rangeStartRow = range.s.r + rangeStartCol = range.s.c + } + } + }) + + // If start row is still -1 that means first row of found range is empty + if (startRow === -1) isComplete = false + + const returnObj: SheetInfo = { + foundData: isComplete, + sheetName, + startRow, + endRow, + csvArrayHeadersMap, + missingHeaders, + rangeStartRow, + rangeStartCol + } + + return returnObj + } + + public promptExcelPassword(): Promise { + return new Promise((resolve, reject) => { + this.filePasswordModal = true + + setTimeout(() => { + const filePasswordInputElement: any = + document.querySelector('#filePasswordInput') + if (filePasswordInputElement) { + filePasswordInputElement.focus() + filePasswordInputElement.value = '' + } + }, 100) + + this.filePasswordSubject.subscribe((password: string | undefined) => { + this.fileUnlockError = false + + if (password) { + resolve(password) + } else { + resolve(undefined) + } + }) + }) + } + + public getFileDesc(event: any, dropped: boolean = false) { + this.excelUploadState = 'Loading' + this.excelFileParsing = true + + let file + if (dropped) { + file = event[0] + } else { + file = event.target.files[0] + } + + this.excelFileReady = false + + this.filename = '' + let filename = file.name + this.filename = filename + + this.appendUploadState(`Loading ${filename} into the browser`) + + let foundData = { + sheet: '' + } + + let fileType = filename.slice( + filename.lastIndexOf('.') + 1, + filename.lastIndexOf('.') + 4 + ) + + if (fileType.toLowerCase() === 'xls') { + let reader: FileReader = new FileReader() + const self = this + reader.onload = async (theFile: any) => { + /* read workbook */ + const bstr = this.toBstr(theFile.target.result) + let wb: XLSX.WorkBook | undefined = undefined + let fileUnlocking: boolean = false + + const xlsxOptions: XLSX.ParsingOptions = { + type: 'binary', + cellDates: false, + cellFormula: true, + cellStyles: true, + cellNF: false, + cellText: false + } + + try { + wb = XLSX.read(bstr, { + ...xlsxOptions + }) + } catch (err: any) { + if (err.message.toLowerCase().includes('password')) { + fileUnlocking = true + + while (fileUnlocking) { + const password = await this.promptExcelPassword() + + if (password) { + try { + wb = XLSX.read(bstr, { + ...xlsxOptions, + password: password + }) + + fileUnlocking = false + this.fileUnlockError = false + } catch (err: any) { + this.fileUnlockError = true + + if (!err.message.toLowerCase().includes('password')) { + fileUnlocking = false + } + } + } else { + fileUnlocking = false + } + } + } else { + this.eventService.showAbortModal( + null, + err, + undefined, + 'Error reading file' + ) + } + } + + if (!wb) { + this.excelFileParsing = false + this.showUploadModal = false + return + } + + /* save data */ + let isComplete: boolean = false + let missingHeaders: string[] = [] + + const csvArrayHeaders: string[] = [ + '_____DELETE__THIS__RECORD_____', + ...this.headerArray + ] + let csvArrayHeadersLower = csvArrayHeaders.map((x) => x.toLowerCase()) + let csvArrayHeadersMap = csvArrayHeadersLower.reduce( + (map: any, obj: string) => { + map[obj] = -1 + return map + }, + {} + ) + + let csvArrayData: any[] = [] + const rangeSheetRes: SheetInfo = this.getRangeAndSheet(wb) + missingHeaders = rangeSheetRes.missingHeaders + + if (rangeSheetRes.foundData) { + isComplete = true + csvArrayHeadersMap = rangeSheetRes.csvArrayHeadersMap + const ws: XLSX.WorkSheet = wb.Sheets[rangeSheetRes.sheetName] + + this.appendUploadState( + `Table found on sheet ${rangeSheetRes.sheetName} on row ${rangeSheetRes.startRow}` + ) + + let startAddress = '' + let endAddress = '' + + for ( + let row = rangeSheetRes.startRow; + row < rangeSheetRes.endRow; + ++row + ) { + const arr: any[] = [] + + csvArrayHeadersLower.forEach((x) => { + const col = csvArrayHeadersMap[x] + const addr = XLSX.utils.encode_cell({ + r: rangeSheetRes.rangeStartRow + row, + c: rangeSheetRes.rangeStartCol + col + }) + + if (startAddress === '') startAddress = addr + endAddress = addr + + let cell + + if (!ws[addr]) { + cell = { v: '' } + } else { + cell = ws[addr] + } + arr.push(cell) + }) + + // If we found at least one non empty value it means it is not empty row + // othervise, it is empty row + let arrNonEmptyValue = arr.find((x) => x.v !== '') + + if (arrNonEmptyValue) csvArrayData.push(arr) + } + + this.eventService.showInfoModal( + 'Table Found', + `Sheet: ${rangeSheetRes.sheetName}\nRange: ${startAddress}:${endAddress}` + ) + } else { + missingHeaders = rangeSheetRes.missingHeaders + } + + if (missingHeaders.length > 0) { + missingHeaders.sort(function compareSecondColumn(a, b) { + if (a[1] === b[1]) { + return 0 + } else { + return a[1] > b[1] ? -1 : 1 + } + }) + let abortMsg = missingHeaders + .map((x) => x[0]) + .slice(0, 5) + .join('\n') + + this.eventService.showAbortModal(null, abortMsg) + + setTimeout(() => { + this.filename = '' + }) + + this.excelFileParsing = false + this.uploader.queue.pop() + return + } + + // If first row is empty, that means no data has been found + if (csvArrayData.length === 0 || csvArrayData[0].length === 0) { + let abortMsg = 'No relevant data found in File !' + this.eventService.showAbortModal(null, abortMsg) + + setTimeout(() => { + this.filename = '' + }) + + this.excelFileParsing = false + this.uploader.queue.pop() + return + } + + if ( + this.dateTimeHeaders.length > 0 || + this.dateHeaders.length > 0 || + this.timeHeaders.length > 0 + ) { + csvArrayData = this.updateDateTimeCols(csvArrayHeaders, csvArrayData) + } + + if (this.xlRules.length > 0) { + csvArrayData = this.updateXLRuleCols(csvArrayHeaders, csvArrayData) + } + + if (!isComplete) { + if (missingHeaders.length === 0) { + let abortMsg = 'No relevant data found in File !' + this.eventService.showAbortModal(null, abortMsg) + + setTimeout(() => { + this.filename = '' + }) + } else { + missingHeaders.sort(function compareSecondColumn(a, b) { + if (a[1] === b[1]) { + return 0 + } else { + return a[1] > b[1] ? -1 : 1 + } + }) + let abortMsg = missingHeaders + .map((x) => x[0]) + .slice(0, 5) + .join('\n') + + this.eventService.showAbortModal(null, abortMsg) + } + this.excelFileParsing = false + this.uploader.queue.pop() + return + } else { + this.headerShow = csvArrayHeaders + csvArrayData = csvArrayData.map((row: any) => + row.map((col: any) => (col.t === 'n' ? col.v : col.w)) + ) + + csvArrayData = csvArrayData.map((row: any) => { + return row.map((col: any, index: number) => { + if (!col && col !== 0) col = '' + + if (isNaN(col)) { + col = col.replace(/"/g, '""') + + if (col.search(/,/g) > -1) { + col = '"' + col + '"' + } + } + + const colName = this.headerShow[index] + const colRule = this.dcValidator?.getRule(colName) + + if (colRule?.type === 'numeric') { + if (isSpecialMissing(col) && !col.includes('.')) col = '.' + col + } + + return col + }) + }) + + this.data = csvArrayData + + let csvContent = csvArrayHeaders.join(',') + '\n' + // Apply licence rows limitation if exists + csvContent += csvArrayData + .slice(0, this.licenceState.value.submit_rows_limit) + .map((e) => e.join(',')) + .join('\n') + + if (this.encoding === 'WLATIN1') { + let encoded = iconv.decode(Buffer.from(csvContent), 'CP-1252') + let blob = new Blob([encoded], { type: 'application/csv' }) + let newCSVFile: File = this.blobToFile(blob, this.filename + '.csv') + this.uploader.addToQueue([newCSVFile]) + } else { + let blob = new Blob([csvContent], { type: 'application/csv' }) + let newCSVFile: File = this.blobToFile(blob, this.filename + '.csv') + this.uploader.addToQueue([newCSVFile]) + } + + this.excelFileReady = true + } + + if (this.data.length === 0) { + this.showUploadModal = false + this.uploadPreview = false + this.excelFileParsing = false + + this.eventService.showAbortModal( + null, + `Table in the file is empty. Data found on sheet: ${foundData.sheet}` + ) + + return + } + + this.excelFileReady = true + this.getPendingExcelPreview() + + return + } + reader.readAsArrayBuffer(file) + } else if (fileType.toLowerCase() === 'csv') { + if (this.licenceState.value.submit_rows_limit !== Infinity) { + this.eventService.showInfoModal( + 'Notice', + 'Excel files only. To unlock CSV uploads, please contact support@datacontroller.io' + ) + this.excelFileReady = true + this.excelFileParsing = false + this.uploader.queue.pop() + + return + } + + if (this.encoding === 'WLATIN1') { + let reader = new FileReader() + const self = this + // Closure to capture the file information. + reader.onload = (theFile: any) => { + let encoded = iconv.decode( + Buffer.from(theFile.target.result), + 'CP-1252' + ) + let blob = new Blob([encoded], { type: fileType }) + let encodedFile: File = this.blobToFile(blob, this.filename) + this.uploader.queue.pop() + this.uploader.addToQueue([encodedFile]) + this.excelFileReady = true + } + this.excelFileReady = true + this.excelFileParsing = false + reader.readAsArrayBuffer(file) + this.getFile() + } else { + this.excelFileReady = true + this.excelFileParsing = false + this.getFile() + } + } else { + let abortMsg = + 'Invalid file type "' + + this.filename + + '". Please upload csv or excel file.' + this.eventService.showAbortModal(null, abortMsg) + + this.excelFileReady = true + this.excelFileParsing = false + this.uploader.queue.pop() + } + } + + public submitExcel() { + if (this.licenceState.value.submit_rows_limit !== Infinity) { + this.submitLimitNotice = true + return + } + + this.getFile() + } + + public getFile() { + if (this.checkInvalid()) { + this.eventService.showAbortModal(null, 'Invalid values are present.') + return + } + + this.uploadLoading = true + let filesToUpload: UploadFile[] = [] + + for (const file of this.uploader.queue) { + filesToUpload.push({ + file: file, + fileName: file.name + }) + } + + this.sasService + .uploadFile(this.uploadUrl, filesToUpload, { table: this.libds }) + .then( + (res: any) => { + if (typeof res.sasjsAbort === 'undefined') { + if (typeof res.sasparams === 'undefined') { + return + } else { + this.uploadLoading = false + let params = res.sasparams[0] + this.successEnable = true + this.tableId = params.DSID + this.router.navigateByUrl('/stage/' + this.tableId) + } + } else { + // handle succesfull response + const abortRes = res + const abortMsg = abortRes.sasjsAbort[0].MSG + const macMsg = abortRes.sasjsAbort[0].MAC + + this.uploadLoading = false + this.filename = '' + if (this.fileUploadInputCompList.first) { + //clear the attached file to input + this.fileUploadInputCompList.first.nativeElement.value = '' + } + this.uploader.queue = [] + this.eventService.showAbortModal('', abortMsg, { + SYSWARNINGTEXT: abortRes.SYSWARNINGTEXT, + SYSERRORTEXT: abortRes.SYSERRORTEXT, + MAC: macMsg + }) + } + }, + (err: any) => { + this.uploadLoading = false + if (this.fileUploadInputCompList.first) { + //clear the attached file to input + this.fileUploadInputCompList.first.nativeElement.value = '' + } + this.uploader.queue = [] + this.eventService.catchResponseError('file upload', err) + } + ) + } + + public getPendingExcelPreview() { + this.queryTextSaved = this.queryText + this.queryText = '' + + this.excelUploadState = 'Parsing' + + this.toggleHotPlugin('contextMenu', false) + + let previewDatasource: any[] = [] + + this.data.map((item) => { + let itemObject: any = {} + + this.headerShow.map((header: any, index: number) => { + itemObject[header] = item[index] + }) + + // If Delete? column is not set in the file, we set it to NO + if (!itemObject['_____DELETE__THIS__RECORD_____']) + itemObject['_____DELETE__THIS__RECORD_____'] = 'No' + + previewDatasource.push(itemObject) + }) + + this.dataSourceUnchanged = this.helperService.deepClone(this.dataSource) + + this.dataSource = previewDatasource + this.hotTable.data = previewDatasource + + const hot = this.hotInstance + + this.excelUploadState = 'Validating-HOT' + + hot.updateSettings( + { + data: this.dataSource, + maxRows: Infinity + }, + false + ) + hot.render() + + this.appendUploadState(`Validating rows`) + + hot.validateCells(() => { + this.showUploadModal = false + this.uploadPreview = true + + this.excelFileParsing = false + this.excelUploadState = null + }) + + /** + * This is half validation feature to speed up file upload + * Currently disabled but will leave it here in case it needs to be re-enabled + */ + // this.excelUploadState = 'Validating-DQ' + + // this.validateRowsOnPendingExcel( + // async (rowValidation: RowValidation | undefined) => { + // if (rowValidation) { + // this.eventService.showAbortModal( + // 'Excel validation', + // `Please fix the data and re-submit the file. Invalid data details:

Row: ${rowValidation.rowNumber}
Column: ${rowValidation.colName}
Reason: ${rowValidation.invalidError}
Invalid value: ${rowValidation.value}` + // ) + + // this.excelFileParsing = false + // this.excelUploadState = null + // } else { + // this.excelUploadState = 'Validating-HOT' + + // hot.updateSettings( + // { + // data: this.dataSource + // }, + // false + // ) + // hot.render() + + // hot.validateCells(() => { + // this.showUploadModal = false + // this.uploadPreview = true + + // this.excelFileParsing = false + // this.excelUploadState = null + // }) + // } + // } + // ) + } + + public discardPendingExcel(discardData?: boolean) { + this.hotInstance.updateSettings({ + maxRows: this.licenceState.value.editor_rows_allowed + }) + + if (discardData) this.cancelEdit() + + if (this.fileUploadInputCompList.first) { + this.fileUploadInputCompList.first.nativeElement.value = '' + } + + this.uploadPreview = false + this.excelFileReady = false + this.uploader.queue = [] + + if (!isNaN(parseInt(this.router.url.split('/').pop() || ''))) { + if (this.queryTextSaved.length > 0) { + this.queryText = this.queryTextSaved + this.queryTextSaved = '' + } + } + } + + public previewTableEditConfirm() { + this.discardPendingExcel() + this.convertToCorrectTypes(this.dataSource) + this.editTable(true) + } + + private appendUploadState(state: string, replaceLast: boolean = false) { + this.cdf.detectChanges() + + if (this.uploadStaterCompList.first) { + if (replaceLast) { + this.uploadStaterCompList.first.replaceLastState(state) + } else { + this.uploadStaterCompList.first.appendState(state) + } + } + } + + findValidHeaders( + row: string[], + headers: string[], + rowNumber: number, + tabName: string + ): Array { + let headersFound = false + let missingErrorArray = [] + let j = 0 + + while (j < row.length) { + if (headersFound) { + // return; + } else { + if (headers.indexOf(row[j]) !== -1) { + let breakIndex + let rowStart = 0 + let rowEnd = 0 + let arrStart = 0 + let foundHeadersArray: string[] = [] + let spaceBreak = false + + for (let i = j; i < row.length; i++) { + if ( + row[i] === '' || + (foundHeadersArray.indexOf(row[i]) !== -1 && + this.isColHeader(row[i])) + ) { + if (row[i] === '') { + spaceBreak = true + } + + breakIndex = i + break + } else { + foundHeadersArray.push(row[i]) + } + } + + let tempArray: string[] = [] + + if (breakIndex !== undefined) { + tempArray = row.slice(j, breakIndex) + arrStart = j + rowEnd = breakIndex + + if (spaceBreak) { + rowStart = j + j = breakIndex + } else { + rowStart = j + j = breakIndex - 1 + } + } else { + tempArray = row.slice(j) + rowStart = j + arrStart = j + rowEnd = row.length + j = row.length + } + + let foundHeaders = true + + //We check if there are missing headers + headers.forEach((x) => { + if (tempArray.indexOf(x) === -1) { + foundHeaders = false + } + }) + + if (foundHeaders) { + headersFound = true + + let mapHeaders: any[] = headers + + let csvArrayHeadersMap = mapHeaders.reduce(function (map, obj) { + map[obj] = -1 + return map + }, {}) + + let temp = row.slice(rowStart, rowEnd) + + headers.forEach((x) => { + csvArrayHeadersMap[x] = temp.indexOf(x) + rowStart + }) + + return [true, csvArrayHeadersMap] + } else { + let missingHeaders = getMissingHeaders(tempArray, headers) + + let missingMessage = 'TAB(' + tabName + ')' + missingErrorArray.push([ + missingMessage + + ' - ' + + missingHeaders[1].join(',') + + ' ( missing ' + + missingHeaders[0].join(',') + + ' )', + missingHeaders[1].length + ]) + } + } + } + j++ + } + return [false, missingErrorArray] + } + + isColPk(col: string) { + return this.headerPks.indexOf(col) > -1 + } + + isReadonlyCol(col: string | number) { + const colRules = this.dcValidator?.getRule(col) + + return colRules?.readOnly + } + + isColHeader(col: string) { + return this.headerArray.indexOf(col.toUpperCase()) > -1 + } + + removeQuery() { + this.sasStoreService.removeClause() + } + + updateDateTimeCols(headers: any, data: any) { + if (this.dateHeaders.length > 0) { + let dateCols: number[] = [] + this.dateHeaders.forEach((element) => { + if (headers.indexOf(element) !== -1) { + dateCols.push(headers.indexOf(element)) + } + }) + data.forEach((row: any[]) => { + dateCols.forEach((element) => { + const obj = row[element] + if (isStringNumber(obj.v)) { + const date = excelDateToJSDate(Number(obj.v)) + + obj.v = + date.getFullYear() + + '-' + + ('0' + (date.getMonth() + 1)).slice(-2) + + '-' + + ('0' + date.getDate()).slice(-2) + } else { + if (obj && obj.v && obj.v.toString().indexOf(':') === -1) { + const date = new Date(obj.v) + if (date.toUTCString() !== 'Invalid Date') { + obj.v = dateFormat(date) + } + } + } + row[element] = obj + }) + }) + } + if (this.timeHeaders.length > 0) { + let timeCols: number[] = [] + this.timeHeaders.forEach((element) => { + if (headers.indexOf(element) !== -1) { + timeCols.push(headers.indexOf(element)) + } + }) + data.forEach((row: any[]) => { + timeCols.forEach((element) => { + const obj = row[element] + if ( + isStringNumber(obj.v) || + isStringDecimal(obj.v) || + obj.v.includes('E-') + ) { + const date = excelDateToJSDate(Number(obj.v)) + + obj.v = dateToUtcTime(date) + } + row[element] = obj + }) + }) + } + if (this.dateTimeHeaders.length > 0) { + let dateTimeCols: number[] = [] + this.dateTimeHeaders.forEach((element) => { + if (headers.indexOf(element) !== -1) { + dateTimeCols.push(headers.indexOf(element)) + } + }) + data.forEach((row: any[]) => { + dateTimeCols.forEach((element) => { + const obj = row[element] + if (isStringNumber(obj.v) || isStringDecimal(obj.v)) { + let date = excelDateToJSDate(Number(obj.v)) + obj.v = dateFormat(date) + ' ' + dateToUtcTime(date) + } else { + if (obj.v.indexOf(' ') === -1 && obj.v.indexOf(':') !== -1) { + let str = obj.v.substring(0, obj.v.indexOf(':')) + str = str + ' ' + obj.v.substring(obj.v.indexOf(':') + 1) + obj.v = str + } + let date = new Date(obj.v) + if (date.toUTCString() !== 'Invalid Date') { + obj.v = dateFormat(date) + ' ' + dateToTime(date) + } + } + row[element] = obj + }) + }) + } + return data + } + + updateXLRuleCols(headers: any, data: any) { + if (this.xlRules.length > 0) { + const xlRuleCols: any = [] + this.xlRules.forEach((element: any) => { + if (headers.indexOf(element.XL_COLUMN) !== -1) { + element['index'] = headers.indexOf(element.XL_COLUMN) + xlRuleCols.push(element) + } + }) + data.forEach((row: any[]) => { + xlRuleCols.forEach((element: any) => { + const obj = row[element.index] + if (element.XL_RULE === 'FORMULA') { + if ('f' in obj) { + if (obj['t'] === 'n') { + obj['v'] = '=' + obj['f'] + } else { + obj['w'] = '=' + obj['f'] + } + } + } + row[element] = obj + }) + }) + } + return data + } + + private blobToFile(theBlob: Blob, fileName: string): File { + const b: any = theBlob + b.lastModifiedDate = new Date() + b.name = fileName + return b as File + } + + public toBstr(res: any) { + let bytes = new Uint8Array(res) + let binary = '' + let length = bytes.byteLength + for (let i = 0; i < length; i++) { + binary += String.fromCharCode(bytes[i]) + } + return binary + } + + async sendClause() { + this.submitLoading = true + let nullVariableArr = [] + let emptyVariablesArr = [] + + // to check number of empty clauses + if (typeof this.clauses === 'undefined') { + this.nullVariables = true + this.submitLoading = false + return + } else { + let query = this.clauses.queryObj + + if (query[0].elements.length < 1) { + // Clear cached filtering data + if (globals.rootParam === 'home' || globals.rootParam === 'editor') { + globals.editor.filter.clauses = [] + globals.editor.filter.query = [] + globals.editor.filter.groupLogic = '' + } + + // Reset filtering + this.router.navigate(['/editor/' + this.libds], { + queryParamsHandling: 'preserve' + }) + + return + } + + for (let index = 0; index < query.length; index++) { + const el = query[index].elements + nullVariableArr = el.filter(function (item: any) { + return item.variable === null + }) + if (nullVariableArr.length) { + emptyVariablesArr.push(el) + } + } + } + + if (emptyVariablesArr.length) { + this.nullVariables = true + this.submitLoading = false + return + } else { + try { + if (this.clauses !== undefined && this.libds) { + const filterQuery: FilterQuery = { + groupLogic: this.clauses.groupLogic, + filterGroups: [] + } + this.clauses.queryObj.forEach((group: any) => { + const filterGroup: FilterGroup = { + filterClauses: [] + } + group.elements.forEach((clause: any) => { + filterGroup.filterClauses.push( + this.helperService.deepClone(clause) + ) + }) + filterGroup.clauseLogic = group.clauseLogic + filterQuery.filterGroups.push( + this.helperService.deepClone(filterGroup) + ) + }) + + const filterQueryClauseTable = + this.sasStoreService.createFilterQueryTable(filterQuery) + + await this.sasStoreService + .saveQuery(this.libds, filterQueryClauseTable) + .then((res: any) => { + const id = res.result[0].FILTER_RK + const table = res.result[0].FILTER_TABLE + + this.queryFilter = { id: id, table: table } + + this.router + .navigate(['/'], { + skipLocationChange: true, + queryParamsHandling: 'preserve' + }) + .then(() => + this.router.navigate( + [ + '/editor/' + + this.queryFilter.table + + '/' + + this.queryFilter.id + ], + { + queryParamsHandling: 'preserve' + } + ) + ) + + this.filter = false + }) + .catch((err: any) => { + this.submitLoading = false + }) + } + } catch (error: any) { + this.queryErr = true + this.submitLoading = false + this.queryErrMessage = error + } + } + } + + public openQb() { + if (this.libds) { + // this.libTab = this.libds; + this.filter = true + this.cdf.detectChanges() + + this.submitLoading = false + this.sasStoreService.setQueryVariables(this.libds, this.cols) + } + } + + editTable(previewEdit?: boolean, newRow?: boolean) { + this.toggleHotPlugin('contextMenu', true) + + const hot = this.hotInstance + + let columnSorting = hot.getPlugin('multiColumnSorting') + let columnSortConfig = columnSorting.getSortConfig() + let sortConfigs = Array.isArray(columnSortConfig) + ? columnSortConfig + : [columnSortConfig] + + setTimeout(() => { + if (!previewEdit) { + this.dataSourceUnchanged = this.helperService.deepClone(this.dataSource) + if (newRow) { + this.dataSourceUnchanged.pop() + } + } + this.hotTable.readOnly = false + this.hotTable.data = this.dataSource + + hot.updateSettings( + { + readOnly: this.hotTable.readOnly + }, + false + ) + + hot.render() + + for (let sortConfig of sortConfigs) { + columnSorting.sort(sortConfig) + } + + this.reSetCellValidationValues() + }, 0) + } + + convertToCorrectTypes(dataSource: any) { + for (let row of dataSource) { + for (let colKey in row) { + let colSpecs = this.cols.find((x: any) => x.NAME === colKey) + + if (colSpecs) { + if ( + row[colKey] !== '' && + colSpecs.TYPE === 'num' && + !colSpecs.DDTYPE.includes('TIME') && + !colSpecs.DDTYPE.includes('DATE') + ) + row[colKey] = parseInt(row[colKey]) + } + } + } + } + + cancelEdit() { + this.toggleHotPlugin('contextMenu', false) + + this.cellValidationSource = [] + + const hot = this.hotInstance + let columnSorting = hot.getPlugin('multiColumnSorting') + let columnSortConfig = columnSorting.getSortConfig() + let sortConfigs = Array.isArray(columnSortConfig) + ? columnSortConfig + : [columnSortConfig] + + if (this.dataSourceUnchanged) { + this.dataSource = this.helperService.deepClone(this.dataSourceUnchanged) + } + + this.hotTable.data = this.dataSource + this.hotTable.readOnly = true + + hot.updateSettings( + { + readOnly: this.hotTable.readOnly, + data: this.dataSource + }, + false + ) + + hot.validateRows(this.modifedRowsIndexes) + // this.editRecordListeners(); + for (let sortConfig of sortConfigs) { + columnSorting.sort(sortConfig) + } + + this.checkRowLimit() + } + + timesClicked: number = 0 + public hotClicked() { + if (this.timesClicked === 1 && this.hotTable.readOnly) { + this.editTable() + } + + if (this.timesClicked === 0) { + this.timesClicked++ + + setTimeout(() => { + this.timesClicked = 0 + }, 200) + } + } + + public cleanExceed() { + this.exceedCells = [] + } + + public approversToggle() { + this.showApprovers = !this.showApprovers + } + + public addRow() { + this.addingNewRow = true + + setTimeout(() => { + const hot = this.hotInstance + + let dsInsertIndex = this.dataSource.length + hot.alter('insert_row_below', dsInsertIndex, 1) + hot.updateSettings({ data: this.dataSource }, false) + hot.selectCell(this.dataSource.length - 1, 0) + hot.render() + + if (this.dataSource[dsInsertIndex]) { + this.dataSource[dsInsertIndex]['noLinkOption'] = true + } + + this.addingNewRow = false + + this.reSetCellValidationValues() + }) + } + + public cancelSubmit() { + this.dataSource = this.helperService.deepClone(this.dataSourceBeforeSubmit) + this.dataSourceBeforeSubmit = [] + this.hotTable.data = this.dataSource + + const hot = this.hotInstance + hot.updateSettings( + { + data: this.dataSource, + colHeaders: this.headerColumns, + columns: this.cellValidation, + modifyColWidth: function (width: number, col: number) { + if (col === 0) { + return 60 + } + if (width > 500) return 500 + else return width + } + }, + false + ) + + hot.selectCell(0, 0) + hot.render() + hot.validateRows(this.modifedRowsIndexes) + + this.reSetCellValidationValues() + } + + public getRowsSubmittingCount() { + if (this.sasService.getSasjsConfig().debug) { + this.loggerService.log(this.dataSource) + this.loggerService.log(this.dataSourceUnchanged) + } + + let rowsUpdated = 0 + let rowsDeleted = 0 + let rowsAdded = 0 + this.modifedRowsIndexes = [] + this.dataModified = [] + + for (let i = 0; i < this.dataSource.length; i++) { + let dataRow = this.helperService.deepClone(this.dataSource[i]) + + if (dataRow._____DELETE__THIS__RECORD_____ === 'Yes') { + this.dataModified.push(dataRow) + rowsDeleted++ + } else { + let dataRowUnchanged = this.dataSourceUnchanged.find((row: any) => { + for (let pkCol of this.headerPks) { + if (row[pkCol] !== dataRow[pkCol]) { + return false + } + } + + return true + }) + + if (dataRowUnchanged) { + if (JSON.stringify(dataRow) !== JSON.stringify(dataRowUnchanged)) { + this.dataModified.push(dataRow) + this.modifedRowsIndexes.push(i) + rowsUpdated++ + } + } else { + this.dataModified.push(dataRow) + this.modifedRowsIndexes.push(i) + rowsAdded++ + } + } + } + + this.rowsChanged = { + rowsUpdated, + rowsDeleted, + rowsAdded + } + } + + public validatePrimaryKeys() { + const hot = this.hotInstance + + let myTable = hot.getData() + this.pkFields = [] + for (let index = 0; index < myTable.length; index++) { + let pkRow = '' + for (let ind = 1; ind < this.readOnlyFields + 1; ind++) { + pkRow = pkRow + '|' + myTable[index][ind] + } + this.pkFields.push(pkRow) + } + + let results = [] + let rows = this.dataSource.length + + for (let j = 0; j < this.pkFields.length; j++) { + for (let i = 0; i < this.pkFields.length; i++) { + if (this.pkFields[j] === this.pkFields[i] && i !== j) { + results.push(i) + } + } + } + + if (this.pkFields.length > rows) { + for (let n = rows; n < this.pkFields.length; n++) { + for (let p = rows; p < this.pkFields.length; p++) { + if (n < p && this.pkFields[n] === this.pkFields[p]) { + results.push(p) + } + } + } + } + + let cellMeta + for (let k = 0; k < results.length; k++) { + for (let index = 1; index < this.readOnlyFields + 1; index++) { + cellMeta = hot.getCellMeta(results[k], index) + cellMeta.valid = false + cellMeta.dupKey = true + hot.render() + } + } + + this.duplicatePkIndexes = [...new Set(results.sort())] + } + + /** + * After any change or update to the hot datasource we lose cell validation values. + * This function is called in those places, to update all cells with values if existing. + * Note that was discussed: + * Rows with same data does not have arrows until you click on them (arrows gets lost after addRow) + * That is because this function resets the values for the found hashes, and if multiple rows have same data, + * hash table contains only first row that is hashed, so others don't get arrow re-set + * + * @param specificRowForceValue re-set will apply force values only to this row. That is used in cases + * when we don't want to re-set force values of every row in the table + */ + public reSetCellValidationValues( + setForcedValues: boolean = false, + specificRowForceValue?: number + ) { + const hot = this.hotInstance + + for (let entry of this.cellValidationSource) { + const colSource = entry.values.map( + (el: any) => el[this.cellValidationFields.RAW_VALUE] + ) + + hot.batch(() => { + const cellMeta = hot.getCellMeta(entry.row, entry.col) + const cellRule = this.dcValidator?.getRule( + (cellMeta.data as string) || '' + ) + let cellSource: string[] | number[] | undefined + + if (cellRule) { + cellSource = this.dcValidator?.getDqDropdownSource(cellRule) + } + + if (!cellSource) cellSource = [] + + const combinedSource = [...new Set([...cellSource, ...colSource])] + + this.currentEditRecordValidator?.updateRule(entry.col, { + source: combinedSource + }) + + hot.setCellMeta(entry.row, entry.col, 'source', combinedSource) + + if (entry.values.length > 0) { + hot.setCellMeta(entry.row, entry.col, 'renderer', 'autocomplete') + hot.setCellMeta(entry.row, entry.col, 'editor', 'autocomplete') + hot.setCellMeta(entry.row, entry.col, 'strict', entry.strict) + hot.setCellMeta(entry.row, entry.col, 'filter', false) + + this.currentEditRecordValidator?.updateRule(entry.col, { + renderer: 'autocomplete', + editor: 'autocomplete', + strict: entry.strict, + filter: false + }) + } + + this.reSetExtendedCellValidationValues( + entry, + undefined, + setForcedValues, + specificRowForceValue + ) + + hot.render() + }) + } + } + + public reSetExtendedCellValidationValues( + cellValidationEntry?: CellValidationSource, + row?: number, + setForcedValues: boolean = false, + specificRowForceValue?: number + ) { + const hot = this.hotInstance + + if (cellValidationEntry) { + if (!row) row = cellValidationEntry.row + + const extendedValuesObject = + this.getExtendedValuesByCellValue(cellValidationEntry) + + this.setExtendedValuesToCells( + cellValidationEntry, + row, + extendedValuesObject, + setForcedValues, + specificRowForceValue + ) + + return + } + + for (let entry of this.cellValidationSource) { + const extendedValuesObject = this.getExtendedValuesByCellValue(entry) + + this.setExtendedValuesToCells( + entry, + entry.row, + extendedValuesObject, + setForcedValues, + specificRowForceValue + ) + } + } + + private setExtendedValuesToCells( + cellValidationEntry: CellValidationSource, + row: number, + extendedValues: DynamicExtendedCellValidation[], + setForcedValues: boolean = false, + specificRowForceValue?: number + ) { + const hot = this.hotInstance + + let uniqueCells: any[] = [] + + for (let element of extendedValues) { + if (uniqueCells.indexOf(element.EXTRA_COL_NAME) < 0) + uniqueCells.push(element.EXTRA_COL_NAME) + } + + for (let cell of uniqueCells) { + const valuesForCol = extendedValues.filter( + (x) => x.EXTRA_COL_NAME === cell + ) + let colSource: any = valuesForCol.map( + (el: DynamicExtendedCellValidation) => + el.DISPLAY_TYPE === 'C' ? el.RAW_VALUE_CHAR : el.RAW_VALUE_NUM + ) + const cellCol = hot.propToCol(cell) + const dynamicValidationEl = + this.disabledBasicDynamicCellValidationMap.find( + (x) => x.row === row && x.col === cellCol + ) + + if (!dynamicValidationEl) { + this.disabledBasicDynamicCellValidationMap.push({ + row, + col: cellCol, + active: false + }) + } + + hot.setCellMeta(row, cellCol, 'renderer', 'autocomplete') + hot.setCellMeta(row, cellCol, 'editor', 'autocomplete') + hot.setCellMeta(row, cellCol, 'strict', cellValidationEntry.strict) + hot.setCellMeta(row, cellCol, 'filter', false) + + this.currentEditRecordValidator?.updateRule(cellCol, { + renderer: 'autocomplete', + editor: 'autocomplete', + strict: cellValidationEntry.strict, + filter: false + }) + + const cellMeta = hot.getCellMeta(row, cellCol) + + const cellRule = this.dcValidator?.getRule( + (cellMeta.data as string) || '' + ) + let cellSource: string[] | number[] | undefined + + if (cellRule) { + cellSource = this.dcValidator?.getDqDropdownSource(cellRule) + } + + if (!cellSource) cellSource = [] + + if (cellRule?.type === 'numeric') { + cellSource = this.helperService.convertArrayValues( + cellSource, + 'number' + ) as number[] + colSource = this.helperService.convertArrayValues( + colSource, + 'number' + ) as number[] + } else { + cellSource = this.helperService.convertArrayValues( + cellSource, + 'string' + ) as string[] + colSource = this.helperService.convertArrayValues( + colSource, + 'string' + ) as string[] + } + + const combinedSource = [...new Set([...cellSource, ...colSource])] + + hot.setCellMeta(row, cellCol, 'source', combinedSource) + + this.currentEditRecordValidator?.updateRule(cellCol, { + source: combinedSource + }) + + if (setForcedValues) { + if (specificRowForceValue && specificRowForceValue !== row) { + return + } + + const forceValue = valuesForCol.find( + (x: DynamicExtendedCellValidation) => x.FORCE_FLAG === 1 + ) + + if (forceValue) { + // Adding timeout here makes forced values cell to re-validate itself + setTimeout(() => { + hot.setDataAtCell( + row, + cellCol, + forceValue.DISPLAY_TYPE === 'C' + ? forceValue.RAW_VALUE_CHAR + : forceValue.RAW_VALUE_NUM, + 'force_cell_validation_value' + ) + + if (this.currentEditRecordIndex === row) { + this.dataSource[this.currentEditRecordIndex][cell] = + forceValue.DISPLAY_TYPE === 'C' + ? forceValue.RAW_VALUE_CHAR + : forceValue.RAW_VALUE_NUM + } + }) + } + } + } + } + + /** + * Parses values of extended cell validation for the given dynamic cell validation entry + * @param cellValidationEntry stored dynamic cell validation entry from which to parse extended validation values + * @param rowOverride if not provided, row that is used is row found in `cellValidationEntry`. This is needed when for example we change the w in hot + * we need to get `cellValue` from that row and not from hashed cell validation source. + * @returns extended values object + */ + private getExtendedValuesByCellValue( + cellValidationEntry: CellValidationSource, + rowOverride?: number + ): DynamicExtendedCellValidation[] { + const hot = this.hotInstance + + const cellValue = hot.getDataAtCell( + rowOverride ? rowOverride : cellValidationEntry.row, + cellValidationEntry.col + ) + const valueIndex = (cellValidationEntry.values.find( + (x) => x[this.cellValidationFields.RAW_VALUE] === cellValue + ) || [])[this.cellValidationFields.DISPLAY_INDEX] + + const filteredValues = cellValidationEntry.extended_values?.filter( + (x) => x[0] === valueIndex + ) + const prepObj = this.helperService.deepClone( + this.extendedCellValidationFields + ) + + const extendedValuesObject = [] + + for (let extendedValue of filteredValues || []) { + let tempObj: any = {} + + for (let key of Object.keys(prepObj)) { + tempObj[key] = extendedValue[prepObj[key]] + } + + extendedValuesObject.push(tempObj) + } + + return extendedValuesObject + } + + public checkSave() { + this.getRowsSubmittingCount() + + if ( + this.rowsChanged.rowsAdded === 0 && + this.rowsChanged.rowsUpdated === 0 && + this.rowsChanged.rowsDeleted === 0 + ) { + this.badEditTitle = 'No changes to submit' + this.badEditCause = 'Please modify some values and try again.' + this.badEdit = true + return + } + + const hot = this.hotInstance + + this.dataSourceBeforeSubmit = this.helperService.deepClone(this.dataSource) + + for (let i = 0; i < this.dataSource.length; i++) { + delete this.dataSource[i].noLinkOption + } + + hot.updateSettings( + { + data: this.dataSource, + colHeaders: this.headerColumns, + columns: this.cellValidation, + modifyColWidth: function (width: number, col: number) { + if (width > 500) return 500 + else return width + } + }, + false + ) + + this.reSetCellValidationValues() + + EditorComponent.cnt = 0 + EditorComponent.nonPkCnt = 0 + // this.saveLoading = true; + + /** + * Below code should be analized, not sure what is the purpose of exceedCells + */ + let myTableData = hot.getData() + + // If the last row is empty, remove it before validation + if (myTableData.length > 1 && hot.isEmptyRow(myTableData.length - 1)) { + hot.alter('remove_row', myTableData.length - 1) + } + + this.validatePrimaryKeys() + + if (this.duplicatePkIndexes.length !== 0) { + this.pkDups = true + this.submit = false + this.cancelSubmit() + return + } else { + this.pkDups = false + } + + hot.validateRows(this.modifedRowsIndexes, () => { + if (this.checkInvalid()) { + let abortMsg = 'Invalid Values are Present' + + this.eventService.showInfoModal('Validation error', abortMsg) + + return + } + + this.submit = true + this.validationDone = 1 + + setTimeout(() => { + let txt: any = document.getElementById('formFields_8') + txt.focus() + }) + }) + + // let cnt = 0; + // hot.addHook("afterValidate", () => { + // this.updateSoftSelectColumns(true); + // cnt++; + // if (cnt === long) { + // this.validationDone = 1; + // } + // }); + } + + public async saveTable(data: any) { + const hot = this.hotInstance + let hotData = hot.getData() + + data = data.filter((dataRow: any) => { + let elModified = this.dataModified.find((row) => { + for (let pkCol of this.headerPks) { + if (row[pkCol] !== dataRow[pkCol]) { + return false + } + } + + return true + }) + + return !!elModified + }) + + data = data.map((row: any) => { + let deleteColValue = row['_____DELETE__THIS__RECORD_____'] + + delete row['_____DELETE__THIS__RECORD_____'] + row['_____DELETE__THIS__RECORD_____'] = deleteColValue + + // If cell is numeric and value is dot `.` we change it to `null` + Object.keys(row).map((key: string) => { + const colRule = this.dcValidator?.getRule(key) + + if (colRule?.type === 'numeric' && row[key] === '.') row[key] = null + }) + + return row + }) + + this.loggerService.log('Data submitted', data) + + if (this.checkInvalid()) { + let abortMsg = 'Invalid Values are Present' + this.eventService.showInfoModal('Validation error', abortMsg) + this.cancelSubmit() + this.submit = false + return + } + + this.validationDone = 0 + this.saveLoading = true + + if ( + EditorComponent.cnt < 1 && + this.duplicatePkIndexes.length === 0 && + EditorComponent.nonPkCnt < 1 + ) { + this.saveLoading = true + this.disableSubmit = false + this.submit = true + let updateParams: any = {} + updateParams.ACTION = 'LOAD' + this.message = this.message.replace(/\n/g, '. ') + updateParams.MESSAGE = this.message + // updateParams.APPROVER = this.approver; + updateParams.LIBDS = this.libds + + if (this.cols) { + const submitData = data.slice( + 0, + this.licenceState.value.submit_rows_limit + ) + + const success = await this.sasStoreService + .updateTable( + updateParams, + submitData, + 'SASControlTable', + 'editors/stagedata', + this.$dataFormats + ) + .then((res: any) => { + if (typeof res.sasparams !== 'undefined') { + this.router.navigateByUrl('/stage/' + res.sasparams[0].DSID) + + return true + } + + let error = `Submit request failed` + + if (res) { + let errorText = + typeof res === 'string' ? res : JSON.stringify(res) + + error += `\n${errorText}` + } + + this.eventService.showAbortModal( + 'editors/stagedata', + error, + null, + 'Submit error' + ) + }) + .catch((err: any) => { + console.log('err', err) + EditorComponent.cnt = 0 + EditorComponent.nonPkCnt = 0 + this.disableSubmit = true + this.submit = false + + let errorText = typeof err === 'string' ? err : JSON.stringify(err) + + this.eventService.showAbortModal( + 'editors/stagedata', + `Submit request failed\n${errorText}`, + null, + 'Submit error' + ) + + return false + }) + + if (success) return //stop code execution if route redirected + } + } + + if (EditorComponent.cnt >= 1) { + this.pkNull = true + this.submit = true + } else { + this.submit = false + } + if (EditorComponent.nonPkCnt >= 1) { + this.noPkNull = true + this.submit = true + } else { + this.submit = false + } + + this.cancelSubmit() + EditorComponent.cnt = 0 + EditorComponent.nonPkCnt = 0 + this.disableSubmit = true + } + + public validatorRuleSource(colName: string) { + return this.dcValidator?.getRule(colName) + } + + public checkInvalid() { + const hotElement = (this.hotInstanceCompList.first.container as any) + .nativeElement + const invalidCells = hotElement.querySelectorAll('.htInvalid') + + return invalidCells.length > 0 + } + + public goToEditor() { + this.router.navigateByUrl('/') + } + + closeRecordEdit(confirmButtonClicked?: boolean) { + this.currentEditRecordIndex = -1 + this.currentEditRecord = undefined + this.currentEditRecordValidator = undefined + + if (this.recordAction === 'ADD' && !confirmButtonClicked) { + this.dataSource = this.helperService.deepClone(this.prevDataSource) + + const hot = this.hotInstance + + hot.updateSettings( + { + data: this.dataSource + }, + false + ) + } + } + + confirmRecordEdit(close: boolean = true) { + const closingRecordIndex = this.currentEditRecordIndex + + if (close) this.currentEditRecordIndex = -1 + + this.columnHeader.map((colName: string) => { + const value = this.currentEditRecord[colName] + const isNum = this.$dataFormats?.vars[colName]?.type === 'num' + const specialMissing = isSpecialMissing(value) + + if (isNum && !isNaN(value) && !specialMissing) { + this.currentEditRecord[colName] = value * 1 + } + }) + + this.dataSource[closingRecordIndex] = this.currentEditRecord + this.hotTable.data[closingRecordIndex] = this.currentEditRecord + + const hot = this.hotInstance + + hot.updateSettings( + { + data: this.dataSource + }, + false + ) + + if (close) this.currentEditRecord = undefined + } + + onNextRecord() { + this.confirmRecordEdit(false) + this.currentEditRecordIndex = + this.currentEditRecordIndex >= this.dataSource.length - 1 + ? 0 + : this.currentEditRecordIndex + 1 + this.editRecord(null, this.currentEditRecordIndex) + } + + onPreviousRecord() { + this.confirmRecordEdit(false) + this.currentEditRecordIndex = + this.currentEditRecordIndex <= 0 + ? this.dataSource.length - 1 + : this.currentEditRecordIndex - 1 + this.editRecord(null, this.currentEditRecordIndex) + } + + addRecordButtonClick() { + if (this.restrictions.restrictAddRecord) { + this.eventService.showDemoLimitModal('Add Record') + return + } + + this.addEditNewRecord() + } + + addEditNewRecord() { + this.addRecord() + setTimeout(() => { + this.editRecord(null, this.dataSource.length - 1, true) + }, 1000) + } + + addRecord() { + this.addRow() + } + + editRecord(item: Element | null, index?: number, newRecord?: boolean) { + if (this.restrictions.restrictEditRecord) { + this.eventService.showDemoLimitModal('Edit Record') + return + } + + if (index === undefined || index < 0) return + + if (this.restrictions.restrictEditRecord) { + return + } + + this.recordAction = newRecord ? 'ADD' : 'EDIT' + + if (this.hotTable.readOnly) { + this.editTable(false, newRecord) + } + + // Create copy of DC validator to be used in RECORD MODAL + this.currentEditRecordValidator = this.helperService.deepClone( + this.dcValidator + ) + + if (newRecord) { + this.prevDataSource = this.helperService.deepClone(this.dataSource) + this.prevDataSource.pop() + } else { + const currentEditRecordCellsMeta = this.helperService.deepClone( + this.hotInstance.getCellMetaAtRow( + index + ) as Partial[] + ) + + // Update that copy with current cells meta (dynamic validation data) + for (let cellMeta of currentEditRecordCellsMeta) { + if (cellMeta) { + const data = cellMeta.prop?.toString() //------------ + delete cellMeta.prop // We convert to be able to update dcValidator rule by using CellProperties + delete cellMeta.data //----------------- + + this.currentEditRecordValidator?.updateRule(cellMeta.col!, { + ...cellMeta, + data: data + }) + } + } + } + + this.currentEditRecordIndex = index + this.currentEditRecord = this.helperService.deepClone( + this.dataSource[index] + ) + } + + toggleHotPlugin(pluginName: string, enable: boolean) { + const hot = this.hotInstance + + hot.batch(() => { + let contextMenuPlugin = hot.getPlugin(pluginName) + + if (!contextMenuPlugin) { + console.warn( + 'Toggle Hot Plugin failed - Plugin named: ' + + pluginName + + ' - could not be found.' + ) + return + } + + setTimeout(() => { + if (enable) { + contextMenuPlugin.enablePlugin() + return + } + + contextMenuPlugin.disablePlugin() + }, 100) + + hot.render() + }) + } + + private dynamicCellValidationDisabled(row: number, col: number) { + const rowColFound = this.disabledBasicDynamicCellValidationMap.find( + (x) => x.row === row && x.col === col && !x.active + ) + + return !!rowColFound + } + + /** + * This function takes row and column numbers for the cel to be validated and pouplated with values. + * It will send the row values without the current column to the sas. + * Sas will return values and if length greater then zero cel becomes dropdown type and values from sas + * put to source. + * @param row handsontable row + * @param column handsontable column + */ + public dynamicCellValidation(row: number, column: number) { + if (this.dynamicCellValidationDisabled(row, column)) return + + const hot = this.hotInstance + + const cellMeta = hot.getCellMeta(row, column) + + if (cellMeta.readOnly) return + + const cellData = hot.getDataAtCell(row, column) + const clickedRow = this.helperService.deepClone(this.dataSource[row]) + const clickedColumnKey = Object.keys(clickedRow)[column] + + /** + * We will hash the row (without current column) so later we check if hash is the same + * we set the values relative to that hash + * if not we fire the request. + */ + const hashedRow = this.helperService.deleteKeysAndHash( + clickedRow, + [clickedColumnKey, 'noLinkOption'], + false + ) + + const validationSourceIndex = this.cellValidationSource.findIndex( + (entry: CellValidationSource) => entry.hash === hashedRow + ) + + /** + * Set the values for found hash. + */ + + if (validationSourceIndex > -1) { + let colSource = this.cellValidationSource[ + validationSourceIndex + ].values.map((el) => el[this.cellValidationFields.RAW_VALUE]) + + const cellHadSource = + (hot.getCellMeta(row, column).source || []).length < 1 + const cellHasValue = cellData !== ' ' + + hot.batch(() => { + const cellMeta = hot.getCellMeta(row, column) + + const cellRule = this.dcValidator?.getRule( + (cellMeta.data as string) || '' + ) + let cellSource: string[] | number[] | undefined + + if (cellRule) { + cellSource = this.dcValidator?.getDqDropdownSource(cellRule) + } + + if (!cellSource) cellSource = [] + + if (cellRule?.type === 'numeric') { + cellSource = this.helperService.convertArrayValues( + cellSource, + 'number' + ) as number[] + colSource = this.helperService.convertArrayValues( + colSource, + 'number' + ) as number[] + } else { + cellSource = this.helperService.convertArrayValues( + cellSource, + 'string' + ) as string[] + colSource = this.helperService.convertArrayValues( + colSource, + 'string' + ) as string[] + } + + const cellSourceCombined = [...new Set([...cellSource, ...colSource])] + + hot.setCellMeta(row, column, 'source', cellSourceCombined) + + this.currentEditRecordValidator?.updateRule(column, { + source: cellSourceCombined + }) + + if ( + this.cellValidationSource[validationSourceIndex].values.length > 0 + ) { + const strict = this.cellValidationSource[validationSourceIndex].strict + + hot.setCellMeta(row, column, 'renderer', 'autocomplete') + hot.setCellMeta(row, column, 'editor', 'autocomplete') + hot.setCellMeta(row, column, 'strict', strict) + hot.setCellMeta(row, column, 'filter', false) + + this.currentEditRecordValidator?.updateRule(column, { + renderer: 'autocomplete', + editor: 'autocomplete', + strict: strict, + filter: false + }) + } + + this.reSetExtendedCellValidationValues( + this.cellValidationSource[validationSourceIndex], + row, + cellHadSource && cellHasValue + ) + + hot.render() + }) + } + + /** + * Send request to sas. + */ + if (validationSourceIndex < 0) { + const data = { + SASControlTable: [ + { + libds: this.libds, + variable_nm: clickedColumnKey + } + ], + source_row: [clickedRow] + } + + const validationHook = this.dcValidator + ?.getDqDetails(clickedColumnKey) + .find( + (rule: DQRule) => + rule.RULE_TYPE === 'SOFTSELECT_HOOK' || + rule.RULE_TYPE === 'HARDSELECT_HOOK' + ) + + /** + * Do the validation only if current column has validation hooks in place. + */ + if (validationHook) { + this.cellValidationSource.push({ + row: row, + col: column, + strict: validationHook.RULE_TYPE === 'HARDSELECT_HOOK', + values: [], + hash: hashedRow, + count: this.cellValidationSource.length + 1 + }) + + hot.setCellMeta(row, column, 'renderer', spinnerRenderer) + this.currentEditRecordLoadings.push(column) + hot.render() + + this.sasService + .request('editors/getdynamiccolvals', data, undefined, { + suppressSuccessAbortModal: true, + suppressErrorAbortModal: true + }) + .then((res: any) => { + const colSource = res.dynamic_values.map( + (el: any) => el[this.cellValidationFields.RAW_VALUE] + ) + + if (colSource.length > 0) { + const validationSourceIndex = this.cellValidationSource.findIndex( + (entry: CellValidationSource) => entry.hash === hashedRow + ) + + if (validationSourceIndex > -1) { + this.cellValidationSource[validationSourceIndex] = { + ...this.cellValidationSource[validationSourceIndex], + row: row, + col: column, + values: res.dynamic_values, + extended_values: res.dynamic_extended_values + } + } + + //Removing the spinner from cell, so validation not fail + hot.setCellMeta(row, column, 'renderer', noSpinnerRenderer) + this.currentEditRecordLoadings.splice( + this.currentEditRecordLoadings.indexOf(column), + 1 + ) + hot.deselectCell() + hot.render() + + /** + * `cells` function of hot settings is remembering the old state of component + * we need to update it here after we set new `cellValidationSource` (validation lookup hash table) values + * so that it will check those values to decide whether numeric cells should be + * converted to the dropdown + */ + + hot.batch(() => { + /** + * In the case that the original value is not included in the newly created cell dropdown + * and validation type is HARDSELECT, the cell shoud be red + */ + setTimeout(() => { + this.reSetCellValidationValues(true, row) + hot.render() + + hot.validateRows([row]) + }, 100) + }) + } + + //Removing the spinner from cell, so validation not fail + hot.setCellMeta(row, column, 'renderer', noSpinnerRenderer) + this.currentEditRecordLoadings.splice( + this.currentEditRecordLoadings.indexOf(column), + 1 + ) + hot.deselectCell() + hot.render() + + /** + * If hash table limit reached, remove the oldest element. + * Oldest element is element with lowest `count` number. + */ + if (this.cellValidationSource.length > this.validationTableLimit) { + const oldestElement = this.cellValidationSource.reduce( + (prev, curr) => (prev.count < curr.count ? prev : curr) + ) + const oldestElementIndex = + this.cellValidationSource.indexOf(oldestElement) + + this.cellValidationSource.splice(oldestElementIndex, 1) + } + }) + .catch((err: any) => { + const currentRowHashIndex = this.cellValidationSource.findIndex( + (x) => x.hash === hashedRow + ) + + this.cellValidationSource.splice(currentRowHashIndex, 1) + + hot.batch(() => { + // Render error icon inside a cell + hot.setCellMeta(row, column, 'renderer', errorRenderer) + + hot.render() + }) + + //Stop edit record modal loading spinner + this.currentEditRecordLoadings.splice( + this.currentEditRecordLoadings.indexOf(column), + 1 + ) + + //Show error on edit record modal + this.currentEditRecordErrors.push(column) + + // After waiting time remove the error icon from cell and edit record modal field + setTimeout(() => { + hot.setCellMeta(row, column, 'renderer', noSpinnerRenderer) + hot.render() + + //Remove error icon on the edit record modal field + this.currentEditRecordErrors.splice( + this.currentEditRecordErrors.indexOf(column), + 1 + ) + }, 3000) + + this.reSetCellValidationValues() + + this.loggerService.log('getdynamiccolvals error:', err) + }) + } + } + } + + checkEmptyRowWhenFilter() { + this.zeroFilterRows = false + + if ( + typeof this.filter_pk !== 'undefined' && + this.hotTable.data.length === 1 + ) { + if ([null, ''].includes(this.hotTable.data[0][this.headerPks[0]])) + this.zeroFilterRows = true + } + } + + onRecordInputFocus(event: EditRecordInputFocusedEvent) { + this.dynamicCellValidation(this.currentEditRecordIndex, event.colName) + } + + executeDynamicCellValidationIfApplicable(colProp: any, col: any, row: any) { + const hashedRow = this.helperService.deleteKeysAndHash( + this.dataSource[row], + [colProp, 'noLinkOption'] + ) + + const cellValidation = this.cellValidationSource.find( + (entry: CellValidationSource) => + entry.hash === hashedRow && col === entry.col + ) + + if ( + cellValidation && + cellValidation.extended_values && + cellValidation.extended_values.length > 0 + ) { + const extendedValidationObject = this.getExtendedValuesByCellValue( + cellValidation, + row + ) + + this.setExtendedValuesToCells( + cellValidation, + row, + extendedValidationObject, + true + ) + } + } + + viewboxManager() { + this.viewboxes = true + } + + get totalRowsChanged() { + return ( + this.rowsChanged.rowsUpdated + + this.rowsChanged.rowsDeleted + + this.rowsChanged.rowsAdded + ) + } + + async ngOnInit() { + this.licenceService.hot_license_key.subscribe( + (hot_license_key: string | undefined) => { + this.hotTable.licenseKey = hot_license_key + } + ) + + this._query = this.sasStoreService.query.subscribe((query: any) => { + if (query.libds === this.libds) { + this.whereString = query.string + this.clauses = query.obj + // this.libds = query.libds + } + }) + + // recover lib and table parameters from url; filter pk is optional - if filter is applied + let myParams: any = {} + if (typeof this.route.snapshot.params['libMem'] !== 'undefined') { + this.libds = this.route.snapshot.params['libMem'] + this.filter_pk = this.route.snapshot.params['filterId'] + + if (this.route.snapshot.url[0].path === 'edit-record') { + if (typeof this.filter_pk !== 'undefined') { + this.recordAction = 'EDIT' + } else { + this.recordAction = 'ADD' + } + } + + myParams.LIBDS = this.libds + if (typeof this.filter_pk !== 'undefined') { + myParams.FILTER_RK = parseInt(this.filter_pk) + } + myParams.OUTDEST = 'WEB' + + if (this.libds) { + globals.editor.library = this.libds.split('.')[0] + globals.editor.table = this.libds.split('.')[1] + } + } + + if (this.libds) { + this.getdataError = false + + await this.sasStoreService + .callService(myParams, 'SASControlTable', 'editors/getdata', this.libds) + .then((res: EditorsGetdataServiceResponse) => { + this.initSetup(res) + }) + .catch((err: any) => { + this.getdataError = true + this.tableTrue = true + }) + } + } + + ngAfterViewInit() {} + + initSetup(response: EditorsGetdataServiceResponse) { + this.hotInstance = this.hotRegisterer.getInstance('hotInstance') + + if (this.getdataError) return + if (!response) return + if (!response.data) return + + this.cols = response.data.cols + this.dsmeta = response.data.dsmeta + + const hot: Handsontable = this.hotInstance + + const approvers: Approver[] = response.data.approvers + + if (this.cols) { + this.headerArray = parseTableColumns(this.cols) + } + // Note: the above this.headerArray is being reassigned without being used. + // So, above assignment does not make sense. + + approvers.forEach((item: Approver) => { + this.approvers.push(item.PERSONNAME) + }) + + this.tableTrue = true + this.libds = response.libds + this.hotTable.data = response.data.sasdata + + this.headerColumns = response.data.sasparams[0].COLHEADERS.split(',') + this.headerPks = response.data.sasparams[0].PK.split(' ') + this.columnLevelSecurityFlag = !!response.data.sasparams[0].CLS_FLAG + + if (this.columnLevelSecurityFlag) + this.setRestrictions({ + restrictAddRow: true, + removeEditRecordButton: true, + removeAddRecordButton: true + }) + + this.checkEmptyRowWhenFilter() + + if (this.headerColumns.indexOf('_____DELETE__THIS__RECORD_____') !== -1) { + this.headerColumns[ + this.headerColumns.indexOf('_____DELETE__THIS__RECORD_____') + ] = 'Delete?' + } + + this.headerArray = this.headerColumns.slice(1) + + if (response.data.sasparams[0].DTVARS !== '') { + this.dateHeaders = response.data.sasparams[0].DTVARS.split(' ') + } + if (response.data.sasparams[0].TMVARS !== '') { + this.timeHeaders = response.data.sasparams[0].TMVARS.split(' ') + } + if (response.data.sasparams[0].DTTMVARS !== '') { + this.dateTimeHeaders = response.data.sasparams[0].DTTMVARS.split(' ') + } + if (response.data.xl_rules.length > 0) { + this.xlRules = this.helperService.deepClone(response.data.xl_rules) + } + + this.dcValidator = new DcValidator( + response.data.sasparams[0], + response.data.$sasdata, + this.cols, + response.data.dqrules, + response.data.dqdata + ) + + this.cellValidation = this.dcValidator.getRules() + + // to take datasource + this.dataSource = response.data.sasdata + this.$dataFormats = response.data.$sasdata + + // Note: this.headerColumns and this.columnHeader contains same data + // need to resolve redundancy + + // default schema + for (let i = 0; i < this.headerColumns.length; i++) { + const colType = this.cellValidation[i].type + + this.hotDataSchema[this.cellValidation[i].data] = getHotDataSchema( + colType, + this.cellValidation[i] + ) + } + + // this.addActionButtons(); + // this.addActionColumns(); + // now all validation params we have in this.cellValidation + + this.checkRowLimit() + + hot.updateSettings( + { + data: this.dataSource, + colHeaders: this.headerColumns, + columns: this.cellValidation, + height: this.hotTable.height, + formulas: this.hotTable.formulas, + stretchH: 'all', + readOnly: this.hotTable.readOnly, + hiddenColumns: { + indicators: true, + columns: this.dcValidator.getHiddenColumns() + }, + modifyColWidth: function (width: number, col: number) { + if (col === 0) { + return 60 + } + if (width > 500) return 500 + else return width + }, + copyPaste: this.hotTable.copyPaste, + manualColumnFreeze: false, //https://handsontable.com/docs/7.0.3/demo-freezing.html + // false due to https://forum.handsontable.com/t/gh-5112-column-freeze-sorting/3236 + multiColumnSorting: true, // https://handsontable.com/docs/7.0.0/demo-multicolumn-sorting.html + manualColumnResize: true, + filters: false, + manualRowResize: true, + viewportRowRenderingOffset: 50, + // show a bar on the left to enable users to select an entire row + rowHeaders: (index: number) => { + return ' ' + }, + rowHeaderWidth: 15, + rowHeights: 24, + maxRows: this.licenceState.value.editor_rows_allowed || Infinity, + invalidCellClassName: 'htInvalid', + dropdownMenu: { + items: { + make_read_only: { + name: 'make_read_only' + }, + alignment: { + name: 'alignment' + }, + sp1: { + name: '---------' + }, + info: { + name: 'test info', + renderer: ( + hot: Handsontable.Core, + wrapper: HTMLElement, + row: number, + col: number, + prop: string | number, + itemValue: string + ) => { + const elem = document.createElement('span') + let colInfo: DataFormat | undefined + let textInfo = 'No info found' + + if (this.hotInstance) { + const hotSelected: [number, number, number, number][] = + this.hotInstance.getSelected() || [] + const selectedCol: number = hotSelected + ? hotSelected[0][1] + : -1 + const colName = this.hotInstance?.colToProp(selectedCol) + colInfo = this.$dataFormats?.vars[colName] + + if (colInfo) + textInfo = `LABEL: ${colInfo?.label}
TYPE: ${colInfo?.type}
LENGTH: ${colInfo?.length}
FORMAT: ${colInfo?.format}` + } + + elem.innerHTML = textInfo + + return elem + } + } + } + }, + // filters: true, + dataSchema: this.hotDataSchema, + contextMenu: this.hotTable.settings.contextMenu, + //, '---------','freeze_column','unfreeze_column'], + currentHeaderClassName: 'customH', + afterGetColHeader: (col: number, th: any) => { + const column = this.columnHeader[col] + + // header columns styling - primary keys + const isPKCol = column && this.isColPk(column) + const isReadonlyCol = column && this.isReadonlyCol(column) + + if (isPKCol) th.classList.add('primaryKeyHeaderStyle') + if (isReadonlyCol && !isPKCol) th.classList.add('readonlyCell') + + // Remove header arrow from Delete column + if (col === 0) { + th.classList.add('firstColumnHeaderStyle') + } + }, + afterGetCellMeta: ( + row: number, + col: number, + cellProperties: Handsontable.CellProperties + ) => { + const isReadonlyCol = col && this.isReadonlyCol(col) + if (isReadonlyCol) cellProperties.className = 'readonlyCell' + } + }, + false + ) + + this.hotTable.hidden = false + this.toggleHotPlugin('contextMenu', false) + /** + * This is needed if freeze column is enabled + */ + // hot.getPlugin('manualColumnFreeze').freezeColumn(0); + + this.queryText = response.data.sasparams[0].FILTER_TEXT + this.columnHeader = response.data.sasparams[0].COLHEADERS.split(',') + // First column is always used to mark records for deletion + this.columnHeader[0] = 'Delete?' + this.readOnlyFields = response.data.sasparams[0].PKCNT + + let hotInstaceEl = document.getElementById('hotInstance') + + if (hotInstaceEl) { + hotInstaceEl.addEventListener('mousedown', (event) => { + if (!this.uploadPreview) { + this.hotClicked() + } + + setTimeout(() => { + let menuDebugItem: any = + document.querySelector('.debug-switch-item') || undefined + if (menuDebugItem) menuDebugItem.click() + }, 100) + }) + } + + hot.addHook( + 'afterSelection', + ( + row: number, + column: number, + row2: number, + column2: number, + preventScrolling: any, + selectionLayerLevel: any + ) => { + /** + * This is needed if freeze column is enabled + */ + // if (column === 0) { + // delete contextMenuToSet.items.unfreeze_column; + // } + + if ( + row === row2 && + column === column2 && + this.hotTable.readOnly === false + ) { + this.dynamicCellValidation(row, column) + } + + /** + * This is needed if freeze column is enabled + */ + // if (column === 0) { + // if (!this.firstColumnSelected) { + // hot.updateSettings({ + // contextMenu: contextMenuToSet + // }); + // this.firstColumnSelected = true; + // } + // } else { + // if (this.firstColumnSelected) { + // hot.updateSettings({ + // contextMenu: contextMenuToSet + // }); + // this.firstColumnSelected = false; + // } + // } + } + ) + + hot.addHook('beforeKeyDown', (e: any) => { + const hotSelected = this.hotInstance.getSelected() + const selection = hotSelected ? hotSelected[0] : hotSelected + + // When we open a dropdown we want filter disabled so value in cell + // don't filter out items, since we want to see them all. + // When we start typing, we are enabling the filter since we want to find + // values faster. + if (selection) { + const startRow = selection[0] + const endRow = selection[2] + const startCell = selection[1] + const endCell = selection[3] + + if (startRow === endRow && startCell === endCell) { + const cellMeta = this.hotInstance.getCellMeta(startRow, startCell) + + if (cellMeta && cellMeta.filter === false) { + this.hotInstance.setCellMeta(startRow, startCell, 'filter', true) + } + } + } + }) + + hot.addHook('afterChange', (source: any, change: any) => { + if (change === 'edit') { + const hot = this.hotInstance + + const row = source[0][0] + const colProp = source[0][1] + const col = hot.propToCol(colProp) + + // On edit we enabled filter for this cell, now when editing is finished + // We want filter to be disabled again, to be ready for next dropdown opening. + const cellMeta = hot.getCellMeta(row, col) + if (cellMeta && cellMeta.filter === false) + hot.setCellMeta(row, col, 'filter', true) + + this.executeDynamicCellValidationIfApplicable(colProp, col, row) + } + }) + + hot.addHook('afterRender', (isForced: boolean) => { + this.eventService.dispatchEvent('resize') + }) + + hot.addHook('afterCreateRow', (source: any, change: any) => { + if (source > this.dataSource.length) { + // don't scroll if row is not added to the end (bottom) + let wtHolder = document.querySelector('.wtHolder') + + setTimeout(() => { + if (wtHolder) wtHolder.scrollTop = wtHolder.scrollHeight + }) + } + }) + + hot.addHook('beforePaste', (data: any, cords: any) => { + const startCol = cords[0].startCol + + // We iterate trough pasting data to convert to numbers if needed + data[0] = data[0].map((value: any, index: number) => { + const colName = this.columnHeader[startCol + index] + const isColNum = this.$dataFormats?.vars[colName]?.type === 'num' + const specialMissing = isSpecialMissing(value) + + if (isColNum && !isNaN(value) && !specialMissing) value = value * 1 + + return value + }) + }) + + hot.addHook('afterRemoveRow', () => { + this.checkRowLimit() + }) + + hot.addHook('afterCreateRow', () => { + this.checkRowLimit() + }) + + this.uploadUrl = 'services/editors/loadfile' + + if (this.recordAction !== null) { + if (this.recordAction === 'ADD') { + this.addRecord() + this.editRecord(null, this.dataSource.length - 1, true) + } else { + if (this.dataSource.length === 1) { + this.editRecord(null, 0) + } + } + } + + if (response.data.query.length > 0) { + if ( + (globals.rootParam === 'home' || globals.rootParam === 'editor') && + globals.editor.filter.clauses.length === 0 + ) { + globals.editor.filter.query = this.helperService.deepClone( + response.data.query + ) + globals.editor.filter.libds = this.route.snapshot.params['libMem'] + this.sasStoreService.initializeGlobalFilterClause('editor', this.cols) + } + } + + hot.render() + } +} diff --git a/client/src/app/editor/editor.module.ts b/client/src/app/editor/editor.module.ts new file mode 100644 index 0000000..c09b6d9 --- /dev/null +++ b/client/src/app/editor/editor.module.ts @@ -0,0 +1,43 @@ +import { CommonModule } from '@angular/common' +import { NgModule } from '@angular/core' +import { FormsModule } from '@angular/forms' +import { ClarityModule } from '@clr/angular' +import { HotTableModule } from '@handsontable/angular' +import { registerAllModules } from 'handsontable/registry' +import { AppSharedModule } from '../app-shared.module' +import { DirectivesModule } from '../directives/directives.module' +import { PipesModule } from '../pipes/pipes.module' +import { SharedModule } from '../shared/shared.module' +import { EditRecordComponent } from './components/edit-record/edit-record.component' +import { UploadStaterComponent } from './components/upload-stater/upload-stater.component' +import { EditorRoutingModule } from './editor-routing.module' +import { EditorComponent } from './editor.component' +import { HomeModule } from '../home/home.module' +import { DcTreeModule } from '../shared/dc-tree/dc-tree.module' +import { DragDropModule } from '@angular/cdk/drag-drop' +import { ViewboxesModule } from '../shared/viewboxes/viewboxes.module' +import { QueryModule } from '../query/query.module' + +// register Handsontable's modules +registerAllModules() + +@NgModule({ + declarations: [EditRecordComponent, EditorComponent, UploadStaterComponent], + imports: [ + ViewboxesModule, + CommonModule, + FormsModule, + EditorRoutingModule, + ClarityModule, + HotTableModule.forRoot(), + AppSharedModule, + DirectivesModule, + SharedModule, + HomeModule, + PipesModule, + DcTreeModule, + DragDropModule, + QueryModule + ] +}) +export class EditorModule {} diff --git a/client/src/app/editor/models/EditRecordModal.ts b/client/src/app/editor/models/EditRecordModal.ts new file mode 100644 index 0000000..1b32926 --- /dev/null +++ b/client/src/app/editor/models/EditRecordModal.ts @@ -0,0 +1,6 @@ +import { DcValidation } from 'src/app/shared/dc-validator/models/dc-validation.model' + +export interface EditRecordModal extends DcValidation { + noLinkOption: boolean + [key: string]: any +} diff --git a/client/src/app/editor/models/cellValidation.ts b/client/src/app/editor/models/cellValidation.ts new file mode 100644 index 0000000..cf6e1b9 --- /dev/null +++ b/client/src/app/editor/models/cellValidation.ts @@ -0,0 +1,19 @@ +export interface CellValidation { + data: string + length: number + type?: string + source: string[] + format?: number + validator?: any + valid?: boolean + renderer?: any + dateFormat?: string + readOnly?: boolean + desc?: string + correctFormat?: boolean + /** + * Key for accessing object fields, any type because it can be + * any of the types interface have + */ + [key: string]: any +} diff --git a/client/src/app/editor/models/column.ts b/client/src/app/editor/models/column.ts new file mode 100644 index 0000000..903aa36 --- /dev/null +++ b/client/src/app/editor/models/column.ts @@ -0,0 +1,36 @@ +export enum ColumnType { + string = 'string', + number = 'number' +} + +export interface ColumnInterface { + id: number | undefined + name: string | undefined + type: ColumnType | undefined + length: number | undefined +} + +export class Column implements ColumnInterface { + public id: number | undefined + public name: string | undefined + public type: ColumnType | undefined + public length: number | undefined + public static fromPlainObject(obj: object) { + return Object.assign(new Column(), obj) + } + + constructor(id?: number, name?: string, type?: ColumnType, length?: number) { + this.id = id + this.name = name + this.type = type + this.length = length + } + + get hsType() { + return ( + (this.type === ColumnType.string && 'text') || + (this.type === ColumnType.number && 'numeric') || + null + ) + } +} diff --git a/client/src/app/editor/models/dynamicExtendedCellValidation.ts b/client/src/app/editor/models/dynamicExtendedCellValidation.ts new file mode 100644 index 0000000..4342eb4 --- /dev/null +++ b/client/src/app/editor/models/dynamicExtendedCellValidation.ts @@ -0,0 +1,9 @@ +export interface DynamicExtendedCellValidation { + DISPLAY_INDEX: number + DISPLAY_TYPE: string + DISPLAY_VALUE: string + EXTRA_COL_NAME: string + RAW_VALUE_CHAR: string + RAW_VALUE_NUM: number + FORCE_FLAG: number +} diff --git a/client/src/app/editor/models/edit-record/edit-record-events.ts b/client/src/app/editor/models/edit-record/edit-record-events.ts new file mode 100644 index 0000000..0eedbb9 --- /dev/null +++ b/client/src/app/editor/models/edit-record/edit-record-events.ts @@ -0,0 +1,9 @@ +export interface EditRecordInputFocusedEvent { + event: any + colName: number +} + +export interface EditRecordDropdownChangeEvent { + colName: string + col: number +} diff --git a/client/src/app/editor/models/editor-restrictions.model.ts b/client/src/app/editor/models/editor-restrictions.model.ts new file mode 100644 index 0000000..6fe828b --- /dev/null +++ b/client/src/app/editor/models/editor-restrictions.model.ts @@ -0,0 +1,8 @@ +export interface EditorRestrictions { + restrictEditRecord?: boolean // Feature is locked but edit/add record buttons are visible so when user clicks he gets the `locked feature modal` + restrictAddRecord?: boolean // Same as editRecord, but for addRecord + removeAddRecordButton?: boolean // Removes the buttons in cases as such when Column Level Security is enabled + removeEditRecordButton?: boolean // Same as removeAddRecordButton + restrictAddRow?: boolean // locks add row button + restrictFileUpload?: boolean // locks file upload +} diff --git a/client/src/app/editor/table.ts b/client/src/app/editor/table.ts new file mode 100644 index 0000000..03c9a19 --- /dev/null +++ b/client/src/app/editor/table.ts @@ -0,0 +1,71 @@ +import { Column, ColumnType } from './models/column' + +export enum TableType { + INPUT = 'In', + OUTPUT = 'Out' +} + +export interface TableInterface { + id: number | undefined + name: string | undefined + data: Array + columns: Array + type: TableType | undefined +} + +export class Table implements TableInterface { + public id: number | undefined + public name: string | undefined + public data: Array + public columns: Array = [] + public type: TableType | undefined + + public static fromPlainObject(obj: any) { + obj.columns = obj.columns.map((column: object) => { + return Column.fromPlainObject(column) + }) + + return Object.assign(new Table(), obj) + } + + constructor( + id?: number, + name?: string, + type?: TableType, + data?: Array, + columns?: Array + ) { + this.id = id + this.name = name + this.type = type + + this.data = data || [{}] + this.columns = columns || [] + } + + public getNextColumnId(): number { + let highestIdColumn: any = this.columns.sort( + (cA: any, cB: any) => cA.id - cB.id + )[this.columns.length - 1] + return (highestIdColumn && highestIdColumn.id + 1) || 0 + } + + public addColumn(column: Column) { + this.columns.push(column) + + this.data.forEach((row: any) => { + if (column.name) { + row[column.name] = column.type === ColumnType.string ? '' : null + } + }) + + return column + } + + public removeColumn(colInd: any) { + this.data.forEach((row) => { + delete row[this.columns[colInd].name!] + }) + this.columns.splice(colInd, 1) + } +} diff --git a/client/src/app/editor/utils/date.utils.ts b/client/src/app/editor/utils/date.utils.ts new file mode 100644 index 0000000..d738201 --- /dev/null +++ b/client/src/app/editor/utils/date.utils.ts @@ -0,0 +1,23 @@ +export const dateToUtcTime = (date: Date) => { + let timeStr = ('0' + date.getUTCHours()).slice(-2) + ':' + timeStr = timeStr + ('0' + date.getUTCMinutes()).slice(-2) + ':' + timeStr = timeStr + ('0' + date.getUTCSeconds()).slice(-2) + return timeStr +} + +export const dateToTime = (date: Date) => { + let timeStr = ('0' + date.getHours()).slice(-2) + ':' + timeStr = timeStr + ('0' + date.getMinutes()).slice(-2) + ':' + timeStr = timeStr + ('0' + date.getSeconds()).slice(-2) + return timeStr +} + +export const dateFormat = (date: Date) => { + return ( + date.getFullYear() + + '-' + + ('0' + (date.getMonth() + 1)).slice(-2) + + '-' + + ('0' + date.getDate()).slice(-2) + ) +} diff --git a/client/src/app/editor/utils/grid.utils.ts b/client/src/app/editor/utils/grid.utils.ts new file mode 100644 index 0000000..30b4ad2 --- /dev/null +++ b/client/src/app/editor/utils/grid.utils.ts @@ -0,0 +1,32 @@ +import { Col } from 'src/app/shared/dc-validator/models/col.model' + +export const excelDateToJSDate = (serial: number) => { + return new Date(Math.round((serial - 25569) * 86400 * 1000)) +} + +export const parseTableColumns = (data: Col[]): string[] => { + const columns: string[] = [] + + for (let specEntry of data) { + if (specEntry.NAME !== '_____DELETE__THIS__RECORD_____') { + columns.push(specEntry.NAME) + } + } + + return columns +} + +export const getMissingHeaders = (data: any, headers: any) => { + const missingHeaders: string[] = [] + const remainingHeaders: string[] = [] + + headers.forEach((element: string) => { + if (data.indexOf(element) === -1) { + missingHeaders.push(element) + } else { + remainingHeaders.push(element) + } + }) + + return [missingHeaders, remainingHeaders] +} diff --git a/client/src/app/editor/utils/renderers.utils.ts b/client/src/app/editor/utils/renderers.utils.ts new file mode 100644 index 0000000..95bbc96 --- /dev/null +++ b/client/src/app/editor/utils/renderers.utils.ts @@ -0,0 +1,46 @@ +export const errorRenderer = ( + instance: any, + td: any, + row: number, + col: number, + prop: string, + value: any, + cellProperties: any +) => { + td.innerHTML = `${ + value ? value.toString() : '' + } ` + + return td +} + +export const noSpinnerRenderer = ( + instance: any, + td: any, + row: number, + col: number, + prop: string, + value: any, + cellProperties: any +) => { + td.innerHTML = value ? value : '' + + return td +} + +// Spinner shown whilst waiting for SAS to respond +export const spinnerRenderer = ( + instance: any, + td: any, + row: number, + col: number, + prop: string, + value: any, + cellProperties: any +) => { + td.innerHTML = `${ + value ? value.toString() : '' + } ` + + return td +} diff --git a/client/src/app/editor/utils/types.utils.ts b/client/src/app/editor/utils/types.utils.ts new file mode 100644 index 0000000..5165cfd --- /dev/null +++ b/client/src/app/editor/utils/types.utils.ts @@ -0,0 +1,15 @@ +export const isStringNumber = (str: string) => { + if (/^-{0,1}\d+$/.test(str)) { + return true + } else { + return false + } +} + +export const isStringDecimal = (str: string) => { + if (/^\d+\.\d+$/.test(str)) { + return true + } else { + return false + } +} diff --git a/client/src/app/free-tier.config.ts b/client/src/app/free-tier.config.ts new file mode 100644 index 0000000..057ead9 --- /dev/null +++ b/client/src/app/free-tier.config.ts @@ -0,0 +1,36 @@ +import { LicenceState } from './models/LicenceState' + +/** + * These properties Will be applied when NO KEY FREE TIER is active + * and when key is FREE TIER it is used for limit values that are not set + * props from the LICENCE KEY is will be used to override these values + * + * @param users_allowed - users allowed IF NO key is provided + * @param viewer_rows_allowed --------- + * @param editor_rows_allowed ---- Infinity is unlimited + * @param stage_rows_allowed ----- positive number is rows limit + * @param history_rows_allowed --- + * @param submit_rows_limit ----------- + * @param viewbox_limit - number of viewboxes allowed to open + * @param lineage_daily_limit - dailiy limit of opening lineage diagrams + * @param tables_in_library_limit - limit of shown tables in library lists + * @param viewbox - enable/disable Viewbox feature + * @param fileUpload - enable/disable File Upload in table feature + * @param editRecord - enable/disable Edit Record feature + * @param addRecord - enable/disable Add Record feature + */ +export const freeTierConfig: LicenceState = { + users_allowed: 1, + viewer_rows_allowed: 15, + editor_rows_allowed: 15, + stage_rows_allowed: Infinity, + history_rows_allowed: 15, + submit_rows_limit: 5, + viewbox_limit: 1, + lineage_daily_limit: 3, + tables_in_library_limit: 35, + viewbox: true, + fileUpload: true, + editRecord: true, + addRecord: true +} diff --git a/client/src/app/group/group.component.html b/client/src/app/group/group.component.html new file mode 100644 index 0000000..b3cfccd --- /dev/null +++ b/client/src/app/group/group.component.html @@ -0,0 +1,143 @@ + + + +
+ + + +
+
+ + + +

+ + {{ group.GROUPNAME }} +

+
+
+
+
+ +
+
+ Loading... +
+
+
+
+ + + + + + + + + +
+

+ {{ groupName }} +

+
+ {{ groupDesc || 'no description' }} +
+
+
+ +
+
+
+
+

MEMBERS ({{ groupMemberCount }})

+
No Members Present
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NAMEEMAILCREATEDUPDATEDIDDISPLAY NAMEUSER NAME
{{ member.MEMBERNAME }}{{ member.EMAIL }}{{ member.MEMBERCREATED }}{{ member.MEMBERUPDATED }}{{ member.ID }}{{ member.DISPLAYNAME }}{{ member.USERNAME }}
+
+
+
+

{{ groupName }}

+
No Members Present
+
+ + + + + + + + + + + +
+ MEMBERS ({{ groupMemberCount }}) +
{{ member.MEMBERNAME }}
+
+
+
+
+
+
+
+
diff --git a/client/src/app/group/group.component.scss b/client/src/app/group/group.component.scss new file mode 100644 index 0000000..84e373d --- /dev/null +++ b/client/src/app/group/group.component.scss @@ -0,0 +1,52 @@ +.sidebar-height{ + height: 100%; +} +.group-info-text{ + display: inline; + font-size: 20px; +} +.group-info{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.group-info td{ + text-align: center; +} + +.group-data{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.group-data{ + min-height: auto; + h3, h5{ + text-align: center; +} + +.member-table{ + background-color: #f9f9f9; + width: 100%; +} +.member-table thead{ + background-color: #dadada; +} +.member-table tbody{ + tr:hover{ + background-color: #e6e6e6; + cursor: pointer; + } +} +} +.table-container{ + overflow: auto; +} + +@media screen and (max-width: 768px){ + .group-data{ + min-height: unset !important; + } +} \ No newline at end of file diff --git a/client/src/app/group/group.component.ts b/client/src/app/group/group.component.ts new file mode 100644 index 0000000..6c5be2f --- /dev/null +++ b/client/src/app/group/group.component.ts @@ -0,0 +1,215 @@ +import { Location } from '@angular/common' +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { SASjsConfig } from '@sasjs/adapter' +import { ServerType } from '@sasjs/utils/types/serverType' +import { HelperService } from '../services/helper.service' +import { SasService } from '../services/sas.service' +import { globals } from '../_globals' + +@Component({ + selector: 'app-group', + templateUrl: './group.component.html', + styleUrls: ['./group.component.scss'], + host: { + class: 'content-container' + } +}) +export class GroupComponent implements OnInit { + public groups: Array | undefined + public groupSearch: string = '' + public groupMembers: Array | undefined + public groupMemberCount: number | undefined + public paramPresent: boolean = false + public paramURI: string = '' + public groupUri: string = '' + public groupName: string = '' + public groupDesc: string = '' + public sasjsConfig: SASjsConfig = new SASjsConfig() + public isViya: boolean = false + public loading: boolean = false + public serverType: string + + ServerType = ServerType + + constructor( + private sasService: SasService, + private helperService: HelperService, + private router: Router, + private location: Location, + private route: ActivatedRoute + ) { + this.sasjsConfig = this.sasService.getSasjsConfig() + this.serverType = this.sasService.getServerType() + + if (this.sasjsConfig.serverType === 'SASVIYA') { + this.isViya = true + } + } + + ngOnInit() { + globals.viewer.currentSelection = 'view/usernav/groups' + if (this.route.snapshot.params['uri'] !== undefined) { + this.paramPresent = true + this.paramURI = this.route.snapshot.params['uri'] + } + if (globals.usernav.groupList && !this.paramPresent) { + this.groups = globals.usernav.groupList + this.groupSearch = globals.usernav.groupSearch + } else { + if (globals.usernav.groupList === undefined) { + this.loading = true + if (this.isViya) { + fetch(this.sasjsConfig.serverUrl + '/identities/groups?limit=2000', { + headers: { + Accept: 'application/json' + } + }) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + let groups = jsonRes.items.map((group: any) => { + return { + GROUPURI: group.id, + GROUPNAME: group.name, + GROUPDESC: group.description + } + }) + this.loading = false + this.groups = groups + globals.usernav.groupList = groups + }) + } else { + this.sasService.request('public/getgroups', null).then((res: any) => { + this.loading = false + this.groups = res.groups + globals.usernav.groupList = res.groups + }) + } + } else { + this.groups = globals.usernav.groupList + this.groupSearch = globals.usernav.groupSearch + } + if (this.paramPresent) { + this.loading = true + + if (this.isViya) { + fetch( + this.sasjsConfig.serverUrl + + '/identities/groups/' + + this.paramURI + + '/members?limit=2000', + { + headers: { + Accept: 'application/json' + } + } + ) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + this.loading = false + let groupMembers = jsonRes.items.map((member: any) => { + return { + MEMBERNAME: member.name, + MEMBERID: member.id + } + }) + this.groupMembers = groupMembers + this.groupMemberCount = groupMembers.length + this.groupUri = this.paramURI + this.groupName = this.paramURI + }) + } else { + let data = { iwant: [{ groupid: this.paramURI }] } + this.sasService + .request('usernav/usermembersbygroup', data) + .then((res: any) => { + this.groupMembers = res.sasmembers + this.groupMemberCount = res.sasmembers.length + if (res.sasmembers[0] !== undefined) { + this.loading = false + this.groupUri = res.sasmembers[0].URIMEM || this.paramURI + this.groupName = res.sasmembers[0].GROUPNAME + this.groupDesc = res.sasmembers[0].GROUPDESC + + if (!this.groupName) { + this.groupName = this.paramURI + } + } + }) + } + } + } + } + + public groupListOnFilter() { + this.helperService.libraryOnFilter( + this.groups, + this.groupSearch, + 'GROUPNAME' + ) + globals.usernav.groupSearch = this.groupSearch + } + + public groupOnClick(group: any) { + this.loading = true + let url = this.router.url + + if (this.paramPresent) { + this.location.replaceState( + url.slice(0, url.lastIndexOf('/')) + '/' + encodeURI(group.GROUPURI) + ) + } else { + this.location.replaceState(url + '/' + encodeURI(group.GROUPURI)) + } + if (this.isViya) { + fetch( + this.sasjsConfig.serverUrl + + '/identities/groups/' + + group.GROUPURI + + '/members?limit=2000', + { + headers: { + Accept: 'application/json' + } + } + ) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + this.loading = false + this.groupUri = group.GROUPURI + this.groupName = group.GROUPNAME + this.groupDesc = group.GROUPDESC + let groupMembers = jsonRes.items.map((member: any) => { + return { + MEMBERNAME: member.name, + MEMBERID: member.id + } + }) + this.groupMembers = groupMembers + this.groupMemberCount = groupMembers.length + }) + } else { + let data = { iwant: [{ groupid: group.GROUPURI }] } + + this.sasService + .request('usernav/usermembersbygroup', data) + .then((res: any) => { + this.loading = false + this.groupUri = group.GROUPURI + this.groupName = group.GROUPNAME + this.groupDesc = group.GROUPDESC + this.groupMembers = res.sasmembers + this.groupMemberCount = res.sasmembers.length + }) + } + } +} diff --git a/client/src/app/history/history.component.html b/client/src/app/history/history.component.html new file mode 100644 index 0000000..0b82ac6 --- /dev/null +++ b/client/src/app/history/history.component.html @@ -0,0 +1,167 @@ +
+
+ +

There is no history to show

+
+ + + + + + +
+ Loading... +
+

Loading history

+
+
+ +
+
+

HISTORY

+

+ To unlock more than + {{ licenceState.value.history_rows_allowed }} records, contact + support@datacontroller.io +

+
+ + + BASE_TABLE + STATUS + SUBMITTER + SUBMIT REASON + SUBMITTED + APPROVED / REJECTED + DOWNLOAD + + + + {{ historyItem.basetable }} + + {{ historyItem.status }} + {{ historyItem.submitter }} + {{ + historyItem.submittedReason + }} + {{ historyItem.submitted }} + {{ historyItem.reviewed }} + + + + + + + + + +
+ +
+
+
diff --git a/client/src/app/history/history.component.scss b/client/src/app/history/history.component.scss new file mode 100644 index 0000000..00118e4 --- /dev/null +++ b/client/src/app/history/history.component.scss @@ -0,0 +1,37 @@ +.rejected { + color: #f83126; + font-weight: bold +} + +.accepted { + color: #3fc424; + font-weight: bold +} + +.hsCell { + display: flex !important; + flex-direction: column !important; + justify-content: center !important; + align-items: center !important; + padding: 7px; +} +.btCell { + display: flex !important; + justify-content: center !important; +} + +.verCenter { + display: flex; + align-items: center; + word-break: break-all; +} + +.load-more { + input { + width: 90px; + } +} + +#noDataContainer { + height: calc(100vh - 200px); +} \ No newline at end of file diff --git a/client/src/app/history/history.component.ts b/client/src/app/history/history.component.ts new file mode 100644 index 0000000..10e7f87 --- /dev/null +++ b/client/src/app/history/history.component.ts @@ -0,0 +1,162 @@ +import { Component, OnInit } from '@angular/core' + +import { SasStoreService } from '../services/sas-store.service' +import { Router } from '@angular/router' +import { SasService } from '../services/sas.service' +import { EventService } from '../services/event.service' +import { SASjsConfig } from '@sasjs/adapter' +import { LicenceService } from '../services/licence.service' + +@Component({ + selector: 'app-history', + templateUrl: './history.component.html', + styleUrls: ['./history.component.scss'], + host: { + class: 'content-container' + } +}) +export class HistoryComponent implements OnInit { + public history: Array = [] + public tableTitles: Array = [] + public historyArr: Array = [] + public loaded: boolean = false + public itemsNum: number = 10 + public openModal: boolean = false + public noData: boolean = false + public approveData: any = {} + public sasjsConfig: SASjsConfig = new SASjsConfig() + + public histParams: { HIST: number; STARTROW: number; NOBS: number } = { + HIST: 0, + STARTROW: 1, + NOBS: -1 + } + public loadingMore: boolean = false + + public licenceState = this.licenceService.licenceState + public Infinity = Infinity + + constructor( + private licenceService: LicenceService, + private sasStoreService: SasStoreService, + private eventService: EventService, + private router: Router, + private sasService: SasService + ) { + this.sasjsConfig = this.sasService.getSasjsConfig() + } + + public getTable(table_id: any) { + this.router.navigateByUrl('/stage/' + table_id) + } + + public getBaseTable(baseTable: any) { + this.router.navigateByUrl('/view/data/' + baseTable) + } + + public getEditTable(editTable: any) { + this.router.navigateByUrl('/editor/' + editTable) + } + + public getApprIndex(historyItem: any) { + const historyItemIndex = this.historyArr.findIndex( + (itm: any) => itm.TABLE_ID === historyItem.tableId + ) + + if (historyItemIndex > -1) { + this.approveData = this.historyArr[historyItemIndex] + this.openModal = true + } + } + + public get rowsLeftToLoad() { + const rowsLeft = this.histParams.NOBS - this.history.length + const rowsInStep = this.histParams.HIST + + if (rowsLeft <= 0) return 0 + if (rowsLeft > rowsInStep) return rowsInStep + + return rowsLeft + } + + public download(id: any) { + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = this.sasService.getExecutionPath() + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/auditors/getauditfile&table=' + + id + + '&_contextname=' + + this.sasjsConfig.contextName + window.open(downUrl) + } + + async loadData() { + let histParams = { + STARTROW: this.histParams.HIST + this.histParams.STARTROW + } + + this.loadingMore = true + + try { + let res = await this.sasStoreService.getHistory( + histParams, + 'BrowserParams', + 'approvers/gethistory' + ) + + this.loadingMore = false + + this.histParams = res.histparams[0] + + let tableTitles: Array + const fromsas = res.fromsas.slice( + 0, + this.licenceState.value.history_rows_allowed + ) + + if (fromsas.length > 0) { + const arr = fromsas + this.historyArr = fromsas + + tableTitles = Object.keys(arr[0]) + + this.tableTitles = tableTitles + + let historyTable = fromsas.map(function (item: any) { + return { + tableId: item.TABLE_ID, + submitter: item.SUBMITTER, + submittedReason: item.SUBMITTED_REASON_TXT, + submitted: item.SUBMITTED, + status: item.STATUS, + reviewReason: item.REVIEW_REASON_TXT, + reviewer: item.REVIEWER, + reviewed: item.REVIEWED, + numOfApprovals: item.NUM_OF_APPROVALS_REQUIRED, + basetable: item.BASE_TABLE + } + }) + + this.history.push(...historyTable) + this.loaded = true + } else { + this.loaded = true + + if (this.history.length === 0) this.noData = true + } + } catch (error) { + this.eventService.catchResponseError('approvers/gethistory', error) + this.loadingMore = false + } + } + + async ngOnInit() { + this.loadData() + } +} diff --git a/client/src/app/home/home.component.html b/client/src/app/home/home.component.html new file mode 100644 index 0000000..bde22bf --- /dev/null +++ b/client/src/app/home/home.component.html @@ -0,0 +1,135 @@ + + + +
+ + + + +
+
+ + + +

+ + {{ library.LIBRARYREF }} +

+ + +
+ + + + +
+
+ + + + + + + + To unlock all tables, contact support@datacontroller.io + + + + +
+
+
+
+ +
+
+
+
+ Loading... +
+
+ +
+ +

+ Please select a table +

+

+ No Editable Tables Configured +

+
+
+
diff --git a/client/src/app/home/home.component.scss b/client/src/app/home/home.component.scss new file mode 100644 index 0000000..48673f3 --- /dev/null +++ b/client/src/app/home/home.component.scss @@ -0,0 +1,32 @@ +clr-tree-node button { + white-space: nowrap; +} + +.card-block { + height: 100%; + padding: 0; +} + +.no-table-selected { + position: relative; + height: 100%; +} + +::ng-deep { + // .badge.badge-info { + // background: #6a9235!important; + // color: #fff; + // } + clr-icon.is-blue, clr-icon.is-info { + fill: #6a9235; + } +} + +.spinner-wrapper-fullpage { + display: flex; + justify-content: center; + align-items: center; + + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/client/src/app/home/home.component.ts b/client/src/app/home/home.component.ts new file mode 100644 index 0000000..9e531ba --- /dev/null +++ b/client/src/app/home/home.component.ts @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 VMware, Inc. All Rights Reserved. + * This software is released under MIT license. + * The full license information can be found in LICENSE in the root directory of this project. + */ +import { Component, AfterContentInit } from '@angular/core' +import { Router } from '@angular/router' +import { ActivatedRoute } from '@angular/router' +import { globals } from '../_globals' +import { HelperService } from '../services/helper.service' +import { EventService } from '../services/event.service' +import { SasService } from '../services/sas.service' +import { LicenceService } from '../services/licence.service' + +@Component({ + selector: 'home-component', + styleUrls: ['./home.component.scss'], + templateUrl: './home.component.html', + host: { + class: 'content-container' + } +}) +export class HomeComponent implements AfterContentInit { + public treeNodeLibraries: Array | null = null + public librariesSearch: string = '' + public libraries: Array | undefined + public libsAndTables: Array | undefined + public tables: Array | undefined + public lib: any = '' + public table: any = '' + public libds: string | undefined + public libTab: string | undefined + + public encoding: any = 'UTF-8' + public loading: boolean = true + + public licenceState = this.licenceService.licenceState + + constructor( + private route: Router, + private router: ActivatedRoute, + private licenceService: LicenceService, + private helperService: HelperService, + private eventService: EventService, + private sasService: SasService + ) {} + + public collapseLibraryItems(libraries: any, libraryToSkip: any) { + libraries.forEach((library: any) => { + if (library.LIBRARYID !== libraryToSkip.LIBRARYID) { + library['expanded'] = false + } + }) + } + + public treeNodeClicked(event: any, library: any) { + if (event.target.title === 'Collapse') { + this.collapseLibraryItems(this.libraries, library) + } + } + + public libraryOnClick(lib: string, library: any) { + library['expanded'] = !library['expanded'] + + if (library['expanded'] && !this.table) { + this.selectLibrary(lib, false, library) + } + + this.collapseLibraryItems(this.libraries, library) + } + + public selectLibrary(libs: any, initial?: boolean, library?: any) { + library['loadingTables'] = true + + let newarray: Array + let dups: Array = [] + if (this.libsAndTables) { + newarray = this.libsAndTables[libs] + this.table = undefined + if (libs !== 'Please select library') { + let arr = newarray.filter(function (el) { + if (dups.indexOf(el) === -1) { + dups.push(el) + return true + } + return false + }) + + this.tables = arr + globals.editor.libraries = this.libraries + } + } + globals.editor.library = libs + if (!initial) { + this.clearGlobalsFilter() + } + + library['loadingTables'] = false + library['expanded'] = true + } + + public async selectTable(ev: string, initial?: boolean) { + let libTab = this.lib + '.' + this.table + this.libTab = libTab + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = + sasjsConfig.serverType === 'SAS9' + ? sasjsConfig.pathSAS9 + : sasjsConfig.pathSASViya + + globals.editor.table = ev + if (!initial) { + this.clearGlobalsFilter() + } + } + + private clearGlobalsFilter() { + globals.editor.filter.libds = '' + globals.editor.filter.whereClause = '' + globals.editor.filter.groupLogic = '' + globals.editor.filter.clauses = [] + globals.editor.filter.vals = [] + globals.editor.filter.cols = [] + } + + public libTabActive(library: string, table: string) { + if (!this.lib || !this.table) { + return false + } + + return library === this.lib && table === this.table + } + + public treeOnFilter(array: any, arrToFilter: string) { + this.helperService.treeOnFilter(array, arrToFilter) + } + + public libraryOnFilter() { + this.helperService.libraryOnFilter( + this.treeNodeLibraries, + this.librariesSearch, + 'LIBRARYREF' + ) + + globals.lineage.librariesSearch = this.librariesSearch + } + + public onTableClick(libTable: any, library: any) { + this.table = libTable + this.lib = library.LIBRARYREF + this.selectTable(libTable) + this.editTable() + } + + public editTable() { + let libMem: string = this.lib + '.' + this.table + this.route.navigateByUrl('/editor/' + libMem) + } + + private getLibraryTableState() { + if (globals.editor.treeNodeLibraries !== null) { + this.treeNodeLibraries = globals.editor.treeNodeLibraries + } + + if (globals.editor.library !== '') { + this.lib = globals.editor.library + + let treeNodeLibrary = null + if (this.treeNodeLibraries) { + treeNodeLibrary = this.treeNodeLibraries.find( + (lib: any) => lib.LIBRARYREF === this.lib + ) + } + + this.selectLibrary(globals.editor.library, true, treeNodeLibrary) + } + } + + public getFromGlobals() { + this.libsAndTables = globals.editor.libsAndTables + this.libraries = globals.editor.libraries + + this.getLibraryTableState() + + this.loading = false + } + + ngAfterContentInit(): void { + if (globals.editor.startupSet) { + this.getFromGlobals() + } else { + this.eventService.onStartupDataLoaded.subscribe(() => { + this.getFromGlobals() + }) + } + } +} diff --git a/client/src/app/home/home.module.ts b/client/src/app/home/home.module.ts new file mode 100644 index 0000000..9655d2e --- /dev/null +++ b/client/src/app/home/home.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { HomeComponent } from './home.component' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { AppSharedModule } from '../app-shared.module' +import { DcTreeModule } from '../shared/dc-tree/dc-tree.module' +import { DirectivesModule } from '../directives/directives.module' + +@NgModule({ + declarations: [HomeComponent], + imports: [ + FormsModule, + ClarityModule, + AppSharedModule, + CommonModule, + DcTreeModule, + DirectivesModule + ], + exports: [HomeComponent] +}) +export class HomeModule {} diff --git a/client/src/app/index.ts b/client/src/app/index.ts new file mode 100644 index 0000000..e6c1294 --- /dev/null +++ b/client/src/app/index.ts @@ -0,0 +1,3 @@ +export * from './app.component' +export * from './app.module' +import '@clr/icons' diff --git a/client/src/app/interfaces.ts b/client/src/app/interfaces.ts new file mode 100644 index 0000000..ff32067 --- /dev/null +++ b/client/src/app/interfaces.ts @@ -0,0 +1,6 @@ +export interface SpecObj { + [propName: string]: { + colType: string + colLength: any + } +} diff --git a/client/src/app/licensing/licensing.component.html b/client/src/app/licensing/licensing.component.html new file mode 100644 index 0000000..640a85b --- /dev/null +++ b/client/src/app/licensing/licensing.component.html @@ -0,0 +1,149 @@ +
+
Licencing
+ +
+ +

+ Licence key is invalid. We can't provide you more details at the moment +

+ +

+ +

Details: {{ errorDetails }}

+
+ + +

+ The registered number of users reached the limit specified for your + licence. Please contact + + or your reseller to arrange additional licences for this product. +

+
+ + +

+ Update the license key by uploading the licence file or by pasting a + license key and activation key in the inputs below. +

+
+ +

+ SYSSITE: + + {{ id }}{{ i === syssite.value?.length! - 1 ? '' : ',' }} + + + + + Copy to clipboard + +

+ +

+ Allowed users: + {{ licenseKeyData.users_allowed }} +

+ + + + + + +
+ + +
+ Drop / Browse licence file +
+
+ Selected file: {{ licencefile.filename }} +
+
+ {{ licenceFileError }} +
+
+
+
+
+ + + + +
+

Licence key:

+
+ +
+
+ +
+

Activation key:

+
+ +
+
+
+
+
+ + + + +
+
+ + diff --git a/client/src/app/licensing/licensing.component.scss b/client/src/app/licensing/licensing.component.scss new file mode 100644 index 0000000..4e77d3c --- /dev/null +++ b/client/src/app/licensing/licensing.component.scss @@ -0,0 +1,52 @@ +:host { + height: calc(100% - 96px); + padding: 20px 20px; +} + +.card { + margin-top: 0; +} + +.key-error { + font-size: 16px; +} + +.misskey { + color: #E74C3C; +} + +.license-key-form, .activation-key-form { + padding: 0; + + .clr-control-container { + width: 100%; + + textarea { + width: 100%; + height: 170px; + max-height: 170px; + min-height: 170px; + resize: none; + } + } +} + +.apply-keys { + height: 40px; + width: 200px; +} + +.drop-area { + display: flex; + justify-content: center; + align-items: center; + padding: 15px; + border: 2px dashed #b2b2b2; + border-radius: 4px; + cursor: pointer; + margin: 10px 0; +} + +clr-tabs button { + box-shadow: none !important +} \ No newline at end of file diff --git a/client/src/app/licensing/licensing.component.ts b/client/src/app/licensing/licensing.component.ts new file mode 100644 index 0000000..61e7ad7 --- /dev/null +++ b/client/src/app/licensing/licensing.component.ts @@ -0,0 +1,172 @@ +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { AppService, LicenceService, SasService } from '../services' +import { LicenseKeyData } from '../models/LicenseKeyData' + +enum LicenseActions { + key = 'key', + register = 'register', + limit = 'limit', + update = 'update' +} + +@Component({ + selector: 'app-licensing', + templateUrl: './licensing.component.html', + styleUrls: ['./licensing.component.scss'] +}) +export class LicensingComponent implements OnInit { + public action: LicenseActions | null = null + + public licenseErrors: { [key: string]: string } = { + missing: `Licence key is missing - please contact support@datacontroller.io and enter valid keys below.`, + expired: `Licence key is expired - please contact support@datacontroller.io and enter valid keys below.`, + invalid: `Licence key is invalid - please contact support@datacontroller.io and enter valid keys below.`, + missmatch: `Your SYSSITE (below) is not found in the licence key - please contact support@datacontroller.io and enter valid keys below.` + } + + public keyError: string | undefined + public errorDetails: string | undefined + public missmatchedKey: string | undefined + public licenceKeyValue: string = '' + public activationKeyValue: string = '' + + public applyingKeys: boolean = false + + public syssite = this.appService.syssite + public currentLicenceKey = this.licenceService.licenceKey + public currentActivationKey = this.licenceService.activationKey + public isAppFreeTier = this.licenceService.isAppFreeTier + public userCountLimitation = this.licenceService.userCountLimitation + + public licenseKeyData: LicenseKeyData | null = null + + public inputType: 'file' | 'paste' = 'file' + public licenceFileError: string | undefined + public licenceFileLoading: boolean = false + public licencefile: { filename: string } = { + filename: '' + } + + constructor( + private route: ActivatedRoute, + private licenceService: LicenceService, + private sasService: SasService, + private appService: AppService + ) {} + + ngOnInit(): void { + this.licenceKeyValue = this.currentLicenceKey || '' + this.activationKeyValue = this.currentActivationKey || '' + + this.route.queryParams.subscribe((queryParams: any) => { + this.keyError = queryParams.error + this.missmatchedKey = queryParams.missmatchId + + if (queryParams.details) { + this.errorDetails = atob(queryParams.details) + } + }) + + this.route.params.subscribe((params: any) => { + let actionInUrl = params.action + + if (actionInUrl) { + if (Object.values(LicenseActions).includes(actionInUrl)) { + this.action = actionInUrl + } + } + }) + + this.licenseKeyData = this.licenceService.getLicenseKeyData() + } + + public trimKeys() { + this.licenceKeyValue = this.licenceKeyValue.trim() + this.activationKeyValue = this.activationKeyValue.trim() + } + + public copySyssite(copyIconRef: any, copyTooltip: any, syssite: string[]) { + const syssiteString = syssite.join('\n') + + navigator.clipboard.writeText(syssiteString).then(() => { + copyIconRef.setAttribute('shape', 'check') + copyIconRef.setAttribute('class', 'is-success') + copyTooltip.innerText = 'Copied!' + + setTimeout(() => { + copyIconRef.setAttribute('shape', 'copy') + copyIconRef.removeAttribute('class') + copyTooltip.innerText = 'Copy to clipboard' + }, 1000) + }) + } + + public applyKeys() { + this.applyingKeys = true + + let table = { + keyupload: [ + { + ACTIVATION_KEY: this.activationKeyValue, + LICENCE_KEY: this.licenceKeyValue + } + ] + } + + this.sasService + .request('admin/registerkey', table) + .then((res: any) => { + if (res.return && res.return[0] && res.return[0].MSG === 'SUCCESS') { + location.replace(location.href.split('#')[0]) + } + }) + .finally(() => { + this.applyingKeys = false + }) + } + + public onFileCapture(event: any, dropped = false) { + let file = dropped ? event[0] : event.target.files[0] + this.licencefile.filename = file.name + + if (!file) return + + this.licenceFileLoading = true + + const reader = new FileReader() + + reader.onload = (evt) => { + this.licenceFileError = 'Error reading file.' + + if (!evt || !evt.target) return + if (evt.target.readyState != 2) return + if (evt.target.error) return + if (!evt.target.result) return + + this.licenceFileLoading = false + this.licenceFileError = undefined + const fileArr = evt.target.result.toString().split('\n') + this.activationKeyValue = fileArr[1] + this.licenceKeyValue = fileArr[0] + } + + reader.readAsText(file) + } + + public switchType(type: 'paste' | 'file') { + this.inputType = type + } + + get disableApplyButton(): boolean { + if (this.licenceKeyValue.length < 1 || this.activationKeyValue.length < 1) + return true + if ( + this.licenceKeyValue === this.currentLicenceKey && + this.activationKeyValue === this.currentActivationKey + ) + return true + + return false + } +} diff --git a/client/src/app/lineage/lineage.component.html b/client/src/app/lineage/lineage.component.html new file mode 100644 index 0000000..74fb318 --- /dev/null +++ b/client/src/app/lineage/lineage.component.html @@ -0,0 +1,410 @@ + + + +
+ + + +
+
+ + + +

+ + {{ library.LIBRARYNAME }} +

+ + +
+ + + +
+
+ + +

+ + {{ libTable.TABLENAME }} +

+ + +
+ + + +
+
+ + + + +
+
+
+
+ +
+ Loading... +
+
+ +
+
+
+ +

Please select a column or table

+
+ + +
+

+ {{ + currentLineagePathColumn + ? currentLineagePathLibTable + '.' + currentLineagePathColumn + : currentLineagePathLibTable + }} +

+
+ +
+
+
+ + {{ lineageTableName.split('.')[0] }}.{{ lineageTableName.split('.')[1] }}{{ lineageColumnName.length > 0 ? '.' + lineageColumnName : '' }} + +
+ +
+ + + +
+
+ + +
+ +
+ + +
+
+ + + + + +
SVG
+
+ PNG +
+
Dot
+
+ CSV +
+
+
+ + + + + +
+
+ +
+
+ Loading... + +
+
+ +
+ +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/client/src/app/lineage/lineage.component.scss b/client/src/app/lineage/lineage.component.scss new file mode 100644 index 0000000..793da52 --- /dev/null +++ b/client/src/app/lineage/lineage.component.scss @@ -0,0 +1,79 @@ +.toggle-switch input[type=checkbox]:checked+label:before { + border-color: #314351; + background-color: #314351!important; + transition: .15s ease-in; + transition-property: border-color,background-color; +} + +#graph{ + height: calc(100vh - 195px); + overflow: hidden; + text-align: center; + display: block; + width: 100%; + border: 1px solid #e4e4e4; + margin-top: 10px; +} + +.selection-wrapper { + width: 100%; + max-width: 670px; +} + +.column-active { + background: #d8e3e9; + color: black; +} + +.content-area { + padding: 0.5rem !important; + + .card { + min-height: calc(100vh - 120px); + + .card-block { + padding: 0.5rem 0.35rem !important; + } + } +} + +clr-tree-node button { + white-space: nowrap; +} + +.graph-render-spinner { + position: absolute; + top: 0; + width: 100%; + display: flex; + justify-content: center; + margin-top: 10px; +} + +.biglineage-row { + display: flex; + justify-content: space-between; + align-items: center; + + margin-bottom: 20px; +} + +.modal-footer { + p { + margin: 0; + } +} + +.lineage-title-wrapper { + left: 12px; +} + +.max-depth-input { + width: 100%; +} + +@media (max-width: 768px) { + .toggle-switch-container { + margin-bottom: 20px; + } +} \ No newline at end of file diff --git a/client/src/app/lineage/lineage.component.ts b/client/src/app/lineage/lineage.component.ts new file mode 100644 index 0000000..61b28ea --- /dev/null +++ b/client/src/app/lineage/lineage.component.ts @@ -0,0 +1,892 @@ +import { Component } from '@angular/core' +import { Location } from '@angular/common' +import { globals } from '../_globals' +import * as d3Viz from 'd3-graphviz' +import { ActivatedRoute, Router } from '@angular/router' +import { EventService } from '../services/event.service' +import { HelperService } from '../services/helper.service' +import { SasService } from '../services/sas.service' +import * as saveSvg from 'save-svg-as-png' +import { LoggerService } from '../services/logger.service' +import { LicenceService } from '../services/licence.service' +const moment = require('moment') + +@Component({ + selector: 'app-lineage', + styleUrls: ['./lineage.component.scss'], + templateUrl: './lineage.component.html', + host: { + class: 'content-container' + } +}) +export class LineageComponent { + public switchFlag: boolean = false + public tableFlag: boolean = true + + public forwardLineage: boolean = false + public flatdata: Array = [] + + public graphLoading: boolean = false + public graphRendering: boolean = false + public graphContainer: boolean = false + public vizInput = '' + + public librariesPaging: boolean = false + public libraryTablesRef: string = '' + public libraryList: Array | undefined + public librariesSearch: string = '' + public tableColumnsRef: string = '' + public tablesList: Array | undefined + public columnsList: Array | undefined + + public lineageTableName: string = '' + public lineageColumnName: string = '' + + public lib: string | null = null + public table: string | undefined + public column: string | undefined + public tableDisable = false + public idlookup: any[] | undefined + + public refreshCache: boolean = false + + public currentLineagePathLibTable: string = '' + public currentLineagePathColumn: string = '' + + public largeDotFileLines: number | null = null + public largeDotFileLimit: number = 1000 //default is 1000 + + public limitDotDepth: boolean = false + + public pendingRenderDownload: string | null = null + + constructor( + private licenceService: LicenceService, + private sasService: SasService, + private route: ActivatedRoute, + public router: Router, + private location: Location, + private eventService: EventService, + private loggerService: LoggerService, + public helperService: HelperService + ) {} + + public showTableSelect() { + this.tableFlag = !this.tableFlag + } + + public async tableOnClick( + tableuri: string, + libTable: any, + library: any, + startupLoad: boolean = false + ) { + if (!libTable['columns']) { + libTable['expanded'] = !libTable['expanded'] + libTable['loadingColumns'] = true + this.table = tableuri + + this.currentLineagePathLibTable = + libTable.LIBNAME + '.' + libTable.TABLENAME + + await this.selectTable(tableuri, libTable) + + if (!startupLoad) { + this.onGenerateGraphTableClick() + } + } else { + libTable['expanded'] = !libTable['expanded'] + + if (libTable['expanded'] === true) { + this.table = tableuri + if (!startupLoad) { + this.onGenerateGraphTableClick() + } + } + } + + this.collapseTreeItems(library['tables'], libTable) + } + + public async selectTable($event: any, libTableTree?: any) { + this.columnsList = [] + + let libTable = { SASControlTable: [{ tableuri: $event }] } + + await this.sasService + .request('lineage/getmetacols', libTable) + .then((res: any) => { + this.columnsList = res.metacols + if (this.columnsList && this.columnsList.length > 0) { + // this.column = this.columnsList[0]['COLURI'] + + libTableTree['columns'] = this.columnsList + libTableTree['expanded'] = true + libTableTree['loadingColumns'] = false + } + }) + .catch((err: any) => err) + + this.setGlobalData() + } + + public loadMoreLibraries() { + if (!this.librariesPaging) { + this.librariesPaging = true + + this.helperService.displayLibraries(this.libraryList, true) + + this.librariesPaging = false + } + } + + public collapseTreeItems(tree: any, itemToSkip: any) { + tree.forEach((item: any) => { + if (JSON.stringify(item) !== JSON.stringify(itemToSkip)) { + item['expanded'] = false + } + }) + } + + public treeNodeClicked(event: any, item: any, tree: any) { + if (event.target.title === 'Collapse') { + this.collapseTreeItems(tree, item) + } + } + + public async libraryOnClick(libid: string, library: any) { + library['inForeground'] = true //When we programatically call this function, we make sure it is visible in the sidebar + + if (!library['tables']) { + library['loadingTables'] = true + + await this.selectLibrary(libid, library) + } else { + library['expanded'] = !library['expanded'] + } + + this.collapseTreeItems(this.libraryList, library) + } + public async selectLibrary($event: any, library?: any) { + this.tablesList = [] + this.columnsList = [] + + let libTable = { SASControlTable: [{ liburi: $event }] } + await this.sasService + .request('lineage/getmetatables', libTable) + .then((res: any) => { + this.tablesList = res.metatables + + if (this.tablesList && this.tablesList.length > 0) { + library['tables'] = this.tablesList + library['expanded'] = true + } + + this.setGlobalData() + }) + .catch((err) => err) + + library['loadingTables'] = false + } + + public columnOnClick(libColumn: any, library: any, libTable: any) { + this.lib = library.LIBRARYID + this.table = libTable.TABLEURI + this.column = libColumn.COLURI + + this.setGlobalData() + this.onGenerateClick() + } + + public treeOnFilter(array: any, arrToFilter: string) { + this.helperService.treeOnFilter(array, arrToFilter) + } + + public libraryOnFilter() { + this.helperService.libraryOnFilter( + this.libraryList, + this.librariesSearch, + 'LIBRARYNAME' + ) + + globals.lineage.librariesSearch = this.librariesSearch + } + + public libColumnActive(libColumnUri: string) { + if (!this.column) { + return false + } + + let splitedLibColumnUri = libColumnUri.split('\\') + let splitedColumnUri = this.column.split('\\') + + return ( + splitedLibColumnUri[splitedLibColumnUri.length - 1] == + splitedColumnUri[splitedColumnUri.length - 1] + ) + } + + public setGlobalData() { + globals.lineage.libraryList = this.libraryList + globals.lineage.tablesList = this.tablesList + globals.lineage.columnsList = this.columnsList + + globals.lineage.lib = this.lib + globals.lineage.table = this.table + globals.lineage.column = this.column + } + + public loadGlobalData() { + this.libraryList = globals.lineage.libraryList + this.tablesList = globals.lineage.tablesList + this.columnsList = globals.lineage.columnsList + this.librariesSearch = globals.lineage.librariesSearch + } + + public resubmitWithMaxDepth(maxDepth: number | string) { + this.cancelRenderingGraph() + + let queryParams = undefined + + if (maxDepth) { + queryParams = { + max_depth: maxDepth + } + } + + this.router.navigate([], { + relativeTo: this.route, + queryParams: queryParams + }) + } + + ngOnInit(): void { + globals.viewer.currentSelection = 'view/lineage' + let reload = this.route.snapshot.params['reload'] + + if (reload !== undefined) { + let url = this.router.url + if (reload === 'reload') { + if (!localStorage.getItem('firstLoad')) { + localStorage['firstLoad'] = true + setTimeout(function () { + window.location.reload() + }, 2000) + } else { + localStorage.removeItem('firstLoad') + this.location.replaceState(url.slice(0, url.lastIndexOf('/'))) + } + } else { + this.location.replaceState(url.slice(0, url.lastIndexOf('/'))) + } + } + + this.initData() + } + + public async initData() { + let coluri = this.route.snapshot.params['coluri'] + let direction = this.route.snapshot.params['direction'] + let table_id = this.route.snapshot.params['tableid'] + + if (globals.lineage.libraryList) { + if (globals.lineage.libraryList.length > 0) { + this.loadGlobalData() + } else { + await this.sasService + .request('public/viewlibs', null) + .then((res: any) => { + this.libraryList = res.saslibs + this.helperService.displayLibraries(this.libraryList) + + if (this.libraryList) { + if (this.libraryList.length > 0) { + this.lib = this.libraryList[0]['LIBRARYID'] + } + } + this.setGlobalData() + }) + .catch((err: any) => err) + } + + this.route.queryParams.subscribe((queryParams) => { + this.onRouteChange() + }) + + this.route.params.subscribe((params) => { + this.onRouteChange() + }) + } + } + + debounceTimeout: any + debounceTime: number = 200 //ms + public onRouteChange() { + clearTimeout(this.debounceTimeout) + + this.debounceTimeout = setTimeout(() => { + const coluri = this.route.snapshot.params['coluri'] + const direction = this.route.snapshot.params['direction'] + const table_id = this.route.snapshot.params['tableid'] + const max_depth = this.route.snapshot.queryParams['max_depth'] + + if (coluri && direction) { + this.forwardLineage = direction === 'FORWARD' + this.column = coluri + this.generateGraph(coluri, direction, max_depth) + } + if (!this.router.url.includes('column') && table_id && direction) { + this.forwardLineage = direction === 'FORWARD' + this.table = table_id + this.generateGraphTableLevel(table_id, direction, max_depth) + } + }, this.debounceTime) + } + + ngAfterContentInit(): void {} + + public directionText() { + return this.forwardLineage ? 'FORWARD' : 'REVERSE' + } + + public onGenerateClick() { + let directionText = this.directionText() + let parsedColumnUrl = this.column + ? this.column.substring(this.column.indexOf('\\') + 1) + : null + + this.router.navigateByUrl( + '/view/lineage/column/' + parsedColumnUrl + '/' + directionText + ) + } + + public onGenerateGraphTableClick() { + let directionText = this.directionText() + let table_id = this.table!.includes('\\') + ? this.table!.split('\\')[1] + : this.table + + this.router.navigateByUrl('/view/lineage/' + table_id + '/' + directionText) + } + + public async generateGraphTableLevel( + table_id: string, + urlDirection?: string, + max_depth?: string + ) { + let libTable: any = { + SASControlTable: [ + { + table_id: table_id, + direction: urlDirection ? urlDirection : this.directionText() + } + ] + } + + if (libTable.SASControlTable[0].table_id === 'undefined') + this.eventService.showAbortModal( + 'generateGraphTableLevel()', + 'table_id is undefined.', + undefined, + 'Frontend error' + ) + + if (max_depth) libTable.SASControlTable[0].max_depth = max_depth + + this.tableFlag = false + this.switchFlag = true + this.graphContainer = true + this.graphLoading = true + this.vizInput = '' + + return new Promise((resolve, reject) => { + this.sasService + .request('lineage/fetchtablelineage', libTable) + .then(async (res: any) => { + if (res.flatdata.length > 0) { + if (this.licenceService.checkLineageLimit()) { + this.eventService.showInfoModal( + 'Notice', + `You have reached daily maximum of lineage diagram renderings. To unlock additional diagrams, contact support@datacontroller.io` + ) + this.router.navigateByUrl('/view/lineage') + return + } + } + + if (typeof res === 'string') { + this.vizInput = 'digraph G {SAS Error}' + this.buildGraph() + return + } + + this.lineageTableName = + res.info[0].LIBREF + '.' + res.info[0].TABLENAME + + let dotArray = res.finalfinal + let vizTmp: string = '' + + for (let i = 0; i < dotArray.length; i++) { + vizTmp += unescape(dotArray[i].LINE) + '\n' + } + + this.flatdata = res.flatdata + + if (this.libraryList) { + let libraryToSelect = this.libraryList.find((library: any) => + res.info[0].LIBURI.toUpperCase().includes( + library.LIBRARYID.toUpperCase() + ) + ) + + if (libraryToSelect) { + let tableToSelect + + await this.libraryOnClick( + libraryToSelect.LIBRARYID, + libraryToSelect + ) + + if (libraryToSelect['tables']) { + tableToSelect = libraryToSelect['tables'].find((table: any) => + table.TABLEURI.toUpperCase().includes( + res.info[0].TABLEID.toUpperCase() + ) + ) + + if (tableToSelect) { + this.table = tableToSelect.TABLEURI + + if (this.table) { + const query = this.table.replace('\\', '\\\\') + + setTimeout(() => { + let tablePElement = document.querySelector( + `[id='${query}']` + ) + + if (tablePElement) { + tablePElement.scrollIntoView() + } + }, 1000) + } + + this.tableOnClick( + tableToSelect.TABLEURI, + tableToSelect, + libraryToSelect, + urlDirection !== undefined + ) + } + } + + if (libraryToSelect) { + libraryToSelect['expanded'] = true + } + + if (tableToSelect) { + tableToSelect['expanded'] = true + } + } + } + + this.vizInput = vizTmp ? vizTmp : 'digraph G {No Lineage Available}' + this.vizInput = this.vizInput + .replace(/\sds:/g, '\nds:') + .replace(/\s\n/g, '\n') + + this.idlookup = res.idlookup + + if (res.finalfinal.length > this.largeDotFileLimit) { + this.largeDotFileLines = res.finalfinal.length + } else { + this.buildGraph() + } + + resolve() + }) + .catch((err: any) => { + this.graphLoading = false + this.graphContainer = false + }) + }) + } + + public cancelRenderingGraph() { + this.vizInput = 'digraph G {No Lineage Available}' + + this.largeDotFileLines = null + this.buildGraph() + } + + public continueRenderingGraph() { + this.largeDotFileLines = null + + this.buildGraph(() => { + if (this.pendingRenderDownload !== null) { + switch (this.pendingRenderDownload) { + case 'PNG': { + this.downloadPNG() + + break + } + case 'SVG': { + this.downloadSVG() + + break + } + } + + this.pendingRenderDownload = null + this.vizInput = 'digraph G {No Lineage Available}' + this.buildGraph() + } + }) + } + + public renderToDownload(type: string) { + switch (type) { + case 'PNG': { + this.pendingRenderDownload = 'PNG' + this.continueRenderingGraph() + + break + } + case 'SVG': { + this.pendingRenderDownload = 'SVG' + this.continueRenderingGraph() + + break + } + } + } + + public makeGraphLinkable(idlookup: any) { + let graphNodes: any = document.querySelectorAll('#graph .node') + + for (let node of graphNodes) { + let metaid = node.querySelector('title').innerHTML + let meta = idlookup.find((x: any) => x.METAID === metaid) + + let href: string + + if (meta) { + if (meta.METATYPE === 'TABLE') { + href = '/view/data/' + meta.METANAME + } else { + href = '/view/metadata/object/' + meta.METAID + } + + node.classList.add('cursor-pointer') + node.addEventListener('click', (event: MouseEvent) => { + this.router.navigateByUrl(href) + }) + } + } + } + + public async generateGraph( + urlColumn?: String | undefined, + urlDirection?: string, + max_depth?: string + ): Promise { + let libTable: any = { + SASControlTable: [ + { + coluri: urlColumn ? urlColumn : this.column, + direction: urlDirection ? urlDirection : this.directionText(), + refresh: this.refreshCache ? 1 : 0 + } + ] + } + + if (libTable.SASControlTable[0].coluri === 'undefined') + this.eventService.showAbortModal( + 'generateGraph()', + 'coluri is undefined.', + undefined, + 'Frontend error' + ) + + if (max_depth) libTable.SASControlTable[0].max_depth = max_depth + + this.tableFlag = false + this.switchFlag = true + this.graphContainer = true + this.graphLoading = true + this.vizInput = '' + + return new Promise((resolve, reject) => { + this.sasService + .request('lineage/fetchcollineage', libTable) + .then(async (res: any) => { + if (res.flatdata.length > 0) { + if (this.licenceService.checkLineageLimit()) { + this.eventService.showInfoModal( + 'Notice', + `You have reached daily maximum of lineage diagram renderings. To unlock additional diagrams, contact support@datacontroller.io` + ) + this.router.navigateByUrl('/view/lineage') + return + } + } + + if (typeof res === 'string') { + this.vizInput = 'digraph G {SAS Error}' + this.buildGraph() + return + } + + this.lineageTableName = res.info[0].LIBREF + '.' + res.info[0].TABNAME + this.lineageColumnName = res.info[0].COLNAME + + this.idlookup = res.idlookup + + let dotArray = res.fromsas + let vizTmp: string = '' + for (let i = 0; i < dotArray.length; i++) { + vizTmp += unescape(dotArray[i].STRING) + '\n' + } + + this.vizInput = vizTmp ? vizTmp : 'digraph G {No Lineage Available}' + this.vizInput = this.vizInput + .replace(/\sds:/g, '\nds:') + .replace(/\s\n/g, '\n') + + this.flatdata = res.flatdata + + if (this.libraryList) { + let libraryToSelect = this.libraryList.find( + (library: any) => + res.info[0]?.LIBURI?.toUpperCase()?.includes( + library?.LIBRARYID?.toUpperCase() + ) + ) + + let tableToSelect: any + + if (libraryToSelect) { + await this.libraryOnClick( + libraryToSelect.LIBRARYID, + libraryToSelect + ) + + if (libraryToSelect['tables']) { + tableToSelect = libraryToSelect['tables'].find( + (table: any) => table.TABLEURI === res.info[0].TABURI + ) + + if (tableToSelect) { + this.tableOnClick( + tableToSelect.TABLEURI, + tableToSelect, + libraryToSelect, + true + ).then(() => { + let tableUri = tableToSelect.TABLEURI + + if (tableUri) { + const query = tableUri.replace('\\', '\\\\') + let tablePElement = document.querySelector( + `[id='${query}']` + ) + + setTimeout(() => { + if (tablePElement) { + this.loggerService.log( + 'libraryToSelect', + libraryToSelect + ) + tablePElement.scrollIntoView() + } + }, 1000) + } + }) + } + } + + if (libraryToSelect) { + libraryToSelect['expanded'] = true + } + + if (tableToSelect) { + tableToSelect['expanded'] = true + } + } + } + + if (res.fromsas.length > this.largeDotFileLimit) { + this.largeDotFileLines = res.fromsas.length + } else { + this.buildGraph() + } + + resolve() + }) + .catch((err: any) => { + this.graphLoading = false + this.graphContainer = false + }) + }) + } + + private getSVGURL() { + let svg: any = document.getElementById('graph') + let serializer = new XMLSerializer() + let svg_blob = new Blob([serializer.serializeToString(svg)], { + type: 'image/svg+xml' + }) + return URL.createObjectURL(svg_blob) + } + + private getSVGBlob() { + let svg: any = document.getElementById('graph') + let serializer = new XMLSerializer() + let svg_blob = new Blob([serializer.serializeToString(svg)], { + type: 'image/svg+xml' + }) + return svg_blob + } + + downloadSVG() { + d3Viz.graphviz('#graph').resetZoom() + + if (navigator.appVersion.toString().indexOf('.NET') > 0) { + window.navigator.msSaveBlob(this.getSVGBlob(), this.constructName('svg')) + } else { + let downloadLink = document.createElement('a') + downloadLink.href = this.getSVGURL() + downloadLink.download = this.constructName('svg') + document.body.appendChild(downloadLink) + downloadLink.click() + document.body.removeChild(downloadLink) + } + } + + async downloadPNG() { + d3Viz.graphviz('#graph').resetZoom() + + saveSvg.saveSvgAsPng( + document.querySelector('#graph svg'), + this.constructName('png') + ) + } + + downloadCSV() { + let data = this.flatdata + + const replacer = (key: any, value: any) => (value === null ? '' : value) + const header = Object.keys(data[0]) + let csv = data.map((row: any) => + header + .map((fieldName) => JSON.stringify(row[fieldName], replacer)) + .join(',') + ) + csv.unshift(header.join(',')) + let csvArray = csv.join('\r\n') + + var a = document.createElement('a') + var blob = new Blob([csvArray], { type: 'text/csv' }) + + if (navigator.appVersion.toString().indexOf('.NET') > 0) { + window.navigator.msSaveBlob(blob, this.constructName('csv')) + } else { + var url = window.URL.createObjectURL(blob) + a.href = url + a.download = this.constructName('csv') + a.click() + window.URL.revokeObjectURL(url) + a.remove() + } + } + + private getDotUrl() { + let data = this.vizInput + let dot_blob = new Blob([data], { type: 'text/plain' }) + return window.URL.createObjectURL(dot_blob) + } + + private getDotBlob() { + let data = this.vizInput + let dot_blob = new Blob([data], { type: 'text/plain' }) + return dot_blob + } + + downloadDot() { + if (navigator.appVersion.toString().indexOf('.NET') > 0) { + window.navigator.msSaveBlob(this.getDotBlob(), this.constructName('txt')) + } else { + let downloadLink = document.createElement('a') + downloadLink.href = this.getDotUrl() + downloadLink.download = this.constructName('txt') + document.body.appendChild(downloadLink) + downloadLink.click() + document.body.removeChild(downloadLink) + } + } + + public showSvg() { + window.open(this.getSVGURL(), '_blank') + } + + public buildGraph(callback?: any) { + this.eventService.closeSidebar() + + this.graphLoading = false + this.graphRendering = true + + setTimeout(() => { + d3Viz + .graphviz('#graph') + .zoom(true) + .addImage( + 'https://datacontroller.io/wp-content/uploads/2020/01/fc1.png', + '30px', + '30px' + ) + .renderDot(this.vizInput, () => { + this.graphRendering = false + + if (!!this.idlookup) { + this.makeGraphLinkable(this.idlookup) + } + + if (callback) { + callback() + } + }) + }, 100) + } + + public constructName(extension: string) { + let libraryName = '' + let tableName = '' + let columnName = '' + let date = moment().format('YYMMDD_HHmm') + if (this.libraryList && this.libraryList.length) { + let library: any = this.libraryList.find( + (e: any) => e.LIBRARYID == this.lib + ) + if (library) { + libraryName = `_${library.LIBRARYNAME}` + } + } + if (this.tablesList && this.tablesList.length) { + let table: any = this.tablesList.find( + (e: any) => e.TABLEURI == this.table + ) + if (table) { + tableName = `_${table.TABLENAME}` + } + } + if (this.columnsList && this.columnsList.length) { + let column: any = this.columnsList.find( + (e: any) => e.COLURI == this.column + ) + if (column) { + columnName = `_${column.COLNAME}` + } + } + return `${this.directionText()}${libraryName}${tableName}${columnName}_${date}.${extension}` + } +} diff --git a/client/src/app/metadata/metadata.component.html b/client/src/app/metadata/metadata.component.html new file mode 100644 index 0000000..a264056 --- /dev/null +++ b/client/src/app/metadata/metadata.component.html @@ -0,0 +1,220 @@ + +
+ + + + +
+ + + +
+ + + +
+
+ + +

+ + {{ metaData.ID }} +

+
+
+
+
+ +
+
+

{{ assoTypeSelected }}

+ +
+ +

Please select a type

+
+ +
+ Loading... +
+

Loading metadata types

+

Loading metadata objects

+
+
+
+
+
+ +
+
+
+ + + + + {{ metaObject.NAME }} +

{{ metaObject.ID }}

+
+ + + +
+ + + {{ entry.display }} +

+ {{ entry.URI }} +

+
+
+
+
+
+
+
+
+ +
+ +
+ +
+

+ {{ metaObject.NAME }} +

+

+ {{ metaObject.ID }} +

+
+
+ + +
+ + + {{ entry.display }} +

+ {{ entry.URI }} +

+
+
+
+
+
+
+ +
+

{{ assoObjectSelected }}

+ + + TYPE + + + + NAME + + + + VALUE + + + + {{ metaObjectAttribute.TYPE }} + {{ metaObjectAttribute.NAME }} + {{ metaObjectAttribute.VALUE }} + + + + Attributes per page + {{ pagination.firstItem + 1 }} - {{ pagination.lastItem + 1 }} of + {{ pagination.totalItems }} Attributes + + + +
+
+
+
diff --git a/client/src/app/metadata/metadata.component.scss b/client/src/app/metadata/metadata.component.scss new file mode 100644 index 0000000..97135ae --- /dev/null +++ b/client/src/app/metadata/metadata.component.scss @@ -0,0 +1,67 @@ + +.objects-col{ + height: 75vh; + overflow: scroll; + border: 1px solid #cccccc; + background: white; + border-radius: 4px; +} + +.cols-head { + background: #fafafa; + border: 1px solid #cccccc; + padding: 10px; + display: flex; +} +.object-text { + display: flex; + align-items: flex-start; + justify-content: space-between; + margin-left: 10px; + flex: 1; +} +.repo-dropdown{ + margin-right: 15px; + margin-left: 15px; + margin-bottom: 10px; +} +.clr-accordion-title{ + width: 100%; +} +.float-right{ + margin: 0px; + float: right; +} +.full-width{ + width: 100%; +} +.object-uri{ + margin: 0px; + margin-top: 5px; +} +.object-header{ + padding-left: 3px; + padding-right: 3px; +} +.object-header:hover{ + background-color: #d8e3e9; + border-radius: 3px; +} +.datagrid-host{ + display: unset !important; +} + +.card { + margin-top: 0; + + flex: 1; + display: flex; + flex-direction: column; +} + +.content-area { + padding: 0.5rem !important; + + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/client/src/app/metadata/metadata.component.ts b/client/src/app/metadata/metadata.component.ts new file mode 100644 index 0000000..0964de9 --- /dev/null +++ b/client/src/app/metadata/metadata.component.ts @@ -0,0 +1,384 @@ +import { Location } from '@angular/common' +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { ClrDatagridStringFilterInterface } from '@clr/angular' +import { Observable, of } from 'rxjs' +import { EventService } from '../services/event.service' +import { HelperService } from '../services/helper.service' +import { SasService } from '../services/sas.service' +import { globals } from '../_globals' + +import { Injectable } from '@angular/core' + +interface MetaData { + NAME: any + TYPE: any + VALUE: any +} +class NameFilter implements ClrDatagridStringFilterInterface { + accepts(data: MetaData, search: string): boolean { + return ( + '' + data.NAME === search || data.NAME.toLowerCase().indexOf(search) >= 0 + ) + } +} + +class TypeFilter implements ClrDatagridStringFilterInterface { + accepts(data: MetaData, search: string): boolean { + return ( + '' + data.TYPE === search || data.TYPE.toLowerCase().indexOf(search) >= 0 + ) + } +} + +class ValueFilter implements ClrDatagridStringFilterInterface { + accepts(data: MetaData, search: string): boolean { + return ( + '' + data.VALUE === search || + data.VALUE.toLowerCase().indexOf(search) >= 0 + ) + } +} + +@Injectable({ + providedIn: 'root' +}) +@Component({ + selector: 'app-metadata', + templateUrl: './metadata.component.html', + styleUrls: ['./metadata.component.scss'], + host: { + class: 'content-container' + } +}) +export class MetadataComponent implements OnInit { + metaDataList: Array | undefined + metaDataSearch: string = '' + metaObjectList: Array | undefined + metaObjectShowList: Array | undefined + metaObjectSearch: string = '' + metaObjectAssociations: Array = [] + metaObjectAttributes: Array = [] + assosiationNames: Array | undefined + assosiationProperties: Array | undefined + showTable: boolean = false + showAcc: boolean = false + root$: Observable | undefined + public metaDataId: string = '' + public typeFilter: any + public nameFilter: any + public valueFilter: any + public pageSize!: number + public loading: boolean = true + public metatypesLoading = true + public metaObjectSize = 200 + public assoTypeSelected = '' + public assoObjectSelected = '' + public repositories: Array | undefined + public repository = '' + public objectRoute = false + public showData = false + public objectView = false + + constructor( + private eventService: EventService, + private sasService: SasService, + private helperService: HelperService, + private location: Location, + private router: Router, + private route: ActivatedRoute + ) {} + + ngOnInit() { + globals.viewer.currentSelection = 'view/metadata' + if (this.router.url.includes('/view/metadata/object/')) { + this.objectRoute = true + this.objectView = true + } + this.pageSize = 5 + + if ( + globals.metadata.metaDataList && + globals.metadata.metaRepositories && + !this.objectRoute + ) { + this.metaDataList = globals.metadata.metaDataList + this.repositories = globals.metadata.metaRepositories + this.repository = globals.metadata.selectedRepository + this.loading = false + this.metatypesLoading = false + this.metaDataSearch = globals.metadata.metaDataSearch + } else { + this.sasService.request('metanav/metatypes', null).then((res: any) => { + this.metaDataList = res.types + globals.metadata.metaDataList = this.metaDataList + this.loading = false + this.metatypesLoading = false + }) + + this.sasService.request('metanav/metarepos', null).then((res: any) => { + let foundation = false + this.repositories = [] + for (let index = 0; index < res.outrepos.length; index++) { + this.repositories.push(res.outrepos[index].NAME) + if (res.outrepos[index].NAME === 'Foundation') { + foundation = true + } + } + if (foundation) { + this.repository = 'Foundation' + } else { + this.repository = res.outrepos[0].NAME + } + globals.metadata.metaRepositories = this.repositories + globals.metadata.selectedRepository = this.repository + if (this.objectRoute) { + this.eventService.closeSidebar() + this.showData = true + let name = '' + let id = this.route.snapshot.params['objectID'] + // let temp = this.router.url.split("%20").join(" ").split("/").reverse(); + this.metaObjectList = [] + this.metaObjectList.push({ ID: id, NAME: name }) + this.metaObjectShowList = this.metaObjectList + this.metaObjectOnClick( + this.metaObjectShowList[0].ID, + this.metaObjectShowList[0] + ) + } + }) + } + } + + public treeNodeClicked(event: any, item: any, tree: any) { + if (event.target.title === 'Collapse') { + this.collapseTreeItems(tree, item) + } + } + + public collapseTreeItems(tree: any, itemToSkip: any) { + tree.forEach((item: any) => { + if (JSON.stringify(item) !== JSON.stringify(itemToSkip)) { + item['expanded'] = false + } + }) + } + + public metaDataOnClick(metaDataId: string, metaData: any) { + this.objectView = false + this.location.replaceState('/view/metadata') + this.showData = false + this.loading = true + this.selectmetaData(metaDataId, metaData) + } + + public metaObjectOnClick(metaObjectId: string, metaObject: any) { + this.assoObjectSelected = ' . ' + this.showAcc = false + this.metaObjectAttributes = [] + this.selectmetaObject(metaObjectId, metaObject) + } + + public async selectmetaData($event: any, metaData?: any) { + const data: any = { + SASControlTable: [{ metatype: $event, repo: this.repository }] + } + this.sasService.request('metanav/metaobjects', data).then((res: any) => { + this.metaObjectList = res.objects + this.getMetaObjectAttributes(this.metaObjectSize) + this.loading = false + this.assoTypeSelected = $event + this.eventService.closeSidebar() + this.showData = true + }) + } + + public async selectmetaObject($event: any, metaData?: any) { + let data: any = { + SASControlTable: [{ objecturi: $event }] + } + this.sasService.request('metanav/metadetails', data).then((res: any) => { + this.metaObjectAssociations = res.associations + this.root$ = of(this.getAssosiationsCount(res.associations)) + this.showAcc = true + this.showTable = true + let metaObjectName = res.attributes.find( + (x: any) => x.NAME === 'Name' + ).VALUE + this.assoObjectSelected = metaObjectName + metaData.NAME = metaObjectName + let url = this.router.url + if (this.objectRoute) { + // this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME)); + this.location.replaceState( + url.slice(0, url.lastIndexOf('object')) + + 'object/' + + $event.slice(1 + $event.indexOf('\\')) + ) + } else { + // this.location.replaceState(url + "/object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME)); + this.location.replaceState( + url + '/object/' + $event.slice(1 + $event.indexOf('\\')) + ) + } + this.metaObjectAttributes = res.attributes + }) + } + + public async selectAssosiationsDetails($event: any, metaData?: any) { + let data: any = { + SASControlTable: [{ objecturi: $event }] + } + this.sasService.request('metanav/metadetails', data).then((res: any) => { + this.metaObjectAttributes = res.attributes + this.showTable = true + }) + } + + public getAssosiationsCount(assosiationList: Array) { + let assosiationsHash = new Map() + for (let assosiation of assosiationList) { + if (!assosiationsHash.has(assosiation.ASSOC)) { + assosiationsHash.set(assosiation.ASSOC, { + count: 0, + details: [] + }) + } + let assocObj = assosiationsHash.get(assosiation.ASSOC) + assocObj.count++ + assocObj.details.push({ + ASSOCURI: assosiation.ASSOCURI, + NAME: assosiation.NAME, + display: assosiation.NAME, + URI: assosiation.ASSOCURI.slice(assosiation.ASSOCURI.indexOf(':') + 1) + }) + } + let assocGrouped: Array = [] + assosiationsHash.forEach(function (val, key) { + assocGrouped.push({ + ASSOC: key, + count: val.count, + details: val.details, + display: key + ' ( ' + val.count + ' )' + }) + }) + return assocGrouped + } + + public setTypeAssosiations(assosiationType: String) { + let tempAssosiations: Array = [] + for (let assosiation of this.metaObjectAssociations) { + if (assosiation.ASSOC === assosiationType) { + tempAssosiations.push(assosiation) + } + } + this.assosiationNames = tempAssosiations + return tempAssosiations + } + + public assosiationNameOnClick(assosiationId: any) { + this.assoObjectSelected = ' . ' + this.metaObjectAttributes = [] + this.showTable = false + this.selectAssosiationsDetails(assosiationId) + } + + public getChildren = (asso: any) => { + // if group_association clicked return list of Objects + if (asso.count) { + return of(asso.details) + } + // else return following api response + const data: any = { + SASControlTable: [{ objecturi: asso.ASSOCURI }] + } + return this.sasService + .request('metanav/metadetails', data) + .then((res: any) => { + this.showTable = true + this.metaObjectAttributes = res.attributes + this.assoObjectSelected = asso.NAME + let url = this.router.url + if (this.objectRoute) { + // this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" +asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf("\\")) + "/" + escape(asso.NAME)); + this.location.replaceState( + url.slice(0, url.lastIndexOf('object')) + + 'object/' + + asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\')) + ) + } else { + // this.location.replaceState( url + "/object/" + asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf("\\")) + "/" + escape(asso.NAME)); + this.location.replaceState( + url + + '/object/' + + asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\')) + ) + } + return this.getAssosiationsCount(res.associations) + }) + } + + public metaListOnFilter() { + this.helperService.libraryOnFilter( + this.metaDataList, + this.metaDataSearch, + 'ID' + ) + + globals.metadata.metaDataSearch = this.metaDataSearch + } + + public metaObjectOnFilter() { + this.metaObjectAttributes = [] + this.helperService.metaObjectOnFilter( + this.metaObjectList, + this.metaObjectSearch, + 'NAME' + ) + this.getMetaObjectAttributes(this.metaObjectSize) + globals.metadata.metaObjectSearch = this.metaObjectSearch + } + + public getMetaObjectAttributes(num: number) { + if (this.metaObjectList !== undefined && this.metaObjectList.length > num) { + let counter = 0 + let breakIndex = -1 + for (let index = 0; index < this.metaObjectList.length; index++) { + if ( + this.metaObjectList[index]['hidden'] === undefined || + this.metaObjectList[index]['hidden'] === false + ) { + counter++ + } + if (counter === num) { + breakIndex = index + break + } + } + if (breakIndex !== -1) { + this.metaObjectShowList = this.metaObjectList.slice(0, breakIndex) + } else { + this.metaObjectShowList = this.metaObjectList + } + } else { + this.metaObjectShowList = this.metaObjectList + } + } + + debounce: boolean = false + panelChange(event: boolean, object: any) { + if (!this.debounce) { + this.metaObjectOnClick(object.ID, object) + + this.debounce = true + + setTimeout(() => { + this.debounce = false + }, 600) + } + } + + updateSelectedRepository() { + globals.metadata.selectedRepository = this.repository + } +} diff --git a/client/src/app/models/CellValidationSource.ts b/client/src/app/models/CellValidationSource.ts new file mode 100644 index 0000000..b7f10a5 --- /dev/null +++ b/client/src/app/models/CellValidationSource.ts @@ -0,0 +1,9 @@ +export interface CellValidationSource { + col: number + row: number + strict: boolean + values: any[] + extended_values?: string[] + hash: string + count: number +} diff --git a/client/src/app/models/DcAdapterSettings.ts b/client/src/app/models/DcAdapterSettings.ts new file mode 100644 index 0000000..6607a51 --- /dev/null +++ b/client/src/app/models/DcAdapterSettings.ts @@ -0,0 +1,7 @@ +import { SASjsConfig } from '@sasjs/adapter' + +export interface DcAdapterSettings extends Partial { + adminGroup: string + dcPath: string + hotLicenceKey: string +} diff --git a/client/src/app/models/FileUploader.class.ts b/client/src/app/models/FileUploader.class.ts new file mode 100644 index 0000000..e7b1f4a --- /dev/null +++ b/client/src/app/models/FileUploader.class.ts @@ -0,0 +1,7 @@ +export class FileUploader { + queue: File[] = [] + + addToQueue(files: File[]): void { + this.queue.push(...files) + } +} diff --git a/client/src/app/models/FilterQuery.ts b/client/src/app/models/FilterQuery.ts new file mode 100644 index 0000000..e9b60d1 --- /dev/null +++ b/client/src/app/models/FilterQuery.ts @@ -0,0 +1,21 @@ +export interface FilterClause { + ddtype: string + invalidClause: boolean + logic: any + operator: string + operators: string[] + type: string + value: any + values: { formatted: string; unformatted: any }[] + variable: string +} + +export interface FilterGroup { + filterClauses: FilterClause[] + clauseLogic?: string +} + +export interface FilterQuery { + groupLogic: string + filterGroups: FilterGroup[] +} diff --git a/client/src/app/models/HotTable.interface.ts b/client/src/app/models/HotTable.interface.ts new file mode 100644 index 0000000..b35bb10 --- /dev/null +++ b/client/src/app/models/HotTable.interface.ts @@ -0,0 +1,8 @@ +import Handsontable from 'handsontable' + +export interface HotTableInterface extends Handsontable.GridSettings { + height?: number | string | (() => number | string) + data: any + hidden?: boolean + settings: Handsontable.GridSettings +} diff --git a/client/src/app/models/InfoModal.ts b/client/src/app/models/InfoModal.ts new file mode 100644 index 0000000..390d51d --- /dev/null +++ b/client/src/app/models/InfoModal.ts @@ -0,0 +1,14 @@ +export class InfoModal { + id?: number + modalTitle?: string + sasService: string | null = null + message: string = '' + details: AbortDetails | null = new AbortDetails() +} + +export class AbortDetails { + SYSWARNINGTEXT?: string + SYSERRORTEXT?: string + MAC?: string + LOG?: string +} diff --git a/client/src/app/models/LicenceState.ts b/client/src/app/models/LicenceState.ts new file mode 100644 index 0000000..1bdb348 --- /dev/null +++ b/client/src/app/models/LicenceState.ts @@ -0,0 +1,40 @@ +export interface LicenceState { + users_allowed?: number + viewer_rows_allowed: number + editor_rows_allowed: number + stage_rows_allowed: number + history_rows_allowed: number + submit_rows_limit: number + viewbox_limit: number + lineage_daily_limit: number + tables_in_library_limit: number //If limit is 5 that means first 5 tables in the list will be UNLOCKED, rest of it LOCKED + viewbox: boolean + fileUpload: boolean + editRecord: boolean + addRecord: boolean +} + +/** + * '-' means unset + * '0' disabled + * '1' enabled + * '10' number when not toggling position + * ',' separator + * + * Example: + * coding: '10,15,15,-,15,5,35,1,1,3,1,1,1,1' + */ +export enum LicenceFeaturesMap { + viewer_rows_allowed = 0, + editor_rows_allowed = 1, + stage_rows_allowed = 2, + history_rows_allowed = 3, + submit_rows_limit = 4, + tables_in_library_limit = 5, + viewbox = 6, + viewbox_limit = 7, + lineage_daily_limit = 8, + fileUpload = 9, + editRecord = 10, + addRecord = 11 +} diff --git a/client/src/app/models/LicenseKeyData.ts b/client/src/app/models/LicenseKeyData.ts new file mode 100644 index 0000000..13759eb --- /dev/null +++ b/client/src/app/models/LicenseKeyData.ts @@ -0,0 +1,9 @@ +export interface LicenseKeyData { + valid_until: string + users_allowed: number + site_id: string + site_id_multiple: string[] + demo: boolean + hot_license_key: string | undefined + features?: string +} diff --git a/client/src/app/models/RequestWrapperOptions.ts b/client/src/app/models/RequestWrapperOptions.ts new file mode 100644 index 0000000..53ac716 --- /dev/null +++ b/client/src/app/models/RequestWrapperOptions.ts @@ -0,0 +1,4 @@ +export interface RequestWrapperOptions { + suppressSuccessAbortModal?: boolean + suppressErrorAbortModal?: boolean +} diff --git a/client/src/app/models/SheetInfo.ts b/client/src/app/models/SheetInfo.ts new file mode 100644 index 0000000..7b55229 --- /dev/null +++ b/client/src/app/models/SheetInfo.ts @@ -0,0 +1,10 @@ +export default interface SheetInfo { + foundData: boolean + sheetName: string + startRow: number + endRow: number + csvArrayHeadersMap: any + missingHeaders: string[] + rangeStartRow: number + rangeStartCol: number +} diff --git a/client/src/app/models/TableData.ts b/client/src/app/models/TableData.ts new file mode 100644 index 0000000..b70425a --- /dev/null +++ b/client/src/app/models/TableData.ts @@ -0,0 +1,55 @@ +export interface QueryClause { + GROUP_LOGIC: string + SUBGROUP_LOGIC: string + SUBGROUP_ID: number + VARIABLE_NM: any + OPERATOR_NM: string + RAW_VALUE: string +} + +export interface ColumnDetail { + DDTYPE: string + FORMAT: string + LABEL: string + LENGTH: number + NAME: string + TYPE: string + VARNUM: number +} + +export interface Approver { + PERSONNAME: string + EMAIL: string + USERID: string +} + +export interface DQData { + BASE_COL: string + RULE_DATA: string + RULE_VALUE: string + SELECTBOX_ORDER: number +} + +export interface MaxVarLength { + MAXLEN: number + NAME: string +} + +export interface SASParam { + COLHEADERS: string + COLTYPE: string + DTTMVARS: string + DTVARS: string + CLS_FLAG: number + FILTER_TEXT: string + LOADTYPE: string + PK: string + PKCNT: number + RK_FLAG: number + TMVARS: string +} + +export interface ExcelRule { + XL_COLUMN: string + XL_RULE: string +} diff --git a/client/src/app/models/sas/auditors-postdata.model.ts b/client/src/app/models/sas/auditors-postdata.model.ts new file mode 100644 index 0000000..2e660c8 --- /dev/null +++ b/client/src/app/models/sas/auditors-postdata.model.ts @@ -0,0 +1,136 @@ +import { BaseSASResponse } from './common/BaseSASResponse' +import { Col } from '../../shared/dc-validator/models/col.model' +export interface AuditorsPostdataSASResponse extends BaseSASResponse { + params: Param[] + cols: Col[] + submits: Submit[] + deleted: any[] + new: any[] + updates: Update[] + originals: Original[] + fmt_deleted: any[] + fmt_new: any[] + fmt_updates: Update[] + fmt_originals: Original[] +} + +export interface Param { + BASE_DS: string + BASE_LIB: string + DIFFS_CSV: string + DIFFTIME: string + FILESIZE_RAW: number + FILESIZE: string + INPUT_OBS: number + INPUT_VARS: number + ISAPPROVER: string + LIBDS: string + NUM_ADDED: number + NUM_DELETED: number + NUM_OF_APPROVALS_REMAINING: number + NUM_OF_APPROVALS_REQUIRED: number + NUM_UPDATED: number + REVIEWED_BY_NM: string + REVIEWED_ON_DTTM?: any + REVIEWED_ON: string + SUBMITTED_BY_NM: string + SUBMITTED_ON_DTTM: number + SUBMITTED_ON: string + SUBMITTED_REASON_TXT: string + SUBMIT_STATUS_CD: string + TABLE_ID: string + TECH_TO_DTTM: number + TRUNCATED: string + [key: string]: any +} + +export interface Submit { + TABLE_ID: string + TECH_FROM_DTTM: number + BASE_TABLE: string + INPUT_VARS: number + INPUT_OBS: number + SUBMITTED_BY_NM: string + SUBMITTED_ON_DTTM: number + SUBMITTED_REASON_TXT: string + APPROVER: string + REVIEW_STATUS_ID: string + REVIEWED_BY_NM: string + REVIEWED_ON_DTTM?: any + REVIEW_REASON_TXT: string + TECH_TO_DTTM: number + NUM_OF_APPROVALS_REQUIRED?: any + [key: string]: any +} + +export interface New { + LIBREF: string + DSN: string + NUM_OF_APPROVALS_REQUIRED: number + LOADTYPE: string + BUSKEY: string + VAR_TXFROM: string + VAR_TXTO: string + VAR_BUSFROM: string + VAR_BUSTO: string + VAR_PROCESSED: string + CLOSE_VARS: string + PRE_EDIT_HOOK: string + POST_EDIT_HOOK: string + PRE_APPROVE_HOOK: string + POST_APPROVE_HOOK: string + SIGNOFF_COLS: string + SIGNOFF_HOOK: string + NOTES: string + RK_UNDERLYING: string + HELPFUL_LINK: string + [key: string]: any +} + +export interface Update { + LIBREF: string + DSN: string + NUM_OF_APPROVALS_REQUIRED: number + LOADTYPE: string + BUSKEY: string + VAR_TXFROM: string + VAR_TXTO: string + VAR_BUSFROM: string + VAR_BUSTO: string + VAR_PROCESSED: string + CLOSE_VARS: string + PRE_EDIT_HOOK: string + POST_EDIT_HOOK: string + PRE_APPROVE_HOOK: string + POST_APPROVE_HOOK: string + SIGNOFF_COLS: string + SIGNOFF_HOOK: string + NOTES: string + RK_UNDERLYING: string + HELPFUL_LINK: string + [key: string]: any +} + +export interface Original { + LIBREF: string + DSN: string + NUM_OF_APPROVALS_REQUIRED: number + LOADTYPE: string + BUSKEY: string + VAR_TXFROM: string + VAR_TXTO: string + VAR_BUSFROM: string + VAR_BUSTO: string + VAR_PROCESSED: string + CLOSE_VARS: string + PRE_EDIT_HOOK: string + POST_EDIT_HOOK: string + PRE_APPROVE_HOOK: string + POST_APPROVE_HOOK: string + SIGNOFF_COLS: string + SIGNOFF_HOOK: string + NOTES: string + RK_UNDERLYING: string + HELPFUL_LINK: string + [key: string]: any +} diff --git a/client/src/app/models/sas/common/BaseSASResponse.ts b/client/src/app/models/sas/common/BaseSASResponse.ts new file mode 100644 index 0000000..b03a098 --- /dev/null +++ b/client/src/app/models/sas/common/BaseSASResponse.ts @@ -0,0 +1,19 @@ +export interface BaseSASResponse { + SYSDATE: string + SYSTIME: string + SYSUSERID: string + MF_GETUSER: string + SYS_JES_JOB_URI: string + SYSJOBID: string + _DEBUG: string + _PROGRAM: string + SYSCC: string + SYSERRORTEXT: string + SYSHOSTNAME: string + SYSSCPL: string + SYSSITE: string + SYSVLONG: string + SYSWARNINGTEXT: string + END_DTTM: string + MEMSIZE: string +} diff --git a/client/src/app/models/sas/common/DateFormat.ts b/client/src/app/models/sas/common/DateFormat.ts new file mode 100644 index 0000000..df978d9 --- /dev/null +++ b/client/src/app/models/sas/common/DateFormat.ts @@ -0,0 +1,6 @@ +export interface DataFormat { + format: string + label: string + length: string + type: string +} diff --git a/client/src/app/models/sas/common/Libinfo.ts b/client/src/app/models/sas/common/Libinfo.ts new file mode 100644 index 0000000..425a143 --- /dev/null +++ b/client/src/app/models/sas/common/Libinfo.ts @@ -0,0 +1,11 @@ +export interface Libinfo { + ENGINE: string + LIBNAME: string + PATHS: string + PERMS: string + OWNERS: string + SCHEMAS: string + LIBID: string + LIBSIZE: number + TABLE_CNT: number +} diff --git a/client/src/app/models/sas/editors-getdata.model.ts b/client/src/app/models/sas/editors-getdata.model.ts new file mode 100644 index 0000000..63580a7 --- /dev/null +++ b/client/src/app/models/sas/editors-getdata.model.ts @@ -0,0 +1,71 @@ +import { Col } from 'src/app/shared/dc-validator/models/col.model' +import { DQRule } from 'src/app/shared/dc-validator/models/dq-rules.model' +import { DQData, SASParam } from '../TableData' +import { BaseSASResponse } from './common/BaseSASResponse' +import { DataFormat } from './common/DateFormat' + +export interface EditorsGetdataServiceResponse { + data: EditorsGetdataSASResponse + libds: string +} + +export interface EditorsGetdataSASResponse extends BaseSASResponse { + $sasdata: $DataFormats + sasdata: Sasdata[] + sasparams: SASParam[] + approvers: Approver[] + dqrules: DQRule[] + dsmeta: DSMeta[] + dqdata: DQData[] + cols: Col[] + maxvarlengths: Maxvarlength[] + xl_rules: any[] + query: any[] +} + +export interface DSMeta { + ODS_TABLE: string + NAME: string + VALUE: string +} + +export interface Sasdata { + _____DELETE__THIS__RECORD_____: string + PRIMARY_KEY_FIELD: number + SOME_CHAR: string + SOME_DROPDOWN: string + SOME_NUM: number + SOME_DATE: string + SOME_DATETIME: string + SOME_TIME: string + SOME_SHORTNUM: number + SOME_BESTNUM: number +} + +export interface Vars { + _____DELETE__THIS__RECORD_____: DataFormat + PRIMARY_KEY_FIELD: DataFormat + SOME_CHAR: DataFormat + SOME_DROPDOWN: DataFormat + SOME_NUM: DataFormat + SOME_DATE: DataFormat + SOME_DATETIME: DataFormat + SOME_TIME: DataFormat + SOME_SHORTNUM: DataFormat + SOME_BESTNUM: DataFormat + [key: string]: DataFormat +} +export interface $DataFormats { + vars: Vars +} + +export interface Approver { + PERSONNAME: string + EMAIL: string + USERID: string +} + +export interface Maxvarlength { + NAME: string + MAXLEN: number +} diff --git a/client/src/app/models/sas/public-getcolvals.model.ts b/client/src/app/models/sas/public-getcolvals.model.ts new file mode 100644 index 0000000..9f62c51 --- /dev/null +++ b/client/src/app/models/sas/public-getcolvals.model.ts @@ -0,0 +1,30 @@ +import { BaseSASResponse } from './common/BaseSASResponse' +import { DataFormat } from './common/DateFormat' + +export interface PublicGetcolvalsSASResponse extends BaseSASResponse { + vals: Val[] + $vals: $Vals + meta: Meta[] +} + +export interface Val { + FORMATTED: string + UNFORMATTED: string | number +} + +export interface Meta { + COLUMN: string + SASFORMAT: string + STARTROW: string + ROWS: string + NOBS: number +} + +export interface $Vals { + vars: Vars +} + +export interface Vars { + FORMATTED: DataFormat + UNFORMATTED: DataFormat +} diff --git a/client/src/app/models/sas/public-getgroups.model.ts b/client/src/app/models/sas/public-getgroups.model.ts new file mode 100644 index 0000000..c2ce3d1 --- /dev/null +++ b/client/src/app/models/sas/public-getgroups.model.ts @@ -0,0 +1,11 @@ +import { BaseSASResponse } from './common/BaseSASResponse' + +export interface PublicGetgroupsResponse extends BaseSASResponse { + groups: any[] +} + +export interface SASGroup { + GROUPDESC: string + GROUPNAME: string + GROUPURI: string +} diff --git a/client/src/app/models/sas/public-refreshlibinfo.model.ts b/client/src/app/models/sas/public-refreshlibinfo.model.ts new file mode 100644 index 0000000..2484beb --- /dev/null +++ b/client/src/app/models/sas/public-refreshlibinfo.model.ts @@ -0,0 +1,6 @@ +import { BaseSASResponse } from './common/BaseSASResponse' +import { Libinfo } from './common/Libinfo' + +export interface PublicRefreshlibinfoServiceResponse extends BaseSASResponse { + libinfo: Libinfo[] +} diff --git a/client/src/app/models/sas/public-startupservice.model.ts b/client/src/app/models/sas/public-startupservice.model.ts new file mode 100644 index 0000000..8a241cc --- /dev/null +++ b/client/src/app/models/sas/public-startupservice.model.ts @@ -0,0 +1,17 @@ +import { BaseSASResponse } from './common/BaseSASResponse' + +export interface PublicStartupserviceResponse extends BaseSASResponse { + sasdatasets: any[] + saslibs: any[] + globvars: Globvar[] +} + +export interface Globvar { + DCLIB: string + SAS9LINEAGE_ENABLED: number + ISREGISTERED: number + REGISTERCOUNT: number + LICENCE_KEY: string + ACTIVATION_KEY: string + DC_ADMIN_GROUP: string +} diff --git a/client/src/app/models/sas/public-viewlibs.model.ts b/client/src/app/models/sas/public-viewlibs.model.ts new file mode 100644 index 0000000..5646201 --- /dev/null +++ b/client/src/app/models/sas/public-viewlibs.model.ts @@ -0,0 +1,12 @@ +import { BaseSASResponse } from './common/BaseSASResponse' + +export interface PublicViewlibsServiceResponse extends BaseSASResponse { + saslibs: Saslibs[] +} + +export interface Saslibs { + ENGINE: string + LIBRARYID: string + LIBRARYNAME: string + LIBRARYREF: string +} diff --git a/client/src/app/models/sas/public-viewtables.model.ts b/client/src/app/models/sas/public-viewtables.model.ts new file mode 100644 index 0000000..9efbaf0 --- /dev/null +++ b/client/src/app/models/sas/public-viewtables.model.ts @@ -0,0 +1,7 @@ +import { BaseSASResponse } from './common/BaseSASResponse' +import { Libinfo } from './common/Libinfo' + +export interface PublicViewtablesServiceResponse extends BaseSASResponse { + mptables: { MEMNAME: string }[] + libinfo: Libinfo[] +} diff --git a/client/src/app/models/sas/validate-filter.model.ts b/client/src/app/models/sas/validate-filter.model.ts new file mode 100644 index 0000000..92965e0 --- /dev/null +++ b/client/src/app/models/sas/validate-filter.model.ts @@ -0,0 +1,11 @@ +import { BaseSASResponse } from './common/BaseSASResponse' + +export interface ValidateFilterSASResponse extends BaseSASResponse { + result: Result[] +} + +export interface Result { + FILTER_RK: number + FILTER_HASH: string + FILTER_TABLE: string +} diff --git a/client/src/app/models/sasjs-api/SASjsApiDriveFileTree.model.ts b/client/src/app/models/sasjs-api/SASjsApiDriveFileTree.model.ts new file mode 100644 index 0000000..b20b0a1 --- /dev/null +++ b/client/src/app/models/sasjs-api/SASjsApiDriveFileTree.model.ts @@ -0,0 +1,11 @@ +export interface SASjsApiTree { + name: string + relativePath: string + absolutePath: string + children: SASjsApiTree[] +} + +export interface SASjsApiDriveFileTree { + status: string + tree: SASjsApiTree +} diff --git a/client/src/app/models/sasjs-api/SASjsApiDriveFolderContents.model.ts b/client/src/app/models/sasjs-api/SASjsApiDriveFolderContents.model.ts new file mode 100644 index 0000000..16b297b --- /dev/null +++ b/client/src/app/models/sasjs-api/SASjsApiDriveFolderContents.model.ts @@ -0,0 +1,4 @@ +export interface SASjsApiDriveFolderContents { + folders: string[] + files: string[] +} diff --git a/client/src/app/models/sasjs-api/SASjsApiServerInfo.model.ts b/client/src/app/models/sasjs-api/SASjsApiServerInfo.model.ts new file mode 100644 index 0000000..b56398b --- /dev/null +++ b/client/src/app/models/sasjs-api/SASjsApiServerInfo.model.ts @@ -0,0 +1,7 @@ +export interface SASjsApiServerInfo { + mode: string + cors: string + whiteList: string[] + protocol: string + runTimes: string[] +} diff --git a/client/src/app/not-found/not-found.component.html b/client/src/app/not-found/not-found.component.html new file mode 100644 index 0000000..39f7c74 --- /dev/null +++ b/client/src/app/not-found/not-found.component.html @@ -0,0 +1,3 @@ +
+

404 - Not Found

+
diff --git a/client/src/app/not-found/not-found.component.scss b/client/src/app/not-found/not-found.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/not-found/not-found.component.ts b/client/src/app/not-found/not-found.component.ts new file mode 100644 index 0000000..6bb0330 --- /dev/null +++ b/client/src/app/not-found/not-found.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-not-found', + templateUrl: './not-found.component.html', + styleUrls: ['./not-found.component.scss'], + host: { + class: 'content-container' + } +}) +export class NotFoundComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/client/src/app/pipes/convert-size.pipe.ts b/client/src/app/pipes/convert-size.pipe.ts new file mode 100644 index 0000000..e08ffe3 --- /dev/null +++ b/client/src/app/pipes/convert-size.pipe.ts @@ -0,0 +1,14 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { bytesToSize } from '@sasjs/utils/utils/bytesToSize' + +@Pipe({ + name: 'convertSize' +}) +export class ConvertSizePipe implements PipeTransform { + transform(bytes: string | number, ...args: string[]): string { + const decimals = parseInt(args[0]) || 2 + const bytesNum = typeof bytes !== 'number' ? parseInt(bytes) : bytes + + return bytesToSize(bytesNum, decimals) + } +} diff --git a/client/src/app/pipes/date-time-formatter.pipe.ts b/client/src/app/pipes/date-time-formatter.pipe.ts new file mode 100644 index 0000000..46a1704 --- /dev/null +++ b/client/src/app/pipes/date-time-formatter.pipe.ts @@ -0,0 +1,32 @@ +import { Pipe, PipeTransform } from '@angular/core' +import * as moment from 'moment' +@Pipe({ + name: 'dateTimeFormatter' +}) +export class DateTimeFormatterPipe implements PipeTransform { + transform(value: Date | string, type: string): string { + if (typeof value === 'string' && value.length < 1) return value + + switch (type) { + case 'date': { + return moment(value, 'DDMMMYYYY:hh:mm:ss').format('DD/MM/YYYY') + } + case 'time': { + if (typeof value !== 'string') + throw new Error('Error parsing time. Value is not string.') + + const hours = parseInt(value.split(':')[0]) + const minutes = parseInt(value.split(':')[1]) + const seconds = parseInt(value.split(':')[2]) + + const hoursString = hours < 10 ? '0' + hours : hours + const minutesString = minutes < 10 ? '0' + minutes : minutes + const secondsString = seconds < 10 ? '0' + seconds : seconds + + return `${hoursString}:${minutesString}:${secondsString}` + } + } + + return typeof value === 'string' ? value : value.toString() + } +} diff --git a/client/src/app/pipes/linkinze.pipe.ts b/client/src/app/pipes/linkinze.pipe.ts new file mode 100644 index 0000000..75975fa --- /dev/null +++ b/client/src/app/pipes/linkinze.pipe.ts @@ -0,0 +1,30 @@ +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'linkinze' +}) +export class LinkinzePipe implements PipeTransform { + /** + * It makes path/url to be clicklable + * @param path /example/path + * @returns string to be used in `innerHTML` + */ + transform(path: string): string { + if (!path.includes('/')) return path + + let cascadingPath = '' + + const pathSplit = path.split('/') + + for (let i = 0; i < pathSplit.length; i++) { + if (pathSplit[i] !== '') { + const link = pathSplit[i] + cascadingPath += '/' + link + + pathSplit[i] = `${link}` + } + } + + return pathSplit.join('/') + } +} diff --git a/client/src/app/pipes/ms-to-date.pipe.ts b/client/src/app/pipes/ms-to-date.pipe.ts new file mode 100644 index 0000000..da14414 --- /dev/null +++ b/client/src/app/pipes/ms-to-date.pipe.ts @@ -0,0 +1,52 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { HelperService } from '../services/helper.service' + +@Pipe({ + name: 'sasToJsDate' +}) +export class sasToJsDatePipe implements PipeTransform { + constructor(private helperService: HelperService) {} + + transform( + sasValue: string | number, + sasUnit: string = 'days', + returnOnlyTime: boolean = false + ): Date | string | null { + if (sasValue === undefined) sasValue = '' + if (typeof sasValue !== 'string') sasValue = sasValue.toString() + + if (sasValue.length === 0) { + if (sasUnit === 'days') return null + if (sasUnit === 'seconds') { + if (returnOnlyTime) { + return '11:00:00' + } else { + return null + } + } + } + + let jsDate = this.helperService.convertSasDaysToJsDate(sasValue, sasUnit) + + // If it's datetime value (formatted) we parse it, conversion is overridden + if (sasValue.split(':').length === 4) { + const sasValueSplit = sasValue.split(':') + + jsDate = new Date(sasValueSplit[0]) + jsDate.setHours(parseInt(sasValueSplit[1])) + jsDate.setMinutes(parseInt(sasValueSplit[2])) + jsDate.setSeconds(parseInt(sasValueSplit[3])) + } else if (isNaN(Number(sasValue))) { + // If it's date value (formatted) we parse it, conversion is overridden + jsDate = new Date(sasValue) + } + + let jsDateTime = `${this.helperService.addLeadingZero( + jsDate.getHours().toString() + )}:${this.helperService.addLeadingZero( + jsDate.getMinutes().toString() + )}:${this.helperService.addLeadingZero(jsDate.getSeconds().toString())}` + + return returnOnlyTime ? jsDateTime : jsDate + } +} diff --git a/client/src/app/pipes/pipes.module.ts b/client/src/app/pipes/pipes.module.ts new file mode 100644 index 0000000..7371c48 --- /dev/null +++ b/client/src/app/pipes/pipes.module.ts @@ -0,0 +1,38 @@ +import { CommonModule } from '@angular/common' +import { NgModule } from '@angular/core' +import { DateTimeFormatterPipe } from './date-time-formatter.pipe' +import { sasToJsDatePipe } from './ms-to-date.pipe' +import { PkSpaceSeparatePipe } from './pk-space-separate.pipe' +import { SecondsParserPipe } from './seconds-parser.pipe' +import { ThousandSeparatorPipe } from './thousand-separator.pipe' +import { ToNumberPipe } from './to-number.pipe' +import { ConvertSizePipe } from './convert-size.pipe' +import { LinkinzePipe } from './linkinze.pipe' +import { PrettyjsonPipe } from './prettyjson.pipe' + +@NgModule({ + declarations: [ + PkSpaceSeparatePipe, + sasToJsDatePipe, + ThousandSeparatorPipe, + SecondsParserPipe, + DateTimeFormatterPipe, + ToNumberPipe, + ConvertSizePipe, + LinkinzePipe, + PrettyjsonPipe + ], + imports: [CommonModule], + exports: [ + PkSpaceSeparatePipe, + sasToJsDatePipe, + ThousandSeparatorPipe, + SecondsParserPipe, + DateTimeFormatterPipe, + ToNumberPipe, + ConvertSizePipe, + LinkinzePipe, + PrettyjsonPipe + ] +}) +export class PipesModule {} diff --git a/client/src/app/pipes/pk-space-separate.pipe.ts b/client/src/app/pipes/pk-space-separate.pipe.ts new file mode 100644 index 0000000..e84f585 --- /dev/null +++ b/client/src/app/pipes/pk-space-separate.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'pkSpaceSeparate' +}) +export class PkSpaceSeparatePipe implements PipeTransform { + transform(value: string): string { + return value.replace(/\|/g, ' | ') + } +} diff --git a/client/src/app/pipes/prettyjson.pipe.ts b/client/src/app/pipes/prettyjson.pipe.ts new file mode 100644 index 0000000..76f3c3e --- /dev/null +++ b/client/src/app/pipes/prettyjson.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'prettyjson' +}) +export class PrettyjsonPipe implements PipeTransform { + transform(rawJson: any): string { + return JSON.stringify(rawJson, null, 2) + } +} diff --git a/client/src/app/pipes/seconds-parser.pipe.ts b/client/src/app/pipes/seconds-parser.pipe.ts new file mode 100644 index 0000000..9fdfbb6 --- /dev/null +++ b/client/src/app/pipes/seconds-parser.pipe.ts @@ -0,0 +1,38 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { HelperService } from '../services/helper.service' + +@Pipe({ + name: 'secondsParser' +}) +export class SecondsParserPipe implements PipeTransform { + constructor(private helperService: HelperService) {} + + transform(value: number | string): string { + if (value === undefined || value === null || value === '') return '' + + let hours + let minutes + let seconds + + // If it's datetime value (formatted) we parse it, othervise we calculate it + if (typeof value === 'string' && value.split(':').length === 3) { + const valueSplit = value.split(':') + + hours = valueSplit[0] + minutes = valueSplit[1] + seconds = valueSplit[2] + } else { + if (typeof value !== 'number') value = parseInt(value) + + hours = Math.floor(value / 3600) + minutes = Math.floor((value % 3600) / 60) + seconds = Math.floor((value % 3600) % 60) + } + + return `${this.helperService.addLeadingZero( + hours + )}:${this.helperService.addLeadingZero( + minutes + )}:${this.helperService.addLeadingZero(seconds)}` + } +} diff --git a/client/src/app/pipes/thousand-separator.pipe.ts b/client/src/app/pipes/thousand-separator.pipe.ts new file mode 100644 index 0000000..e41029a --- /dev/null +++ b/client/src/app/pipes/thousand-separator.pipe.ts @@ -0,0 +1,22 @@ +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'thousandSeparator' +}) +export class ThousandSeparatorPipe implements PipeTransform { + transform(value: string | number, separator?: string): string { + return this.addSeparators(value.toString(), separator) + } + + private addSeparators(value: string, separator: string = ' ') { + value += '' + const decimalSplit = value.split('.') + let whole = decimalSplit[0] + const fractional = decimalSplit.length > 1 ? '.' + decimalSplit[1] : '' + const regex = /(\d+)(\d{3})/ + while (regex.test(whole)) { + whole = whole.replace(regex, '$1' + separator + '$2') + } + return whole + fractional + } +} diff --git a/client/src/app/pipes/to-number.pipe.ts b/client/src/app/pipes/to-number.pipe.ts new file mode 100644 index 0000000..b08611c --- /dev/null +++ b/client/src/app/pipes/to-number.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'toNumber' +}) +export class ToNumberPipe implements PipeTransform { + transform(value: string | number): number { + return Number(value) + } +} diff --git a/client/src/app/query/models/QueryDateTime.model.ts b/client/src/app/query/models/QueryDateTime.model.ts new file mode 100644 index 0000000..ff3e079 --- /dev/null +++ b/client/src/app/query/models/QueryDateTime.model.ts @@ -0,0 +1,6 @@ +export interface QueryDateTime { + clauseIndex: number + queryIndex: number + date: string + time: string +} diff --git a/client/src/app/query/query.component.html b/client/src/app/query/query.component.html new file mode 100644 index 0000000..8902bf3 --- /dev/null +++ b/client/src/app/query/query.component.html @@ -0,0 +1,512 @@ +
+
+ + + + +
+ +
+ + + + +
+
+ +
+
+ + + + +
+
+
+      
+ +
+ + {{whereClause}} +
+
+
+ +
+
+
+ +
+
+
+
+ + + + + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + + +
+
+ + +
+ + + + +
+ + +
+
+ + + +
+ +
+ + + +
+ +
+
+ + + +
+ +
+ + + +
+
+ +
+ + + +
+
+ +
+ + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/app/query/query.component.scss b/client/src/app/query/query.component.scss new file mode 100644 index 0000000..24dc5dd --- /dev/null +++ b/client/src/app/query/query.component.scss @@ -0,0 +1,283 @@ +.content { + display: flex; + + .clauses-container { + display: flex; + flex-direction: column; + + .clause-logic { + display: flex; + justify-content: center; + flex-direction: column; + background: #e9e9e9; + padding: 15px; + } + + .clause-query { + padding: 30px 0px 20px 20px; + background: #fbf8f8; + display: flex; + justify-content: center; + flex-direction: column; + position: relative; + + & > .clr-row { + justify-content: space-between; + + &:not(:last-child) { + padding-bottom: 15px; + margin-bottom: 15px; + border-bottom: 1px solid rgba(0, 0, 0, 0.16) + } + } + + .remove-group-clause-button { + position: absolute; + top: 0px; + right: 10px; + color: gray; + } + + .variable-col { + display: flex; + align-items: flex-start; + padding-bottom: 1px; + + .datalist-wrapper { + width: 100%; + + input { + width: 100%; + } + } + } + + .operator-col { + display: flex; + align-items: flex-start; + + clr-select-container { + height: 45px; + margin-top: 0; + width: 100%; + } + } + + .value-col { + display: flex; + align-items: flex-start; + padding-bottom: 1px; + + .checkbox-vals { + width: 100%; + padding: 0px 5px; + border-bottom: 1px solid rgba(0, 0, 0, 0.3); + + clr-checkbox-container { + margin-top: 0; + } + + section { + max-height: 120px; + overflow-y: scroll; + } + } + + .single-field-vals { + width: 100%; + + ::ng-deep { + .clr-control-container { + width: 100%; + + .clr-input-wrapper { + max-width: none; + + .clr-input-group { + width: 100%; + } + } + } + } + + & > input { + width: 100%; + } + + input[type=time] { + width: 100%; + padding-right: 17px; + } + } + + .range-vals { + width: 100%; + + ::ng-deep { + .clr-control-container { + width: 100%; + + .clr-input-wrapper { + max-width: none; + + .clr-input-group { + width: 100%; + } + } + } + } + + .from { + margin-bottom: 10px; + + & > input { + width: 100%; + } + + input[type=time] { + width: 100%; + padding-right: 17px; + } + } + + .from, .to { + min-width: 100px; + + & > input { + width: 100%; + } + + input[type=time] { + width: 100%; + padding-right: 17px; + } + } + } + + .contains-vals { + width: 100%; + + ::ng-deep { + .clr-control-container { + width: 100%; + + .clr-input-wrapper { + max-width: none; + + .clr-input-group { + width: 100%; + } + } + } + } + + & > input { + width: 100%; + } + + input[type=time] { + width: 100%; + padding-right: 17px; + } + } + } + + .clause-buttons { + display: flex; + justify-content: space-around; + align-items: center; + flex-direction: row; + align-items: center; + + button { + min-width: auto; + } + } + } + } +} + +.invalid-clause { + border-left: 2px solid #d94b31; +} + +.clause-row { + clr-icon { + margin: 0; + } +} + +.clause-row:after { + position: relative; + content: ""; + height: .41667rem; + width: .41667rem; + top: .29167rem; + right: .25rem; + background-image: url(data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org…%2C9.84%2C3.24a0.68%2C0.68%2C0%2C1%2C1%2C1%2C1Z%22%2F%3E%0A%3C%2Fsvg%3E%0A); + background-repeat: no-repeat; + background-size: contain; + vertical-align: middle; + margin: 0; +} +:not(pre) > code[class*="language-"], pre[class*="language-"] { + background-color: #fbf8f8; +} + +pre[class*="language-"] { + padding: 8px; + margin: 0; + border-radius: 1px; + + display: flex; + justify-content: center; + align-items: center; + min-height: 66px; + + position: relative; + + span.spinner { + position: absolute; + left: 10px; + top: 10px; + } + + code { + white-space: pre-wrap; + word-break: break-word; + } +} + +.input-val { + border: 0px; + background: #fbf8f8; + border-bottom: 1px solid #999999; +} + +clr-date-container { + margin-top: 2px !important; +} + +input[type="time"] { + border: 0; + background: transparent; + border-bottom: 1px solid #b3b3b3; + + &:focus { + outline: none; + } +} + +.in-values-modal { + .modal-footer { + border-top: 1px solid #d8d8d8; + margin-top: 10px; + } +} + +.progress, .progress-static { + background-color: transparent; + width: 100%; + height: 4px; + top: 3px; +} \ No newline at end of file diff --git a/client/src/app/query/query.component.ts b/client/src/app/query/query.component.ts new file mode 100644 index 0000000..4594be0 --- /dev/null +++ b/client/src/app/query/query.component.ts @@ -0,0 +1,1068 @@ +import { Subscription } from 'rxjs' +import { + Component, + AfterViewInit, + AfterContentInit, + OnDestroy, + ChangeDetectorRef, + LOCALE_ID, + Input +} from '@angular/core' +import { SasStoreService } from '../services/sas-store.service' +import { globals } from '../_globals' +import { EventService } from '../services/event.service' + +import { registerLocaleData } from '@angular/common' +import localeEnGB from '@angular/common/locales/en-GB' +import { HelperService } from '../services/helper.service' +import { QueryClause } from '../models/TableData' +import { PublicGetcolvalsSASResponse } from '../models/sas/public-getcolvals.model' +import { QueryDateTime } from './models/QueryDateTime.model' +import { isSpecialMissing } from '@sasjs/utils/input/validators' +import { get } from 'lodash-es' +import { OnLoadingMoreEvent } from '../shared/autocomplete/autocomplete.component' + +registerLocaleData(localeEnGB) +@Component({ + selector: 'app-query', + templateUrl: './query.component.html', + styleUrls: ['./query.component.scss'], + providers: [{ provide: LOCALE_ID, useValue: 'en-GB' }] +}) +export class QueryComponent + implements AfterViewInit, AfterContentInit, OnDestroy +{ + @Input() caching: boolean = true + @Input() viewboxId: number | undefined + + private rows_increment: number = 100 + private initial_rows: number = 1000 + + private columnsSub: Subscription | undefined + private valuesSub: Subscription | undefined + private _removeQry: Subscription | undefined + public cols: Array | undefined + public libds: string | undefined + public variable: string | undefined + public value: string | undefined + public operator: string | undefined + public vals: Array | undefined + public innerWidth: any + public noBorder: any + public clauseAmt: Array = [''] + public numOperators: Array = [ + '=', + '<', + '>', + '<=', + '>=', + 'BETWEEN', + 'IN', + 'NOT IN', + 'NE' + ] + public charOperators: Array = [ + '=', + '<', + '>', + '<=', + '>=', + 'CONTAINS', + 'IN', + 'NOT IN', + 'NE' + // "LIKE", + // "BEGINS_WITH", + ] + public logic: string | undefined + public notIn: boolean = false + public notArr: boolean = true + public wasBetween: boolean = false + public whereClauseLoading: boolean = false + public dynamicWhereClause: boolean = true + public usePickers: boolean = false + + private queryObj: { + elements: any[] + clauseLogic?: string + invalidClause?: boolean + } = { + elements: [ + { + logic: null, + type: null, + ddtype: null, + variable: null, + operator: null, + value: null, + startrow: 0, + rows: 0, + nobs: 0, + values: < + { + formatted: any + unformatted: any + }[] + >[], + operators: [] + } + ], + clauseLogic: '', + invalidClause: false + } + + public selVar: any = { + index: null, + format: null, + type: null + } + + public inObj: Array = [ + { + checked: false, + value: null + } + ] + + public groupLogic: string = 'AND' + + public clauses: any = { + queryObj: [this.queryObj], + clauseLogic: [], + groupLogic: this.groupLogic + } + + public whereString: string | undefined + public val: any + public whereClause: string | undefined + public logicOperators: Array = ['AND', 'OR'] + + public queryDateTime: QueryDateTime[] = [] + + public currentClauseIndex: number = -1 + public currentQueryIndex: number = -1 + public pendingINValuesSet: { + clauseIndex: number + queryIndex: number + } | null = null + + constructor( + private sasStoreService: SasStoreService, + private eventService: EventService, + private helperService: HelperService, + private cdf: ChangeDetectorRef + ) { + this.innerWidth = window.screen.width + if (this.innerWidth > 768) { + this.noBorder = 'border-left: 2px solid gray;' + } + } + + getQueryDateTime(clauseIndex: number, queryIndex: number): QueryDateTime { + let existingQueryDateTime = this.queryDateTime.find( + (x) => x.clauseIndex === clauseIndex && x.queryIndex === queryIndex + ) + + if (!existingQueryDateTime) { + const lastIndex = + this.queryDateTime.push({ + clauseIndex, + queryIndex, + date: '', + time: '' + }) - 1 + + existingQueryDateTime = this.queryDateTime[lastIndex] + } + + return existingQueryDateTime + } + + usePickersChange() { + this.queryDateTime = [] + } + + public resetFilter() { + this.whereString = undefined + this.whereClause = undefined + + this.queryObj = { + elements: [ + { + logic: null, + type: null, + ddtype: null, + variable: null, + operator: null, + value: null, + values: [], + operators: [] + } + ] + } + + this.clauses = { + queryObj: [this.queryObj], + clauseLogic: [], + groupLogic: this.groupLogic + } + + this.whereClauseFn(true) + } + + public setToGlobals() { + if (!this.caching) return + + let objPath = '' + + if (globals.rootParam === 'home' || globals.rootParam === 'editor') { + if (this.viewboxId) { + objPath = `viewboxes.${this.viewboxId}` + } else { + objPath = 'editor' + } + } else if (globals.rootParam === 'view') { + objPath = 'viewer' + } + + get(globals, objPath).filter.groupLogic = this.groupLogic + if (typeof this.whereClause === 'string') { + get(globals, objPath).filter.whereClause = this.whereClause + } + if (typeof this.libds === 'string') { + get(globals, objPath).filter.libds = this.libds + } + get(globals, objPath).filter.clauses = this.clauses + + console.log('globals', globals) + } + + public getFromGlobals() { + if (!this.caching) return + + let objPath = '' + + if (globals.rootParam === 'home' || globals.rootParam === 'editor') { + if (this.viewboxId) { + objPath = `viewboxes.${this.viewboxId}` + } else { + objPath = 'editor' + } + } else if (globals.rootParam === 'view') { + objPath = 'viewer' + } + + if (get(globals, objPath).filter.cols.length > 0) { + this.cols = JSON.parse(JSON.stringify(get(globals, objPath).filter.cols)) + } + + if (get(globals, objPath).filter.vals.length > 0) { + this.vals = JSON.parse(JSON.stringify(get(globals, objPath).filter.vals)) + } + + if (get(globals, objPath).filter.groupLogic !== '') { + this.groupLogic = get(globals, objPath).filter.groupLogic + this.whereClause = get(globals, objPath).filter.whereClause + this.libds = get(globals, objPath).filter.libds + this.clauses = get(globals, objPath).filter.clauses + this.whereClauseFn() + } + } + + public setGroupLogic(groupLogic: any) { + this.groupLogic = groupLogic + this.clauses.groupLogic = groupLogic + this.whereClauseFn() + + this.setToGlobals() + } + + public dateChange( + pickerValue: any, + query: any, + queryIndex: number, + clauseIndex: number, + queryValueIndex?: number + ) { + let valueInDays = this.helperService.convertJsDateToSasDate(pickerValue) + + if (query.operator === 'BETWEEN' && queryValueIndex !== undefined) { + this.clauses.queryObj[clauseIndex].elements[queryIndex].value[ + queryValueIndex + ] = valueInDays + } + + this.setVariableValues(valueInDays, queryIndex, clauseIndex) + } + + public dateTimeChange( + query: any, + queryIndex: number, + clauseIndex: number, + queryValueIndex?: number + ) { + const queryDateTime = this.getQueryDateTime(clauseIndex, queryIndex) + + if (queryDateTime.date === '') { + if (query.value === '') return + + queryDateTime.date = query.value.split(':')[0] + } + + const dateHours = parseInt(queryDateTime.time.split(':')[0]) + const dateMinutes = parseInt(queryDateTime.time.split(':')[1]) + const dateSeconds = parseInt(queryDateTime.time.split(':')[2]) || 0 + + let dateObject = new Date(queryDateTime.date) + let dateTimeObject = new Date( + dateObject.getFullYear(), + dateObject.getMonth(), + dateObject.getDate(), + dateHours, + dateMinutes, + dateSeconds + ) + + let valueInSeconds = this.helperService.convertJsDateToSasDate( + dateTimeObject, + 'seconds' + ) + + if (query.operator === 'BETWEEN' && queryValueIndex !== undefined) { + this.clauses.queryObj[clauseIndex].elements[queryIndex].value[ + queryValueIndex + ] = valueInSeconds + } + + this.setVariableValues(valueInSeconds, queryIndex, clauseIndex) + } + + public timeChange( + time: any, + query: any, + ind: number, + clauseIndex: number, + queryValueIndex?: number + ) { + time = time.target.value + + let hours = parseInt(time.split(':')[0]) + let minutes = parseInt(time.split(':')[1]) + let seconds = parseInt(time.split(':')[2]) || 0 + + let hourSeconds = hours * 60 * 60 + let minuteSeconds = minutes * 60 + + let inputValue = hourSeconds + minuteSeconds + seconds + + if (query.operator === 'BETWEEN' && queryValueIndex !== undefined) { + this.clauses.queryObj[clauseIndex].elements[ind].value[queryValueIndex] = + inputValue + } + + this.setVariableValues(inputValue, ind, clauseIndex) + } + + /** + * Takes the clause object, removes current clause and makes new array (table) + * ready to be sent to SAS + */ + public dynamicWhereClauseCreator(groupIndex: number, clauseIndex: number) { + let dynamicWhereClauseTable: QueryClause[] = [] + + if ( + this.clauses.queryObj.length > 1 || + this.clauses.queryObj[groupIndex].elements.length > 1 + ) { + for ( + let groupInd = 0; + groupInd < this.clauses.queryObj.length; + groupInd++ + ) { + for ( + let clauseInd = 0; + clauseInd < this.clauses.queryObj[groupInd].elements.length; + clauseInd++ + ) { + if (groupInd === groupIndex && clauseInd === clauseIndex) continue + if ( + [null, undefined].includes( + this.clauses.queryObj[groupInd].elements[clauseInd].variable + ) || + [null, undefined].includes( + this.clauses.queryObj[groupInd].elements[clauseInd].operator + ) || + [null, undefined].includes( + this.clauses.queryObj[groupInd].elements[clauseInd].value + ) + ) + continue + + let rawValue = '' + const operator = + this.clauses.queryObj[groupInd].elements[clauseInd].operator + const variable = + this.clauses.queryObj[groupInd].elements[clauseInd].variable + + if (operator === 'BETWEEN') { + rawValue = `${this.clauses.queryObj[groupInd].elements[clauseInd].value[0]} AND ${this.clauses.queryObj[groupInd][clauseInd].value[1]}` + } else if (operator === 'IN' || operator === 'NOT IN') { + this.clauses.queryObj[groupInd][clauseInd].value.forEach( + (element: any) => { + if (element.checked) { + let value = element.val + + if (typeof value === 'string' && !isSpecialMissing(value)) { + if (rawValue.length > 0) { + rawValue += `,'${value}'` + } else { + rawValue = `('${value}'` + } + } else { + if (rawValue.length > 0) { + rawValue += `,${value}` + } else { + rawValue = `(${value}` + } + } + } + } + ) + + if (rawValue.length > 0) { + rawValue += ')' + } + } else if ( + this.clauses.queryObj[groupInd].elements[clauseInd].value === '' + ) { + if ( + this.clauses.queryObj[groupInd].elements[clauseInd].type === + 'char' + ) { + rawValue = `' '` + } else { + rawValue = '.' + } + } else { + if ( + this.clauses.queryObj[groupInd].elements[clauseInd].type === + 'char' + ) { + rawValue = `'${this.clauses.queryObj[groupInd].elements[clauseInd].value}'` + } + } + + dynamicWhereClauseTable.push({ + GROUP_LOGIC: this.clauses.groupLogic, + SUBGROUP_LOGIC: + this.clauses.queryObj[groupInd].clauseLogic || 'AND', + SUBGROUP_ID: groupInd, + VARIABLE_NM: variable, + OPERATOR_NM: operator, + RAW_VALUE: + rawValue || + this.clauses.queryObj[groupInd].elements[clauseInd].value + }) + } + } + } + + return dynamicWhereClauseTable + } + + public async getValuesLoadMore( + event: OnLoadingMoreEvent, + variable: any, + ind: any, + clauseIndex: any + ) { + const libds = this.libds || '' + + try { + if (this.cols !== undefined) { + for (let index = 0; index < this.cols.length; index++) { + let element = this.cols[index] + if (element.NAME === variable) { + this.selVar.index = index + } + } + + const DDTYPE = this.cols[this.selVar.index].DDTYPE + + const { startrow: currentStartrow, rows: currentRows } = + this.clauses.queryObj[clauseIndex].elements[ind] + + const ROWS_INCREMENT: number = this.rows_increment + const STARTROW = currentStartrow + currentRows + + let dynamicWhereClauseTable: any[] = [] + + if (this.dynamicWhereClause) { + dynamicWhereClauseTable = this.dynamicWhereClauseCreator( + clauseIndex, + ind + ) + } + + const isDateOrTime = ['DATETIME', 'TIME', 'DATE'].includes(DDTYPE) + + this.sasStoreService + .getQueryValues( + variable, + libds, + dynamicWhereClauseTable, + STARTROW, + ROWS_INCREMENT + ) + .then((res: PublicGetcolvalsSASResponse) => { + const values = res.vals + const { STARTROW, ROWS, NOBS } = res.meta[0] + + this.clauses.queryObj[clauseIndex].elements[ind].startrow = STARTROW + this.clauses.queryObj[clauseIndex].elements[ind].rows = ROWS + this.clauses.queryObj[clauseIndex].elements[ind].nobs = NOBS + + if ( + !( + values.length === 1 && + values[0].FORMATTED === '' && + values[0].UNFORMATTED === '' + ) + ) { + this.clauses.queryObj[clauseIndex].elements[ind].values.push( + ...values.map((item: any) => { + const numeric = res.$vals.vars.UNFORMATTED.type === 'num' + const specialMissing = + numeric && isSpecialMissing(item.UNFORMATTED) + + let unformatted = specialMissing + ? '.' + item.UNFORMATTED + : item.UNFORMATTED + + // If it's not special missing and is numeric and null then it is normal missing `.` + if (numeric && unformatted === null) unformatted = '.' + + return { + formatted: isDateOrTime + ? item.FORMATTED.split('.')[0] + : item.FORMATTED, //WORKAROUND SHOULD BE FIXED PROPERLY (#413): We will remove the milliseconds inside the formatted value, if decimal exists and it is date, time or datetime ddtype + unformatted: unformatted + } + }) + ) + + const currentValues = + this.clauses.queryObj[clauseIndex].elements[ind].values.length + const moreExists = NOBS - currentValues > 0 + + event.loadMoreFinished(moreExists) + } else { + event.loadMoreFinished(false) + } + + this.whereClauseFn() + this.setToGlobals() + this.whereClauseLoading = false + + /** + * If getValues request did not finish when operator was changed to IN, we need to set values after the request is finished. + * Othervise values are not beign populated + */ + if (this.pendingINValuesSet !== null) { + const { clauseIndex, queryIndex } = this.pendingINValuesSet + + this.setINValues(clauseIndex, queryIndex) + + this.pendingINValuesSet = null + } + + this.cdf.detectChanges() + }) + .catch((err: any) => { + this.whereClauseLoading = false + }) + } + } catch (error) { + this.eventService.catchResponseError('public/getcolvals', error) + } + } + + public async getValues(variable: any, ind: any, clauseIndex: any) { + this.whereClauseLoading = true + + let libds: string = '' + + if (this.libds !== undefined) { + libds = this.libds + } + + this.clearValues(ind, clauseIndex) + this.clauses.queryObj[clauseIndex].elements[ind].values = [] + + this.clauses.queryObj[clauseIndex].elements[ind].value = '' + this.clauses.queryObj[clauseIndex].elements[ind].operator = '=' + this.clauses.queryObj[clauseIndex].elements[ind].variable = variable + + try { + if (this.cols !== undefined) { + for (let index = 0; index < this.cols.length; index++) { + let element = this.cols[index] + if (element.NAME === variable) { + this.selVar.index = index + } + } + + const DDTYPE = this.cols[this.selVar.index].DDTYPE + + this.clauses.queryObj[clauseIndex].elements[ind].ddtype = DDTYPE + + this.clauses.queryObj[clauseIndex].elements[ind].type = + this.cols[this.selVar.index].TYPE + + if (this.clauses.queryObj[clauseIndex].elements[ind].type === 'num') { + this.clauses.queryObj[clauseIndex].elements[ind].operators = + this.numOperators + } else { + this.clauses.queryObj[clauseIndex].elements[ind].operators = + this.charOperators + } + + let dynamicWhereClauseTable: any[] = [] + + if (this.dynamicWhereClause) { + dynamicWhereClauseTable = this.dynamicWhereClauseCreator( + clauseIndex, + ind + ) + } + + const isDateOrTime = ['DATETIME', 'TIME', 'DATE'].includes(DDTYPE) + + this.sasStoreService + .getQueryValues( + variable, + libds, + dynamicWhereClauseTable, + 1, + this.initial_rows + ) + .then((res: PublicGetcolvalsSASResponse) => { + const values = res.vals + const { STARTROW, ROWS, NOBS } = res.meta[0] + + this.clauses.queryObj[clauseIndex].elements[ind].startrow = STARTROW + this.clauses.queryObj[clauseIndex].elements[ind].rows = ROWS + this.clauses.queryObj[clauseIndex].elements[ind].nobs = NOBS + + this.clauses.queryObj[clauseIndex].elements[ind].values = values + .map((item: any) => { + const numeric = res.$vals.vars.UNFORMATTED.type === 'num' + const specialMissing = + numeric && isSpecialMissing(item.UNFORMATTED) + + let unformatted = specialMissing + ? '.' + item.UNFORMATTED + : item.UNFORMATTED + + // If it's not special missing and is numeric and null then it is normal missing `.` + if (numeric && unformatted === null) unformatted = '.' + + return { + formatted: isDateOrTime + ? item.FORMATTED.split('.')[0] + : item.FORMATTED, //WORKAROUND SHOULD BE FIXED PROPERLY (#413): We will remove the milliseconds inside the formatted value, if decimal exists and it is date, time or datetime ddtype + unformatted: unformatted + } + }) + .slice(0, 2000) + + this.whereClauseFn() + this.setToGlobals() + this.whereClauseLoading = false + + /** + * If getValues request did not finish when operator was changed to IN, we need to set values after the request is finished. + * Othervise values are not beign populated + */ + if (this.pendingINValuesSet !== null) { + const { clauseIndex, queryIndex } = this.pendingINValuesSet + + this.setINValues(clauseIndex, queryIndex) + + this.pendingINValuesSet = null + } + + this.cdf.detectChanges() + }) + .catch((err: any) => { + this.whereClauseLoading = false + }) + } + } catch (error) { + this.eventService.catchResponseError('public/getcolvals', error) + } + } + + public getlogic(logic: any) { + this.logic = logic + this.whereClauseFn() + } + + public setLogic() { + this.whereClauseFn() + this.setToGlobals() + } + + public isArr(val: any) { + return ( + val instanceof Array && + val.length > 0 && + typeof val[0].checked !== 'undefined' + ) + } + + public variableInputChange( + queryVariable: any, + index: number, + clauseIndex: number, + event: any + ) { + this.getValues(queryVariable, index, clauseIndex) + } + + public setVariableValues(valueObj: any, ind: any, clauseIndex: any) { + // clauseIndex is current clause in group clauses, ind is current query in clause + let operator = this.clauses.queryObj[clauseIndex].elements[ind].operator + + if (operator !== 'BETWEEN' && operator !== 'IN' && operator !== 'NOT IN') { + this.clauses.queryObj[clauseIndex].elements[ind].value = + valueObj.toString() + } + this.whereClauseFn() + this.setToGlobals() + } + + public setVariableOperator(ind: any, operator: any, clauseIndex: any) { + let currentValue = this.clauses.queryObj[clauseIndex].elements[ind].value + if ( + currentValue instanceof Array && + operator !== 'IN' && + operator !== 'NOT IN' + ) { + if ( + currentValue instanceof Array && + currentValue.length === 2 && + typeof currentValue[0] === 'string' + ) { + currentValue = currentValue[0] + } else { + currentValue = '' + } + } + + this.clearValuesOperator(ind, clauseIndex) + this.clauses.queryObj[clauseIndex].elements[ind].operator = operator + // tslint:disable-next-line:max-line-length + if ( + operator === '=' || + operator === '>' || + operator === '<' || + operator === '<=' || + operator === '>=' || + operator === 'NE' + ) { + this.clauses.queryObj[clauseIndex].elements[ind].value = currentValue + } + + if (operator === 'BETWEEN') { + this.clauses.queryObj[clauseIndex].elements[ind].value = [] + this.clauses.queryObj[clauseIndex].elements[ind].value.push(currentValue) + this.clauses.queryObj[clauseIndex].elements[ind].value.push('') + } + + if (operator === 'IN' || operator === 'NOT IN') { + this.setINValues(clauseIndex, ind) + } + + this.whereClauseFn() + this.setToGlobals() + } + + public setINValues(clauseIndex: number, queryIndex: number) { + const vals = [] + + const inValues = + this.clauses.queryObj[clauseIndex].elements[queryIndex].values + + if (inValues.length < 1) { + this.pendingINValuesSet = { + clauseIndex, + queryIndex + } + } + + for (let index = 0; index < inValues.length; index++) { + vals.push({ checked: false, val: inValues[index].formatted }) + } + + this.clauses.queryObj[clauseIndex].elements[queryIndex].value = vals + } + + public clearValues(ind: any, clauseIndex: any) { + this.clauses.queryObj[clauseIndex].elements[ind].value = '' + } + + public clearValuesOperator(ind: any, clauseIndex: any) { + let operator = this.clauses.queryObj[clauseIndex].elements[ind].operator + if ( + operator === 'BETWEEN' || + operator === 'IN' || + operator === 'NOT IN' || + operator === 'CONTAINS' + ) { + this.clearValues(ind, clauseIndex) + } + } + + /** + * Checks if clause is invalid and sets bool property accordingly + * It is being used in html to mark invalid clauses red + */ + public hasInvalidCluase(clauses: any): boolean { + for (let clause of clauses) { + if ( + clause.variable === null || + clause.operator === null || + clause.value === null || + clause.value === '' + ) { + clause['invalidClause'] = true + + return true + } else { + clause['invalidClause'] = false + } + } + + clauses.invalidClause = false + + return false + } + + /** + * Checks if group clause is invalid and sets bool property accordingly + * It is being used in html to mark invalid group clauses red + */ + public hasInvalidGroupCluase(): boolean { + for (let i = 0; i < this.clauses.queryObj.length; i++) { + if (this.hasInvalidCluase(this.clauses.queryObj[i].elements)) { + this.clauses.queryObj[i].invalidClause = true + + return true + } else { + this.clauses.queryObj[i].invalidClause = false + } + } + + return false + } + + public addClause(clauseIndex: number) { + if (this.hasInvalidCluase(this.clauses.queryObj[clauseIndex].elements)) { + this.eventService.showInfoModal( + 'Error', + 'Cannot add new clause, when one or more clauses are invalid or empty.' + ) + return + } + + this.clauseAmt.push('') + this.clauses.queryObj[clauseIndex].elements.push({ + logic: null, + type: null, + variable: null, + operator: null, + value: null, + values: [], + operators: [] + }) + + let clauseLogic = this.clauses.queryObj[clauseIndex].clauseLogic + + if (typeof clauseLogic === 'undefined') { + this.clauses.queryObj[clauseIndex].clauseLogic = 'AND' + } else if (clauseLogic === 'OR') { + this.clauses.queryObj[clauseIndex].clauseLogic = 'OR' + } else { + this.clauses.queryObj[clauseIndex].clauseLogic = 'AND' + } + + this.whereClauseFn() + this.setToGlobals() + } + + public addGroupClause() { + if (this.hasInvalidGroupCluase()) { + this.eventService.showInfoModal( + 'Error', + 'Cannot add new clause, when one or more clauses are invalid or empty.' + ) + return + } + + this.clauses.queryObj.push({ + elements: [ + { + logic: null, + type: null, + variable: null, + operator: null, + value: null, + values: [], + operators: [] + } + ] + }) + this.setToGlobals() + } + + public isInHtmlCollection( + value: string, + collection: HTMLCollectionOf + ): boolean { + for (let i = 0; i < collection.length; i++) { + if (collection[i].value === value) return true + } + + return false + } + + public removeGroupClause(clauseIndex: number) { + this.clauses.queryObj.splice(clauseIndex, 1) + this.whereClauseFn() + } + + public removeClause(ind: number, clauseIndex: any) { + this.clauses.queryObj[clauseIndex].elements.splice(ind, 1) + this.whereClauseFn() + this.setToGlobals() + } + + public whereClauseFn(reset: boolean = false) { + const clauses = this.helperService.deepClone(this.clauses) + + if (reset) clauses.queryObj[0].elements = [] + + if (this.libds !== undefined) { + let result = this.sasStoreService.whereClauseCreator( + clauses, + this.groupLogic, + this.libds + ) + + if (!reset) { + this.whereClause = result.whereClause + this.whereString = result.string + } + } + } + + async ngAfterViewInit() { + this._removeQry = this.sasStoreService.removeQuery.subscribe((remove) => { + let res = remove + if (this.clauses.queryObj.length >= 1) { + this.clauses.queryObj.length = 1 + if (this.clauses.queryObj[0].elements.length >= 1) { + this.clauses.queryObj[0].elements.length = 1 + this.clauses.queryObj[0].elements = [] + this.clauses.queryObj[0].elements.push({ + logic: null, + type: null, + variable: null, + operator: null, + value: null, + values: [], + operators: [] + }) + this.whereClauseFn() + } + } + }) + + this.columnsSub = this.sasStoreService.columns.subscribe( + (response: any) => { + let cols = response.data.cols + + if (globals.rootParam === 'home' || globals.rootParam === 'editor') { + this.cols = cols + let some = cols[0].NAME + this.libds = response.libds + + globals.editor.filter.cols = JSON.parse(JSON.stringify(cols)) + } + + if (globals.rootParam === 'view') { + if (globals.viewer.filter.cols.length < 1) { + this.cols = cols + let some = cols[0].NAME + this.libds = response.libds + + globals.viewer.filter.cols = JSON.parse(JSON.stringify(cols)) + } + } + + if (!this.libds) { + this.libds = response.libds + } + } + ) + + this.valuesSub = this.sasStoreService.values.subscribe((res: any) => { + if (globals.rootParam === 'home' || globals.rootParam === 'editor') { + if (globals.editor.filter.vals.length < 1) { + this.vals = res.vals + + globals.editor.filter.vals = JSON.parse(JSON.stringify(res.vals)) + } + } + + if (globals.rootParam === 'view') { + if (globals.viewer.filter.vals.length < 1) { + this.vals = res.vals + + globals.viewer.filter.vals = JSON.parse(JSON.stringify(res.vals)) + } + } + }) + } + + onAutocompleteLoadingMore( + event: OnLoadingMoreEvent, + variable: any, + ind: any, + clauseIndex: any + ) { + this.getValuesLoadMore(event, variable, ind, clauseIndex) + } + + ngAfterContentInit(): void { + this.getFromGlobals() + + setTimeout(() => { + let varInput: HTMLElement | null = + document.querySelector('#vals_var_id0_0') + + if (varInput) varInput.focus() + }, 500) + } + + ngOnDestroy(): void { + if (this.columnsSub) { + this.columnsSub.unsubscribe() + } + + if (this.valuesSub) { + this.valuesSub.unsubscribe() + } + } +} diff --git a/client/src/app/query/query.module.ts b/client/src/app/query/query.module.ts new file mode 100644 index 0000000..e0f80cd --- /dev/null +++ b/client/src/app/query/query.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { QueryComponent } from './query.component' +import { AppSharedModule } from '../app-shared.module' +import { PipesModule } from '../pipes/pipes.module' +import { DirectivesModule } from '../directives/directives.module' + +@NgModule({ + declarations: [QueryComponent], + imports: [ + CommonModule, + ClarityModule, + CommonModule, + FormsModule, + AppSharedModule, + PipesModule, + DirectivesModule + ], + exports: [QueryComponent] +}) +export class QueryModule {} diff --git a/client/src/app/role/role.component.html b/client/src/app/role/role.component.html new file mode 100644 index 0000000..6215853 --- /dev/null +++ b/client/src/app/role/role.component.html @@ -0,0 +1,129 @@ + + + +
+ + + +
+
+ + +

+ + {{ role.ROLENAME }} +

+
+
+
+
+ +
+
+ Loading... +
+
+
+
+ + + + + + + + + +
+

+ {{ roleName }} +

+
+ {{ roleDesc }} +
+
+
+ +
+
+
+
+

MEMBERS ({{ roleMembersCount }})

+
No Members Present
+
+ + + + + + + + + + + + + + + + + +
NAMEEMAILCREATEDUPDATED
{{ member.MEMBERNAME }}{{ member.EMAIL }}{{ member.MEMBERCREATED }}{{ member.MEMBERUPDATED }}
+
+
+
+
+

Groups ({{ roleGroupsCount }})

+
No Groups Present !
+
+ + + + + + + + + + + + + + + + + +
NAMEEMAILCREATEDUPDATED
{{ group.MEMBERNAME }}{{ group.EMAIL }}{{ group.MEMBERCREATED }}{{ group.MEMBERUPDATED }}
+
+
+
+
+
+
+
+
diff --git a/client/src/app/role/role.component.scss b/client/src/app/role/role.component.scss new file mode 100644 index 0000000..f27c478 --- /dev/null +++ b/client/src/app/role/role.component.scss @@ -0,0 +1,51 @@ +.sidebar-height{ + height: 100%; +} +.role-info-text{ + display: inline; + font-size: 20px; +} +.role-info{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.role-info td{ + text-align: center; +} + +.role-data{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.role-data{ + min-height: unset; + h3, h5{ + text-align: center; + } +} +.member-table{ + background-color: #f9f9f9; + width: 100%; +} +.member-table thead{ + background-color: #dadada; +} +.member-table tbody{ + tr:hover{ + background-color: #e6e6e6; + cursor: pointer; + } +} +.table-container{ + overflow-y: scroll; + max-height: 700px; +} +@media screen and (max-width: 768px){ + .role-data{ + min-height: unset !important; + } +} \ No newline at end of file diff --git a/client/src/app/role/role.component.ts b/client/src/app/role/role.component.ts new file mode 100644 index 0000000..cb66d56 --- /dev/null +++ b/client/src/app/role/role.component.ts @@ -0,0 +1,149 @@ +import { Component, OnInit } from '@angular/core' +import { globals } from '../_globals' +import { HelperService } from '../services/helper.service' +import { Location } from '@angular/common' +import { Router, ActivatedRoute } from '@angular/router' +import { SasService } from '../services/sas.service' + +@Component({ + selector: 'app-role', + templateUrl: './role.component.html', + styleUrls: ['./role.component.scss'], + host: { + class: 'content-container' + } +}) +export class RoleComponent implements OnInit { + public roles: Array | undefined + public roleSearch: string = '' + public roleUri: string = '' + public roleName: string = '' + public roleDesc: string = '' + public roleMembers: Array | undefined + public roleMembersCount: number | undefined + public roleGroups: Array | undefined + public roleGroupsCount: number | undefined + public paramPresent: boolean = false + public paramURI: string = '' + public loading: boolean = false + + constructor( + private sasService: SasService, + private helperService: HelperService, + private router: Router, + private location: Location, + private route: ActivatedRoute + ) {} + + ngOnInit() { + globals.viewer.currentSelection = 'view/usernav/roles' + if (this.route.snapshot.params['uri'] !== undefined) { + this.paramPresent = true + this.paramURI = this.route.snapshot.params['uri'] + } + if (globals.usernav.roleList && !this.paramPresent) { + this.roles = globals.usernav.roleList + this.roleSearch = globals.usernav.roleSearch + } else { + if (globals.usernav.roleList === undefined) { + this.loading = true + this.sasService.request('usernav/userroles', null).then((res: any) => { + this.loading = false + this.roles = res.roles + globals.usernav.roleList = res.roles + if (this.paramPresent) { + if (this.roles !== undefined) { + let validRole = this.findRole(this.roles, this.paramURI) + if (validRole !== false) { + this.loading = true + let data = { iwant: [{ roleid: this.paramURI }] } + this.sasService + .request('usernav/usermembersbyrole', data) + .then((res: any) => { + this.loading = false + this.roleMembers = res.sasmembers + this.roleMembersCount = res.sasmembers.length + this.roleGroups = res.sasgroups + this.roleGroupsCount = res.sasgroups.length + this.roleUri = validRole.ROLEURI + this.roleName = validRole.ROLENAME + this.roleDesc = validRole.ROLEDESC + }) + } + } + } + }) + } else { + this.roles = globals.usernav.roleList + this.roleSearch = globals.usernav.roleSearch + this.sasService.request('usernav/userroles', null).then((res: any) => { + this.roles = res.roles + globals.usernav.roleList = res.roles + + if (this.paramPresent) { + if (this.roles !== undefined) { + let validRole = this.findRole(this.roles, this.paramURI) + if (validRole !== false) { + this.loading = true + let data = { iwant: [{ roleid: this.paramURI }] } + this.sasService + .request('usernav/usermembersbyrole', data) + .then((res: any) => { + this.loading = false + this.roleMembers = res.sasmembers + this.roleMembersCount = res.sasmembers.length + this.roleGroups = res.sasgroups + this.roleGroupsCount = res.sasgroups.length + this.roleUri = validRole.ROLEURI + this.roleName = validRole.ROLENAME + this.roleDesc = validRole.ROLEDESC + }) + } + } + } + }) + } + } + } + + public roleListOnFilter() { + this.helperService.libraryOnFilter(this.roles, this.roleSearch, 'ROLENAME') + globals.usernav.roleSearch = this.roleSearch + } + + public roleOnClick(role: any) { + this.loading = true + let url = this.router.url + if (this.paramPresent) { + this.location.replaceState( + url.slice(0, url.lastIndexOf('/')) + '/' + encodeURI(role.ROLEURI) + ) + } else { + this.location.replaceState(url + '/' + encodeURI(role.ROLEURI)) + } + + let data = { iwant: [{ roleid: role.ROLEURI }] } + this.sasService + .request('usernav/usermembersbyrole', data) + .then((res: any) => { + this.loading = false + this.roleMembers = res.sasmembers + this.roleMembersCount = res.sasmembers.length + this.roleGroups = res.sasgroups + this.roleGroupsCount = res.sasgroups.length + this.roleUri = role.ROLEURI + this.roleName = role.ROLENAME + this.roleDesc = role.ROLEDESC + }) + } + + public findRole(list: Array, role: any): any { + let result = false + list.forEach((element) => { + if (element.ROLEURI === role) { + result = element + } + }) + return result + } +} diff --git a/client/src/app/routes/approve-route/approve-route.component.html b/client/src/app/routes/approve-route/approve-route.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/client/src/app/routes/approve-route/approve-route.component.html @@ -0,0 +1 @@ + diff --git a/client/src/app/routes/approve-route/approve-route.component.scss b/client/src/app/routes/approve-route/approve-route.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/routes/approve-route/approve-route.component.ts b/client/src/app/routes/approve-route/approve-route.component.ts new file mode 100644 index 0000000..bd1a2e5 --- /dev/null +++ b/client/src/app/routes/approve-route/approve-route.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-approve-route', + templateUrl: './approve-route.component.html', + styleUrls: ['./approve-route.component.scss'], + host: { + class: 'content-container' + } +}) +export class ApproveRouteComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/client/src/app/routes/edit-route/edit-route.component.html b/client/src/app/routes/edit-route/edit-route.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/client/src/app/routes/edit-route/edit-route.component.html @@ -0,0 +1 @@ + diff --git a/client/src/app/routes/edit-route/edit-route.component.scss b/client/src/app/routes/edit-route/edit-route.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/routes/edit-route/edit-route.component.ts b/client/src/app/routes/edit-route/edit-route.component.ts new file mode 100644 index 0000000..d3e09d0 --- /dev/null +++ b/client/src/app/routes/edit-route/edit-route.component.ts @@ -0,0 +1,12 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-edit-route', + templateUrl: './edit-route.component.html', + styleUrls: ['./edit-route.component.scss'] +}) +export class EditRouteComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/client/src/app/routes/history-route/history-route.component.html b/client/src/app/routes/history-route/history-route.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/client/src/app/routes/history-route/history-route.component.html @@ -0,0 +1 @@ + diff --git a/client/src/app/routes/history-route/history-route.component.scss b/client/src/app/routes/history-route/history-route.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/routes/history-route/history-route.component.ts b/client/src/app/routes/history-route/history-route.component.ts new file mode 100644 index 0000000..d369a3f --- /dev/null +++ b/client/src/app/routes/history-route/history-route.component.ts @@ -0,0 +1,12 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-history-route', + templateUrl: './history-route.component.html', + styleUrls: ['./history-route.component.scss'] +}) +export class HistoryRouteComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/client/src/app/routes/licensing.guard.ts b/client/src/app/routes/licensing.guard.ts new file mode 100644 index 0000000..664c718 --- /dev/null +++ b/client/src/app/routes/licensing.guard.ts @@ -0,0 +1,55 @@ +import { + ActivatedRouteSnapshot, + RouterStateSnapshot, + Router +} from '@angular/router' +import { LicensingComponent } from '../licensing/licensing.component' +import { Injectable } from '@angular/core' +import { LicenceService } from '../services/licence.service' + +@Injectable() +export class LicensingGuard { + constructor( + private licenceService: LicenceService, + private router: Router + ) {} + + canActivate( + currentRoute: ActivatedRouteSnapshot, + currentState: RouterStateSnapshot + ): boolean { + if (currentState?.root.queryParams.force !== undefined) return true + + if (currentState?.url.includes('licensing/update')) { + if (!!this.licenceService.isAppActivated) return true + } + + if ( + this.licenceService.isAppActivated.value !== null && + this.licenceService.isAppActivated.value === false + ) { + return true + } else { + this.router.navigateByUrl('/home') + return false + } + } + + canDeactivate( + component: LicensingComponent, + currentRoute: ActivatedRouteSnapshot, + currentState: RouterStateSnapshot, + nextState?: RouterStateSnapshot + ): boolean { + if (currentState?.url.includes('licensing/register')) { + return false + } + + if (!!this.licenceService.appLocked.value) return false + + return true + if (this.licenceService.isAppActivated.value === null) return true + + return !!this.licenceService.isAppActivated.value + } +} diff --git a/client/src/app/routes/usernav-route/usernav-route.component.html b/client/src/app/routes/usernav-route/usernav-route.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/client/src/app/routes/usernav-route/usernav-route.component.html @@ -0,0 +1 @@ + diff --git a/client/src/app/routes/usernav-route/usernav-route.component.scss b/client/src/app/routes/usernav-route/usernav-route.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/routes/usernav-route/usernav-route.component.ts b/client/src/app/routes/usernav-route/usernav-route.component.ts new file mode 100644 index 0000000..f5d33b3 --- /dev/null +++ b/client/src/app/routes/usernav-route/usernav-route.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-usernav-route', + templateUrl: './usernav-route.component.html', + styleUrls: ['./usernav-route.component.scss'], + host: { + class: 'content-container' + } +}) +export class UsernavRouteComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/client/src/app/routes/view-route/view-route.component.html b/client/src/app/routes/view-route/view-route.component.html new file mode 100644 index 0000000..0680b43 --- /dev/null +++ b/client/src/app/routes/view-route/view-route.component.html @@ -0,0 +1 @@ + diff --git a/client/src/app/routes/view-route/view-route.component.scss b/client/src/app/routes/view-route/view-route.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/routes/view-route/view-route.component.ts b/client/src/app/routes/view-route/view-route.component.ts new file mode 100644 index 0000000..b98d92a --- /dev/null +++ b/client/src/app/routes/view-route/view-route.component.ts @@ -0,0 +1,17 @@ +import { Component, OnInit, OnDestroy } from '@angular/core' + +@Component({ + selector: 'app-view-route', + templateUrl: './view-route.component.html', + styleUrls: ['./view-route.component.scss'], + host: { + class: 'content-container' + } +}) +export class ViewRouteComponent implements OnInit, OnDestroy { + constructor() {} + + ngOnInit() {} + + ngOnDestroy() {} +} diff --git a/client/src/app/services/app-store.service.ts b/client/src/app/services/app-store.service.ts new file mode 100644 index 0000000..87e5bac --- /dev/null +++ b/client/src/app/services/app-store.service.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core' +import { SASjsConfig } from '@sasjs/adapter' +import { DcAdapterSettings } from '../models/DcAdapterSettings' + +@Injectable({ + providedIn: 'root' +}) +export class AppStoreService { + private dcAdapterSettings: DcAdapterSettings | undefined + public sasjsConfig: SASjsConfig | undefined + + constructor() {} + + public setDcAdapterSettings(dcAdapterSettings: DcAdapterSettings) { + this.dcAdapterSettings = dcAdapterSettings + } + + public getDcAdapterSettings(): DcAdapterSettings | undefined { + return this.dcAdapterSettings + } +} diff --git a/client/src/app/services/app.service.ts b/client/src/app/services/app.service.ts new file mode 100644 index 0000000..e705311 --- /dev/null +++ b/client/src/app/services/app.service.ts @@ -0,0 +1,175 @@ +import { Injectable } from '@angular/core' +import { EventService } from './event.service' +import { globals } from '../_globals' +import { SasService } from './sas.service' +import { NavigationEnd, Router } from '@angular/router' +import { BehaviorSubject } from 'rxjs' +import { LoggerService } from './logger.service' +import { EnvironmentInfo } from '../system/models/environment-info.model' +import { LicenceService } from './licence.service' + +@Injectable() +export class AppService { + public syssite = new BehaviorSubject(null) + private environmentInfo: EnvironmentInfo | null = null + + constructor( + private licenceService: LicenceService, + private eventService: EventService, + private sasService: SasService, + private loggerService: LoggerService, + private router: Router + ) { + this.subscribe() + + this.router.events.subscribe((val) => { + if (val instanceof NavigationEnd) { + if (val.url === '/deploy') { + this.eventService.startupDataLoaded() + } + } + }) + } + + sasServiceInit() { + this.sasService.sasServiceInit() //Code from constructor is put in this function inside SasService, because we first want to subscribe to emitters here before executing SasService init function + } + + subscribe() { + this.sasService.loadStartupServiceEmitter.subscribe(() => { + this.startUpData() + }) + + this.sasService.requestSiteIdEmitter.subscribe((sysite: string) => { + this.patchSyssite(sysite) + }) + } + + public getEnvironmentInfo() { + return this.environmentInfo + } + + public patchSyssite(syssite: string) { + let currentSyssite = this.syssite.getValue() + + if (currentSyssite) { + if (!currentSyssite.includes(syssite)) { + currentSyssite.push(syssite) + this.syssite.next(currentSyssite) + } + } + } + + public async startUpData() { + let startupServiceError = false + + await this.sasService + .request('public/startupservice', null) + .then(async (res: any) => { + this.syssite.next([res.SYSSITE]) + + let missingProps: string[] = [] + + if (!res.globvars || (res.globvars && !res.globvars[0])) + missingProps.push('Globvars') + if (!res.sasdatasets) missingProps.push('Sasdatasets') + if (!res.saslibs) missingProps.push('Saslibs') + + if (missingProps.length > 0) { + startupServiceError = true + this.eventService.showInfoModal( + 'Error', + `${missingProps.join(', ')} are not present in the startupservice` + ) + this.licenceService.isAppActivated.next(false) + + return + } + + this.environmentInfo = { + SYSSITE: res.SYSSITE, + SYSSCPL: res.SYSSCPL, + SYSTCPIPHOSTNAME: res.SYSTCPIPHOSTNAME, + SYSVLONG: res.SYSVLONG, + MEMSIZE: res.MEMSIZE, + SYSPROCESSMODE: res.SYSPROCESSMODE, + SYSHOSTNAME: res.SYSHOSTNAME, + SYSHOSTINFOLONG: res.SYSHOSTINFOLONG, + SYSENCODING: res.SYSENCODING, + AUTOEXEC: res.AUTOEXEC, + ISADMIN: res.globvars[0].ISADMIN, + DC_ADMIN_GROUP: res.globvars[0].DC_ADMIN_GROUP + } + + let libs = res.sasdatasets + let libGroup: any = {} + let libsAndTables + let libraries + + for (let lib of libs) { + if (!libGroup[lib.LIBREF]) { + libGroup[lib.LIBREF] = [] + } + + libGroup[lib.LIBREF].push(lib.DSN) + } + + // Sidebar data structure + let treeNodeTemp = JSON.parse(JSON.stringify(libGroup)) + let treeNode = [] + + for (let library of Object.keys(treeNodeTemp)) { + treeNode.push({ + LIBRARYREF: library, + tables: treeNodeTemp[library] + }) + } + + let treeNodeLibraries = treeNode + // Sidebar data structure end + + libsAndTables = libGroup + libraries = Object.keys(libGroup) + + if (libsAndTables !== undefined) { + globals.editor.libsAndTables = libsAndTables + } + + globals.editor.treeNodeLibraries = treeNodeLibraries + globals.editor.libraries = libraries + globals.editor.startupSet = true + + await this.licenceService.activation(res) + }) + .catch((err: any) => { + startupServiceError = true + this.eventService.showInfoModal( + 'Error', + 'There is an issue with startupservice response' + ) + this.licenceService.isAppActivated.next(false) + }) + + this.loggerService.log( + 'Activated:', + this.licenceService.isAppActivated.value + ) + + if (!startupServiceError) { + this.eventService.startupDataLoaded() + + if (!this.licenceService.isAppActivated.value) { + // If route is already on `licensing` page then we won't re route + if ( + !this.router.url.includes('deploy') && + !this.router.url.includes('licensing') + ) { + this.router.navigateByUrl('/licensing/key?error=missing&force=true') + } + } else { + if (this.router.url.includes('licensing')) + this.router.navigateByUrl('/home') + } + } + } +} diff --git a/client/src/app/services/deploy.service.ts b/client/src/app/services/deploy.service.ts new file mode 100644 index 0000000..d302c0b --- /dev/null +++ b/client/src/app/services/deploy.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@angular/core' + +@Injectable({ + providedIn: 'root' +}) +export class DeployService { + constructor() {} + + public downloadFile( + content: any, + filename: string, + extension: string = 'txt' + ) { + let jobBlob = new Blob([content], { + type: 'text/plain' + }) + + if (navigator.appVersion.toString().indexOf('.NET') > 0) { + window.navigator.msSaveBlob(jobBlob, `${filename}.${extension}`) + } else { + let downloadLink = document.createElement('a') + downloadLink.href = 'data:text/plain,' + encodeURIComponent(content) + downloadLink.download = `${filename}.${extension}` + document.body.appendChild(downloadLink) + downloadLink.click() + document.body.removeChild(downloadLink) + } + } + + public readFile(file: File): Promise { + return new Promise((resolve, reject) => { + let JsonFileReader = new FileReader() + + JsonFileReader.onload = () => { + if (JsonFileReader.result) { + resolve(JSON.parse(JsonFileReader.result.toString())) + } + } + + JsonFileReader.readAsText(file) + }) + } + + public clearUploadInput(event: Event) { + ;(event.target).value = '' + } +} diff --git a/client/src/app/services/event.service.ts b/client/src/app/services/event.service.ts new file mode 100644 index 0000000..113bc79 --- /dev/null +++ b/client/src/app/services/event.service.ts @@ -0,0 +1,119 @@ +import { Injectable, Output, EventEmitter } from '@angular/core' +import { InfoModal, AbortDetails } from '../models/InfoModal' +import { AlertsService } from '../shared/alerts/alerts.service' + +@Injectable({ + providedIn: 'root' +}) +export class EventService { + @Output() onSidebarToggle: EventEmitter = new EventEmitter() + @Output() onStartupDataLoaded: EventEmitter = new EventEmitter() + @Output() + onShowAbortModal: EventEmitter = new EventEmitter() + @Output() onRequestsModalOpen: EventEmitter = new EventEmitter() + @Output() onDemoLimitModalShow: EventEmitter = + new EventEmitter() + + public viewLastUrl: string | null = null + public sidebarCloseLimit = 1280 + + constructor(private alertsService: AlertsService) {} + + public showDemoLimitModal(featureName: string) { + this.onDemoLimitModalShow.emit(featureName) + } + + public showInfoModal(modalTitle: string = 'Info', message: string) { + let infoModal: InfoModal = { + modalTitle, + message, + sasService: '', + details: null + } + + this.onShowAbortModal.emit(infoModal) + } + + public showAbortModal( + sasService: string | null, + message: string, + details?: AbortDetails | null, + modalTitle: string | undefined = undefined + ) { + if (!details) details = null + + let infoModalObject: InfoModal = { + sasService, + message, + details + } + + if (modalTitle) { + infoModalObject.modalTitle = modalTitle + } + + this.onShowAbortModal.emit(infoModalObject) + } + + public openRequestsModal() { + this.onRequestsModalOpen.emit(true) + } + + public catchResponseError(sasService: string | null, err: any) { + let errorMessage: string = 'SAS Service error ocurred' + + if (err.error) { + errorMessage = err.error.message + let log: string | undefined + + if (err.error.details && err.error.details.log) { + log = err.error.details.log + } + + // If not a single useful info is returned from adapter + // We display that it's `unknown` SAS service error + if (!errorMessage || errorMessage.trim().length < 1) { + errorMessage = 'SAS Service error ocurred' + } + + // Otherwise we display error message from adapter + this.showAbortModal( + sasService, + errorMessage, + { LOG: log }, + 'Request error' + ) + } else { + this.showAbortModal(sasService, errorMessage) + } + } + + public toggleSidebar() { + this.onSidebarToggle.emit() + } + + public closeSidebar() { + if (window.innerWidth < this.sidebarCloseLimit) { + this.onSidebarToggle.emit({ open: false }) + } + } + + public openSidebar() { + this.onSidebarToggle.emit({ open: true }) + } + + public startupDataLoaded() { + this.onStartupDataLoaded.emit() + } + + public dispatchEvent(eventName: string) { + let event + if (typeof Event === 'function') { + event = new Event(eventName) + } else { + event = document.createEvent('Event') + event.initEvent(eventName, true, true) + } + window.dispatchEvent(event) + } +} diff --git a/client/src/app/services/helper.service.ts b/client/src/app/services/helper.service.ts new file mode 100644 index 0000000..1b59150 --- /dev/null +++ b/client/src/app/services/helper.service.ts @@ -0,0 +1,302 @@ +import { Injectable } from '@angular/core' +import cloneDeep from 'lodash-es/cloneDeep' +import * as CryptoMD5 from 'crypto-js/md5' + +const librariesToShow = 50 + +@Injectable({ + providedIn: 'root' +}) +export class HelperService { + public shownLibraries: number = librariesToShow + public loadMoreCount: number = librariesToShow + public isMicrosoft: boolean = false + + constructor() { + this.isMicrosoft = this.isIEorEDGE() + console.log('Is IE or Edge?', this.isMicrosoft) + } + + public convertJsDateToSasDate( + jsDate: string | Date, + unit: string = 'days' + ): number { + let jsDateObject: Date + let valueInMilliseconds: number = 0 + + if (!(jsDate instanceof Date)) { + jsDateObject = new Date(jsDate) + } else { + jsDateObject = jsDate + } + + valueInMilliseconds = new Date( + Date.UTC( + jsDateObject.getFullYear(), + jsDateObject.getMonth(), + jsDateObject.getDate(), + jsDateObject.getHours(), + jsDateObject.getMinutes(), + jsDateObject.getSeconds() + ) + ).valueOf() + + const msInDay = 24 * 60 * 60 * 1000 + const msInTenYears = 315619200000 //since calculating it is not practical to get correct value, this is parsed with: new Date(Date.UTC(1960, 0, 1)).getTime() + + const sasMilliseconds = valueInMilliseconds + msInTenYears + + switch (unit) { + case 'days': { + let valueInDays = sasMilliseconds / msInDay + + valueInDays = Math.abs(valueInDays) + valueInDays = Math.floor(valueInDays) + + return valueInDays + } + case 'seconds': { + return sasMilliseconds / 1000 + } + } + + return 0 + } + + public convertSasDaysToJsDate( + sasValue: number | string, + unit: string = 'days' + ) { + const msInDay = 24 * 60 * 60 * 1000 + const msNegativeTenYears = -315619200000 //since calculating it is not practical to get correct value, this is parsed with: new Date(Date.UTC(1960, 0, 1)).getTime() + + if (typeof sasValue !== 'number') sasValue = parseFloat(sasValue) + + if (unit === 'seconds') { + let sasMs = sasValue * 1000 + + let jsMs = msNegativeTenYears + sasMs + + let timezoneOffsetMs = new Date(jsMs).getTimezoneOffset() * 60 * 1000 + + jsMs += timezoneOffsetMs + + return new Date(jsMs) + } + + return new Date(msNegativeTenYears + sasValue * msInDay) + } + + public treeOnFilter(array: any, arrToFilter: string) { + let search = array['searchString'] ? array['searchString'] : '' + let arrToFilterArray = arrToFilter.split('.')[0] + let arrToFilterField = arrToFilter.split('.')[1] + + let arrToFilterAll = arrToFilterArray + 'All' + + if (array[arrToFilterArray]) { + if (!array[arrToFilterAll]) { + array[arrToFilterAll] = this.deepClone(array[arrToFilterArray]) + } + + array[arrToFilterArray] = this.deepClone(array[arrToFilterAll]) + + if (search.length > 0) { + if (arrToFilterField) { + array[arrToFilterArray] = array[arrToFilterArray].filter( + (item: any) => { + return item[arrToFilterField] + .toLowerCase() + .includes(search.toLowerCase()) + } + ) + } else { + array[arrToFilterArray] = array[arrToFilterArray].filter( + (item: any) => { + return item.toLowerCase().includes(search.toLowerCase()) + } + ) + } + } + } + } + + public libraryOnFilter(array: any, search: string, fieldToMatch: any) { + if (search.length > 0) { + array.forEach((item: any) => { + if (!item[fieldToMatch].toLowerCase().includes(search.toLowerCase())) { + item['hidden'] = true + item['inForeground'] = false + } else { + item['hidden'] = false + item['inForeground'] = true + } + }) + } else { + this.resetArrayFilter(array) + this.displayLibraries(array) + } + } + + public displayLibraries(array: any, loadMore?: boolean) { + if (loadMore) { + this.shownLibraries += this.loadMoreCount + } else { + this.shownLibraries = librariesToShow + + this.resetLibraryForeground(array) + } + + for (let index = 0; index < array.length; index++) { + if (index === this.shownLibraries) { + break + } + + array[index]['inForeground'] = true + } + } + + public resetLibraryForeground(array: any) { + for (let index = 0; index < array.length; index++) { + array[index]['inForeground'] = false + } + } + + public metaObjectOnFilter(array: any, search: string, fieldToMatch: any) { + // array = this.deepClone(arrayAll); + + if (search.length > 0) { + this.resetArrayFilter(array) + array.forEach((item: any) => { + if (!item[fieldToMatch].toLowerCase().includes(search.toLowerCase())) { + item['hidden'] = true + } + }) + } else { + this.resetArrayFilter(array) + } + } + + public resetArrayFilter(array: any) { + array.forEach((item: any) => { + item['hidden'] = false + + if (item['inForeground']) { + delete item['inForeground'] + } + }) + } + + public isIEorEDGE() { + var ua = window.navigator.userAgent + + var msie = ua.indexOf('MSIE ') + if (msie > 0) { + // IE 10 or older => return version number + return true + } + + var trident = ua.indexOf('Trident/') + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:') + return true + } + + var edge = ua.indexOf('Edge/') + if (edge > 0) { + // Edge (IE 12+) => return version number + return true + } + + // other browser + return false + } + + public convertObjectsToArray( + objectArray: Array, + deepClone: boolean = false + ) { + if (deepClone) { + objectArray = this.deepClone(objectArray) + } + + return objectArray.map((obj: any) => { + return Object.keys(obj).map((key) => { + return obj[key] + }) + }) + } + + public addLeadingZero(value: string | number): string { + if (typeof value !== 'string') value = value.toString() + + return value.length < 2 ? '0' + value : value + } + + /** + * Hashes the object, if array provided it first deletes the keys from object + * @param data data to hash, it will be deep cloned + * @param keysToRemove keys to remove from data object + * @param clone selecting whether to deep clone data or not. Default is true + * @returns hashed string + */ + public deleteKeysAndHash( + data: any, + keysToRemove: string[], + clone: boolean = true + ): string { + const dataToHash = clone ? this.deepClone(data) : data + + for (let key of keysToRemove) { + delete dataToHash[key] + } + + return CryptoMD5(JSON.stringify(dataToHash)).toString() + } + + downloadTextFile(filename: string, text: string) { + const element = document.createElement('a') + element.setAttribute( + 'href', + 'data:text/plain;charset=utf-8,' + encodeURIComponent(text) + ) + element.setAttribute('download', filename + '.txt') + + element.style.display = 'none' + document.body.appendChild(element) + + element.click() + + document.body.removeChild(element) + } + + public convertArrayValues( + array: any[], + type: 'string' | 'number' + ): string[] | number[] { + if (array.length < 1) return [] + + switch (type) { + case 'number': { + return array.map((value) => value * 1) + } + case 'string': { + return array.toString().split(',') + } + } + } + + // Required type is NodeJS.Timeout + // But NodeJS is not available in browser so we have to go with any + private debounceTimeout: any + public debounceCall(time: number, callback: () => void) { + clearTimeout(this.debounceTimeout) + + this.debounceTimeout = setTimeout(callback, time) + } + + public deepClone(item: any) { + return cloneDeep(item) + } +} diff --git a/client/src/app/services/index.ts b/client/src/app/services/index.ts new file mode 100644 index 0000000..616904d --- /dev/null +++ b/client/src/app/services/index.ts @@ -0,0 +1,10 @@ +export * from './app-store.service' +export * from './app.service' +export * from './deploy.service' +export * from './event.service' +export * from './helper.service' +export * from './licence.service' +export * from './logger.service' +export * from './sas-store.service' +export * from './sas.service' +export * from './sasjs.service' diff --git a/client/src/app/services/licence.service.ts b/client/src/app/services/licence.service.ts new file mode 100644 index 0000000..dc8a237 --- /dev/null +++ b/client/src/app/services/licence.service.ts @@ -0,0 +1,649 @@ +import { Injectable } from '@angular/core' +import { BehaviorSubject } from 'rxjs' +import { LicenseKeyData } from '../models/LicenseKeyData' +import { SasService } from './sas.service' +import * as moment from 'moment' +import * as base64Converter from 'base64-arraybuffer' +import * as encoding from 'text-encoding' +import { Router } from '@angular/router' +import { Globvar } from '../models/sas/public-startupservice.model' +import { freeTierConfig } from '../free-tier.config' +import { AppStoreService } from './app-store.service' +import { HelperService } from './helper.service' +import { LicenceFeaturesMap, LicenceState } from '../models/LicenceState' +import { LoggerService } from './logger.service' +import { EventService } from './event.service' + +@Injectable({ + providedIn: 'root' +}) +export class LicenceService { + public userCountLimitation: boolean = false //toggler for user count limit registration + + public licenceKey: string | undefined + public activationKey: string | undefined + private licenseKeyData: LicenseKeyData | null = null + + private _licenceState: LicenceState = freeTierConfig + private allFeaturesOn: LicenceState = { + viewer_rows_allowed: Infinity, + editor_rows_allowed: Infinity, + stage_rows_allowed: Infinity, + history_rows_allowed: Infinity, + submit_rows_limit: Infinity, + tables_in_library_limit: Infinity, + viewbox_limit: Infinity, + lineage_daily_limit: Infinity, + viewbox: true, + fileUpload: true, + editRecord: true, + addRecord: true + } + + private freeTierLicenceData: LicenseKeyData = { + demo: true, + hot_license_key: this.appStoreService.getDcAdapterSettings()?.hotLicenceKey, + users_allowed: this._licenceState.users_allowed || 1, + valid_until: moment().add(1, 'year').format('YYYY-MM-DD'), + site_id: '', + site_id_multiple: [] + } + + public isAppActivated = new BehaviorSubject(null) + public isAppOverCapacity = new BehaviorSubject(false) + public currentUserCanRegister = new BehaviorSubject(false) + public appLocked = new BehaviorSubject(false) + public licenseExpiresInDays = new BehaviorSubject(null) + public isAppFreeTier = new BehaviorSubject(false) + public licenceProblem = new BehaviorSubject(null) //contains the link for particular licence error if any + public hot_license_key = new BehaviorSubject(undefined) + public licenceState: BehaviorSubject = + new BehaviorSubject(this._licenceState) + + constructor( + private loggerService: LoggerService, + private appStoreService: AppStoreService, + private eventService: EventService, + private sasService: SasService, + private helperService: HelperService, + private router: Router + ) { + this.sasService.incorrectSiteIdEmitter.subscribe((missmatchId: string) => { + if (this.isAppActivated.value !== null && !this.isAppFreeTier.value) { + const url = `/licensing/key?error=missmatch&missmatchId=${missmatchId}&force=true` + this.licenceProblem.next(url) + this.deactivateApp(url) + } + }) + } + + public async activation(startupservice: any) { + this.freeTierLicenceData.hot_license_key = + this.appStoreService.getDcAdapterSettings()?.hotLicenceKey + + await this.setStartupserviceRules(startupservice) + + await this.licensing(startupservice.globvars, startupservice.SYSSITE) + } + + /** + * Sets feature restrictions included in startupservice + * @param startupservice SAS service response + */ + public setStartupserviceRules(startupservice: any) { + // Whether or not to disable EDIT RECORD modal + this._licenceState.editRecord = !( + startupservice.globvars[0].DC_RESTRICT_EDITRECORD === 'YES' + ) + } + + /** + * Parsing the licence key, checking if it's valid, expired etc. + * It also sets the features encoded in the key. + * @param globvars from response, includes licence key, is user registered and user registered count + * @param startup_site_id system site id + */ + public async licensing(globvars: Globvar[], startup_site_id: string) { + if (!globvars || !globvars[0]) { + const err = 'Error getting "Globvars" from startupservice response.' + console.error(err) + + this.isAppActivated.next(false) + this.router.navigateByUrl( + `/licensing/key?error=invalid&details=${btoa(err)}` + ) + return + } + + let variables = globvars[0] + + if ( + variables.LICENCE_KEY === undefined || + variables.ACTIVATION_KEY === undefined || + variables.REGISTERCOUNT === null || + variables.REGISTERCOUNT === undefined || + variables.ISREGISTERED === null || + variables.ISREGISTERED === undefined + ) { + console.error('Some of globvars are not present') + this.isAppActivated.next(false) + this.eventService.showInfoModal( + 'Error', + 'Some of the globvars are not present in the startupservice' + ) + // this.router.navigateByUrl('/licensing/key?error=missing') + return + } + + if (!variables.LICENCE_KEY || !variables.ACTIVATION_KEY) { + //fall back to free tier if key not present + // setTimeout(() => { + return await this.applicationActivation( + this.freeTierLicenceData, + variables, + startup_site_id + ) + // }) + + // return + } + + this.licenceKey = variables.LICENCE_KEY + this.activationKey = variables.ACTIVATION_KEY + + await this.decryptLicenseKey( + variables.LICENCE_KEY, + variables.ACTIVATION_KEY + ).then( + async (decryptedLicenseData: LicenseKeyData) => { + await this.applicationActivation( + decryptedLicenseData, + variables, + startup_site_id + ) + }, + async (err: any) => { + const errString = `Error decrypting license key. ${err}` + console.error(errString) + // this.isAppActivated.next(false) + const url = `/licensing/key?error=invalid&details=${btoa( + errString + )}&force=true` + this.licenceProblem.next(url) + this.router.navigateByUrl(url) + + setTimeout(() => { + return this.applicationActivation( + this.freeTierLicenceData, + variables, + startup_site_id, + true + ) + }) + } + ) + } + + /** + * Checks if: + * - site id match + * - key is/isn't expired + * - user can be registered (user limit) + * @param licenseData + * @param variables from SAS response + * @param startup_site_id of current sas environment + */ + private applicationActivation( + licenseData: LicenseKeyData, + variables?: Globvar, + startup_site_id?: string, + skipRouting?: boolean + ) { + if (!skipRouting) skipRouting = false + + this.setSiteId(licenseData) + + if (!licenseData.demo && variables && startup_site_id) { + this.handleSiteIdMissmatch( + licenseData, + variables, + startup_site_id, + skipRouting + ) + } + + let hotLicenceKey = + licenseData.hot_license_key !== undefined + ? licenseData.hot_license_key + : this.hot_license_key.value + + if (!hotLicenceKey) + hotLicenceKey = this.appStoreService.getDcAdapterSettings()?.hotLicenceKey + + this.hot_license_key.next(hotLicenceKey) + + if (this.userCountLimitation) { + this.handleUsersAllowed(licenseData) + } + + this.licenseKeyData = this.helperService.deepClone(licenseData) + ;(window as any).appinfo() //Show the table of appinfo in the console + + const { expiry_date, daysToExpiry } = this.calculateExpiry(licenseData) + + ;(window as any).licenseExpiresIn = daysToExpiry + this.licenseExpiresInDays.next(daysToExpiry) + + if (daysToExpiry <= 0) { + console.error('License key has expired') + + if (variables && startup_site_id) { + this.handleExpiry(expiry_date, variables, startup_site_id, skipRouting) + } + + return + } + + this.isAppFreeTier.next(!!licenseData.demo) + + if (variables) { + this.handleUserRegistration(licenseData, variables, skipRouting) + } + + this.decodeLicenceFeatures(licenseData) + this.licenceState.next(this._licenceState) //set the global licence state + } + + /** + * Decode and set features that are encoded in the key + * featureValue - used as number/Infinity for limit set + * featureToggle - used as boolean, based on 1 or 0 encoded in the key + * @param licenseData from the licence key + */ + private decodeLicenceFeatures(licenseData: LicenseKeyData) { + if (!licenseData.features) { + if (licenseData.demo) { + return + } else { + this._licenceState = this.allFeaturesOn + return + } + } + + const featuresMap = licenseData.features.split(',') + this._licenceState = { + ...this._licenceState, + viewer_rows_allowed: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.viewer_rows_allowed] + ), + editor_rows_allowed: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.editor_rows_allowed] + ), + stage_rows_allowed: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.stage_rows_allowed] + ), + history_rows_allowed: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.history_rows_allowed] + ), + submit_rows_limit: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.submit_rows_limit] + ), + tables_in_library_limit: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.tables_in_library_limit] + ), + viewbox_limit: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.viewbox_limit] + ), + lineage_daily_limit: this.parseFeatureValue( + featuresMap[LicenceFeaturesMap.lineage_daily_limit] + ), + viewbox: this.parseFeatureToggle(featuresMap[LicenceFeaturesMap.viewbox]), + fileUpload: this.parseFeatureToggle( + featuresMap[LicenceFeaturesMap.fileUpload] + ), + editRecord: this.parseFeatureToggle( + featuresMap[LicenceFeaturesMap.editRecord] + ), + addRecord: this.parseFeatureToggle( + featuresMap[LicenceFeaturesMap.addRecord] + ) + } + + this.loggerService.log('Licence state:', this._licenceState) + } + + /** + * Converts licence key feature code value to the number or Infinity + * Used for limiting rows, submits etc. + * @param codeBit from licence key encoded features. Every bit is separated by comma(,) Eg. 5,10,15 + * @returns number + */ + private parseFeatureValue(codeBit: string): number { + if (codeBit === '-') return Infinity + return parseInt(codeBit) + } + + /** + * Converts licence key feature code value to the boolean. Depending on if it's 0 or 1 + * @param codeBit from licence key encoded features. Every bit is separated by comma(,) Eg. 1,1,0 + * @returns boolean to turn on or off the value + */ + private parseFeatureToggle(codeBit: string): boolean { + return !!parseInt(codeBit) + } + + /** + * If decryption fails, key will be marked as invalid and app not activated. + */ + private decryptLicenseKey( + licenseKey: string, + activationKey: string + ): Promise { + return new Promise(async (resolve, reject) => { + if (!(window.crypto && window.crypto.subtle)) { + try { + let licenseKeyDecoded = atob(licenseKey.split('').reverse().join('')) + + resolve(JSON.parse(licenseKeyDecoded)) + } catch (ex) { + reject('Error parsing http license key data. ' + ex) + } + } + + let licenseKeyBytes = await this.base64ToArrayBuffer(licenseKey).catch( + (err: any) => { + reject(err) + } + ) + + let activationKeyBytes: ArrayBuffer + const activationKeyBytesTemp = await this.base64ToArrayBuffer( + activationKey + ).catch((err: any) => { + reject(err) + }) + + if (!activationKeyBytesTemp) { + reject('Missing activation key') + return + } + + activationKeyBytes = activationKeyBytesTemp + + let decryptionKey + + try { + decryptionKey = await window.crypto.subtle.importKey( + 'pkcs8', + activationKeyBytes, + { + name: 'RSA-OAEP', + hash: 'SHA-256' + }, + true, + ['decrypt'] + ) + } catch (ex) { + reject('Unable to import decryption key: ' + ex) + } + + if (!decryptionKey) { + reject('Unable to import decryption key') + return + } + + if (!licenseKeyBytes) { + reject('License key bytes missing') + } else { + try { + window.crypto.subtle + .decrypt( + { + name: 'RSA-OAEP', + hash: { name: 'SHA-256' } + } as any, + decryptionKey, + licenseKeyBytes + ) + .then( + (value: any) => { + let keyDataString = new encoding.TextDecoder().decode(value) + + try { + resolve(JSON.parse(keyDataString)) + } catch (ex) { + reject('Error parsing license key data. ' + ex) + } + }, + (err: any) => { + reject(err) + } + ) + } catch (ex) { + reject(ex) + } + } + }) + } + + public getHotLicenseKey() { + return this.hot_license_key.value + } + + public getLicenseKeyData() { + return this.licenseKeyData + } + + public deactivateApp(redirectTo?: string) { + // this.isAppActivated.next(false) + + this._licenceState = freeTierConfig + this.applicationActivation(this.freeTierLicenceData) + + if (redirectTo) this.router.navigateByUrl(redirectTo) + } + + /** + * Checks fo lineage daily renderings limit + * + * @param checkOnly if true it will only check if limit reached + * othervise it will increment number of renderings. + * @returns true if limited and false if not limited + */ + public checkLineageLimit(checkOnly?: boolean): boolean { + if (this.licenceState.value.lineage_daily_limit === Infinity) return false + + const renders = localStorage.getItem('lineage_renders') + const todayTimestamp = moment().valueOf() + + if (!renders) { + if (!checkOnly) this.setLineageRender(todayTimestamp, 1) + return false + } + + const timestamp = parseInt(renders.split(',')[0]) + const noOfRenders = parseInt(renders.split(',')[1]) + + if (moment(timestamp).isSame(moment(), 'day')) { + if (noOfRenders >= this.licenceState.value.lineage_daily_limit) + return true + + if (!checkOnly) this.setLineageRender(todayTimestamp, noOfRenders + 1) + return false + } + + if (!checkOnly) this.setLineageRender(todayTimestamp, 1) + return false + } + + private setLineageRender(timestamp: number, renders: number) { + localStorage.setItem('lineage_renders', `${timestamp},${renders}`) + } + + public base64ToArrayBuffer(base64: string): Promise { + return new Promise(async (resolve, reject) => { + resolve(base64Converter.decode(base64)) + }) + } + + public arrayBufferToBase64(arrayBuffer: ArrayBuffer): Promise { + return new Promise((resolve, reject) => { + resolve(base64Converter.encode(arrayBuffer)) + }) + } + + private setSiteId(licenseData: LicenseKeyData) { + if (licenseData.site_id_multiple) { + this.sasService.setLicenseSiteId(licenseData.site_id_multiple) + } else if (licenseData.site_id) { + this.sasService.setLicenseSiteId(licenseData.site_id) + } + } + + /** + * One of our customers is having multiple site ids in same organization. + * So we added support for list od site ids to be placed in licence key. + * But we also want to have dc backwards compatible so we have to check + * for both properties legacy and new. + * New key must work with old DC + * Old key must work with new DC + */ + private handleSiteIdMissmatch( + licenseData: LicenseKeyData, + variables: Globvar, + startup_site_id: string, + skipRouting: boolean + ) { + let noLegacySiteId: boolean = false + let noMultipleSiteId: boolean = false + + if (!licenseData.site_id || licenseData.site_id !== startup_site_id) { + noLegacySiteId = true + } + + if ( + !licenseData.site_id_multiple || + !licenseData.site_id_multiple.includes(startup_site_id) + ) { + noMultipleSiteId = true + } + + if (noLegacySiteId && noMultipleSiteId) { + console.error('The key provided is for different organization.') + // this.isAppActivated.next(false) + + setTimeout(() => { + const url = '/licensing/key?error=missmatch&force=true' + this.licenceProblem.next(url) + + this._licenceState = freeTierConfig + + this.applicationActivation( + this.freeTierLicenceData, + variables, + startup_site_id, + true + ) + + if (!skipRouting) this.router.navigateByUrl(url) + }) + + return + } + } + + private calculateExpiry(licenseData: LicenseKeyData): { + expiry_date: moment.Moment + daysToExpiry: number + } { + let expiry_date = moment(licenseData.valid_until, 'YYYY-MM-DD').startOf( + 'day' + ) + let current_date = moment().startOf('day') + let daysToExpiry = expiry_date.diff(current_date, 'days') + + return { + expiry_date, + daysToExpiry + } + } + + private handleExpiry( + expiry_date: moment.Moment, + variables: Globvar, + startup_site_id: string, + skipRouting: boolean + ) { + setTimeout(() => { + const url = `/licensing/key?force=true&error=expired&details=${btoa( + 'Expiry date: ' + expiry_date.format('DD/MM/YYYY') + )}` + this.licenceProblem.next(url) + // Instead of blocking the app we revert to free tier version of the app + this.applicationActivation( + this.freeTierLicenceData, + variables, + startup_site_id, + true + ) + + if (!skipRouting) { + this.router.navigateByUrl(url) + } + }) + } + + private handleUsersAllowed(licenseData: LicenseKeyData) { + if (licenseData.demo) { + if (this._licenceState.users_allowed !== undefined) + licenseData.users_allowed = + licenseData.users_allowed > 0 + ? licenseData.users_allowed + : this._licenceState.users_allowed + } + + this._licenceState.users_allowed = licenseData.users_allowed + } + + private handleUserRegistration( + licenseData: LicenseKeyData, + variables: Globvar, + skipRouting: boolean + ) { + if (this.userCountLimitation) { + //if limit disabled we don't track the count + if (variables.REGISTERCOUNT > licenseData.users_allowed) { + //App is over capacity of users + console.warn('App has more users registered then licensed.') + this.isAppOverCapacity.next(true) + } else if (variables.REGISTERCOUNT === licenseData.users_allowed) { + //App reached capacity of users + console.warn('App has hit limit of users registered.') + } + } + + if (variables.ISREGISTERED === 1) { + this.isAppActivated.next(true) + return + } else { + // if limit is disabled we always go into register directly + if ( + variables.REGISTERCOUNT < licenseData.users_allowed || + !this.userCountLimitation + ) { + console.log('User can register') + this.currentUserCanRegister.next(true) + // this.appLocked.next(true) + this.isAppActivated.next(false) + if (!skipRouting) this.router.navigateByUrl('/licensing/register') + //After register, activate app + return + } else { + this.currentUserCanRegister.next(false) + this.isAppActivated.next(false) + // this.appLocked.next(true) + if (!skipRouting) this.router.navigateByUrl('/licensing/limit') + } + } + } +} diff --git a/client/src/app/services/logger.service.ts b/client/src/app/services/logger.service.ts new file mode 100644 index 0000000..c5e36b4 --- /dev/null +++ b/client/src/app/services/logger.service.ts @@ -0,0 +1,48 @@ +import { Injectable, Injector } from '@angular/core' +import { SASjsConfig } from '@sasjs/adapter' +import { SasService } from './sas.service' + +@Injectable({ + providedIn: 'root' +}) +export class LoggerService { + private sasjsConfig: SASjsConfig | undefined + + constructor(private injector: Injector) {} + + public log(message: any, optionalParameters?: any) { + this.injectSasService() + + if (this.sasjsConfig?.debug) + optionalParameters + ? console.log(message, optionalParameters) + : console.log(message) + } + + public error(message: any, optionalParameters?: any) { + console.error(message, optionalParameters) + } + + public logRequestData(program: string, data: { [key: string]: any }) { + this.log('--- Adapter Request Input ---') + this.log(program) + + if (!data) { + this.log('no data sent') + return + } + + for (let key of Object.keys(data)) { + this.log(key, data[key]) + } + + this.log('------') + } + + private injectSasService() { + if (!this.sasjsConfig) { + const sasService = this.injector.get(SasService) + this.sasjsConfig = sasService.getSasjsConfig() + } + } +} diff --git a/client/src/app/services/sas-store.service.ts b/client/src/app/services/sas-store.service.ts new file mode 100644 index 0000000..92b9a41 --- /dev/null +++ b/client/src/app/services/sas-store.service.ts @@ -0,0 +1,755 @@ +import { Injectable } from '@angular/core' +import { Subject } from 'rxjs' + +import { SpecObj } from '../interfaces' +import { SasService } from './sas.service' +import { HelperService } from './helper.service' + +import { QueryClause } from '../models/TableData' +import { globals } from '../_globals' +import { FilterClause, FilterGroup, FilterQuery } from '../models/FilterQuery' +import { + $DataFormats, + EditorsGetdataSASResponse, + EditorsGetdataServiceResponse +} from '../models/sas/editors-getdata.model' +import { LoggerService } from './logger.service' +import { isSpecialMissing } from '@sasjs/utils/input/validators' +import { Col } from '../shared/dc-validator/models/col.model' +import { get } from 'lodash-es' + +@Injectable() +export class SasStoreService { + public libds!: string + public response: Subject = new Subject() + public changedTable: Subject = new Subject() + public details: Subject = new Subject() + public diffs: Subject = new Subject() + public columns: Subject = new Subject() + public values: Subject = new Subject() + public filter: Subject = new Subject() + public query: Subject = new Subject() + public submittDetail: Subject = new Subject() + public removeQuery: Subject = new Subject() + public setSubmit: Subject = new Subject() + public setSubmitList: Subject = new Subject() + + constructor( + private sasService: SasService, + private helperService: HelperService, + private loggerService: LoggerService + ) {} + + public async callService( + tableData: Array, + tableName: string, + program: string, + libds: string + ) { + this.libds = libds + let tables: any = {} + tables[tableName] = [tableData] + let res: EditorsGetdataSASResponse = await this.sasService.request( + program, + tables + ) + let response: EditorsGetdataServiceResponse = { + data: res, + libds: this.libds + } + return response + } + + public async updateTable( + tableParams: any, + tableData: any, + tableName: string, + program: string, + $dataFormats: $DataFormats | null + ) { + // add sp as third argument of createData call + + let tables: any = { + jsdata: tableData + } + + if ($dataFormats) { + let formats = this.parseFormats($dataFormats) + + tables.$jsdata = { formats: formats } + } + + tables[tableName] = [tableParams] + + let res: any = await this.sasService.request(program, tables) + + return res + } + + public async getApprovals( + tableData: any, + tableName: string, + program: string + ) { + let tables: any = {} + tables[tableName] = [tableData] + let res: any = await this.sasService.request(program, tables) + return res + } + public async sendDetails(detail: any, index: any, data: any) { + let details = Object.assign({ sub: true }, detail) + let subData = data[index] + let allData = { + data: subData, + viewData: details + } + this.submittDetail.next(allData) + } + public async getSubmitts() { + let res: any = await this.sasService.request('editors/getsubmits', null) + return res + } + + public async viewLibs() { + return this.sasService.request('public/viewlibs', null) + } + + public async refreshLibInfo(libref: string) { + const data = { + lib2refresh: [{ libref }] + } + + return this.sasService.request('public/refreshlibinfo', data) + } + + public async versionHistory(libDataset: any) { + const data = { iwant: [{ LIBDS: libDataset }] } + let res: any = await this.sasService.request( + 'public/getversionhistory', + data + ) + return res + } + + public async viewTables(lib: any) { + let tables = { SASControlTable: [{ MPLIB: lib }] } + let res: any = await this.sasService.request('public/viewtables', tables) + return res + } + + public async viewData(libDataset: any, filter_pk: any) { + let tables = { + SASControlTable: [{ LIBDS: libDataset, FILTER_RK: filter_pk }] + } + let res: any = await this.sasService.request('public/viewdata', tables) + return res + } + + public async viewDataSearch( + searchVal: string, + numeric: boolean = false, + libDataset: any, + filter_pk: any + ) { + let SEARCHTYPE = numeric ? 'NUM' : 'CHAR' + + let tables = { + SASControlTable: [ + { + SEARCHTYPE: searchVal.length > 0 ? SEARCHTYPE : 'NONE', + SEARCHVAL: searchVal, + LIBDS: libDataset, + FILTER_RK: filter_pk + } + ] + } + let res: any = await this.sasService.request('public/viewdata', tables) + return res + } + + public async getDetails(tableData: any, tableName: string, program: string) { + let tables: any = {} + tables[tableName] = [tableData] + + let res: any = await this.sasService.request(program, tables) + return res + } + + public async showDiffs(tableData: any, tableName: string, program: string) { + let tables: any = {} + tables[tableName] = [tableData] + let res: any = await this.sasService.request(program, tables, { + useComputeApi: false + }) + return res + } + public async rejecting(tableData: any, tableName: string, program: string) { + let tables: any = {} + tables[tableName] = [tableData] + let res: any = await this.sasService.request(program, tables, { + useComputeApi: false + }) + return res + } + + public async approveTable( + tableData: any, + tableName: string, + program: string + ) { + let tables: any = {} + tables[tableName] = [tableData] + + let res: any = await this.sasService.request(program, tables) + return res + } + + public async getHistory(tableData: any, tableName: string, program: string) { + let tables: any = {} + tables[tableName] = [tableData] + let res: any = await this.sasService.request(program, tables) + return res + } + + setQueryVariables(dataset: string, cols: any) { + let columnsData: any = { data: { cols: cols }, libds: dataset } + + this.columns.next(columnsData) + } + + public async getChangeInfo(tableId: any) { + let obj = { TABLE: tableId } + let table = { SASControlTable: [obj] } + let res: any = await this.sasService.request('public/getchangeinfo', table) + return res + } + + public async getQueryValues( + variable: string, + dataset: string, + filterQuery: any[], + STARTROW?: number, + ROWS?: number + ) { + let tables: any = { + iwant: [ + { + libds: dataset, + col: variable, + ...(STARTROW && { STARTROW: STARTROW }), //add only if present + ...(ROWS && { ROWS: ROWS }) //add only if present + } + ] + } + + if (filterQuery.length > 0) { + tables.FILTERQUERY = filterQuery + } + + let res: any = await this.sasService + .request('public/getcolvals', tables) + .catch((er: any) => { + throw er + }) + + return res + } + + public async saveQuery(libds: string, filterQuery: QueryClause[]) { + let tables = { + iwant: [{ filter_table: libds }], + filterquery: filterQuery + } + + let res: any = await this.sasService.request( + 'public/validatefilter', + tables + ) + this.filter.next(res) + return res + } + + public async openTable(tableId: string) { + let tables = { iwant: [{ table_id: tableId }] } + let res: any = await this.sasService.request( + 'auditors/getstagetable', + tables + ) + return res + } + + public checkOperator(operator: any, value: any, type: string) { + let val + let operators = ['=', '>', '<', '<=', '>=', 'ne'] + switch (operator) { + case 'BETWEEN': + if (value instanceof Array) { + if (value[0] !== '' && value[1] !== '') { + val = value[0] + ' AND ' + value[1] + } else if (value[0] !== '' && value[1] === '') { + value[1] = '.' + val = value[0] + ' AND ' + value[1] + } else if (value[0] === '' && value[1] !== '') { + value[0] = '.' + val = value[0] + ' AND ' + value[1] + } else { + value[0] = '.' + value[1] = '.' + val = value[0] + ' AND ' + value[1] + } + } + break + case 'IN': + case 'NOT IN': + let arr = [] + if (typeof value !== 'undefined') { + for (let ind = 0; ind < value.length; ind++) { + if (value[ind].checked === true) { + if (type === 'char') { + if (typeof value[ind].val === 'string') { + value[ind].val = value[ind].val.replace("'", "''") + } + + arr.push("'" + value[ind].val + "'") + } else { + if (value[ind].val === null) { + value[ind].val = '.' + } + arr.push(value[ind].val) + } + } + } + } + value = '(' + arr + ')' + break + case 'CONTAINS': + operator = '?' + break + case 'NOT EQUAL': + operator = 'ne' + break + default: + break + } + + if (type === 'num' && value === null) { + value = '.' + } + + if (value === 'Please select value') { + value = '' + } + + if (operators.indexOf(operator) !== -1 && type === 'num' && value === '') { + value = '.' + } + + if (operator === 'BETWEEN') { + return { value: val, operator: operator } + } else { + return { value: value, operator: operator } + } + } + + public whereClauseCreator( + clauses: any, + groupOperator: string, + libds: string + ) { + let whereString: string = '' + let clausesArr = clauses.queryObj + let clausesLogic = clauses.groupLogic + let opr + let where = '' + let clauseArr = [] + + for (let index = 0; index < clauses.queryObj.length; index++) { + let string = '' + let clause = clauses.queryObj[index] + for (let ind = 0; ind < clause.elements.length; ind++) { + let query = clause.elements[ind] + if (ind < clause.elements.length - 1) { + opr = clause.clauseLogic + } else { + opr = '' + } + let val: any + for (let k = 0; k < query.values.length; k++) { + if ( + typeof query.value === 'string' && + typeof query.values[k].formatted === 'number' + ) { + if (query.value === JSON.stringify(query.values[k].formatted)) { + val = query.values[k].unformatted + } + } else { + let dropValue = + typeof query.values[k].formatted !== 'number' && + query.values[k].formatted !== null + ? query.values[k].formatted.trim() + : query.values[k].formatted + + if (query.value === dropValue) { + val = query.values[k].unformatted + } + } + + let operators = ['=', '>', '<', '<=', '>=', 'ne'] + + if ( + query.value === 'Please select value' && + operators.indexOf(query.operator) !== -1 + ) { + val = '' + } + + if ( + query.operator === 'CONTAINS' || + query.operator === 'LIKE' || + query.operator === 'BEGINS_WITH' + ) { + val = query.value + } + } + + if (!val) { + val = query.value + } + + if (query.value instanceof Array && query.operator === 'BETWEEN') { + val = [] + val.push(query.value[0]) + val.push(query.value[1]) + for (let i = 0; i < query.values.length; i++) { + if (val[0] === query.values[i].formatted) { + val[0] = query.values[i].unformatted + } + if (val[1] === query.values[i].formatted) { + val[1] = query.values[i].unformatted + } + } + } + + if ( + query.value instanceof Array && + (query.operator === 'IN' || query.operator === 'NOT IN') + ) { + val = [] + val = query.value + for (let i = 0; i < query.values.length; i++) { + if (val[i] && val[i].val === query.values[i].formatted) { + val[i].val = query.values[i].unformatted + } + } + } + + let type = query.type + let variable = query.variable === null ? '' : query.variable + let oper = query.operator === null ? '' : query.operator + // let value = val === null ? "''" : val; + let value + value = this.checkOperator(oper, val, type).value + if (typeof value === 'string' && value[0] !== '(') { + value = value.replace("'", "''") + } + oper = this.checkOperator(oper, value, type).operator + + if (type === 'char' && oper !== 'IN' && oper !== 'NOT IN') { + if (typeof value === 'undefined') { + value = '' + value = " '" + value + "' " + } else { + value = " '" + value + "' " + } + string = string + ' ' + variable + ' ' + oper + value + opr + } else { + if (type === 'num' && typeof value === 'undefined') { + value = '.' + } + + if (typeof value === 'undefined') { + value = '' + } else { + value = ' ' + value + ' ' + } + string = string + ' ' + variable + ' ' + oper + value + opr + } + } + clauseArr.push(string) + } + where = '' + let groupOper + for (let i = 0; i < clauseArr.length; i++) { + if (i < clauseArr.length - 1) { + groupOper = groupOperator + } else { + groupOper = '' + } + if (clauseArr.length === 1) { + where = clauseArr[0] + } else { + where = where + ' (' + clauseArr[i] + ') ' + groupOper + } + } + + whereString = where.substr(1).slice(0, -1) + where = 'WHERE' + where + ';' + + let queryClause = { + whereClause: where, + string: whereString, + obj: clauses, + libds: libds + } + this.query.next(queryClause) + return { whereClause: where, string: whereString } + } + + /** + * This function creates Filter Query Table + * @param filterQuery an object of type FilterQuery + * @returns {QueryClause[]} array of QueryClause + */ + public createFilterQueryTable(filterQuery: FilterQuery): QueryClause[] { + const filterQueryClauseTable: QueryClause[] = [] + + filterQuery.filterGroups.forEach( + (filterGroup: FilterGroup, groupIndex: number) => { + filterGroup.filterClauses.forEach((filterClause: FilterClause) => { + let rawValue = '' + if (filterClause.operator === 'BETWEEN') { + rawValue = `${filterClause.value[0]} AND ${filterClause.value[1]}` + } else if ( + filterClause.operator === 'IN' || + filterClause.operator === 'NOT IN' + ) { + filterClause.value.forEach((element: any) => { + if (element.checked) { + const value = element.val + if ( + typeof value === 'string' && + (!isSpecialMissing(value) || filterClause.type === 'char') + ) { + if (rawValue.length > 0) { + rawValue += `,'${value.replace(/'/g, "''")}'` + } else { + rawValue = `('${value.replace(/'/g, "''")}'` + } + } else { + if (rawValue.length > 0) { + rawValue += `,${value}` + } else { + rawValue = `(${value}` + } + } + } + }) + if (rawValue.length > 0) { + rawValue += ')' + } + } else if (filterClause.value === '') { + if (filterClause.type === 'char') { + rawValue = `' '` + } else { + rawValue = '.' + } + } else { + if (filterClause.type === 'char') { + rawValue = `'${filterClause.value.replace(/'/g, "''")}'` + } + } + filterQueryClauseTable.push({ + GROUP_LOGIC: filterQuery.groupLogic, + SUBGROUP_LOGIC: filterGroup.clauseLogic || 'AND', + SUBGROUP_ID: groupIndex, + VARIABLE_NM: filterClause.variable, + OPERATOR_NM: filterClause.operator, + RAW_VALUE: rawValue || filterClause.value + }) + }) + } + ) + + return filterQueryClauseTable + } + + /** + * This helper function initializes global filter when user load the filtered url + * @param path it tells whether function is being called from viewer component or editor + * @param cols array of columns metadata + */ + public initializeGlobalFilterClause(page: string, cols: Col[]): void { + const clauses: any = { + queryObj: [], + clauseLogic: [], + groupLogic: get(globals, page).filter.query[0].GROUP_LOGIC + } + + get(globals, page).filter.clauses = this.helperService.deepClone(clauses) + get(globals, page).filter.groupLogic = get( + globals, + page + ).filter.query[0].GROUP_LOGIC + + let subGroupLogic = '' + let group: any = { elements: [] } + let groupID = 0 + + get(globals, page).filter.query.forEach((obj: any) => { + const temp: any = {} + for (let i = 0; i < cols.length; i++) { + if (cols[i].NAME === obj.VARIABLE_NM) { + subGroupLogic = obj.SUBGROUP_LOGIC + temp['ddtype'] = cols[i].DDTYPE + temp['type'] = cols[i].TYPE + + if (cols[i].TYPE === 'num') { + temp['operators'] = globals.operators.numOperators + } else { + temp['operators'] = globals.operators.charOperators + } + + temp['logic'] = null + temp['operator'] = obj.OPERATOR_NM + temp['variable'] = obj.VARIABLE_NM + + if (cols[i].TYPE === 'char') { + if (obj.OPERATOR_NM === 'IN' || obj.OPERATOR_NM === 'NOT IN') { + const newValueArray: { checked: boolean; val: any }[] = [] + const valueString = obj.RAW_VALUE.slice(1, -1) + const valueArray = valueString.split("','") + + if (valueArray.length === 1) { + newValueArray.push({ + checked: true, + val: valueArray[0].slice(1, -1).replace(/''/g, "'") + }) + } else { + valueArray.forEach((element: string, index: number) => { + if (index === 0) { + newValueArray.push({ + checked: true, + val: element.slice(1).replace(/''/g, "'") + }) + } else if (index === valueArray.length - 1) { + newValueArray.push({ + checked: true, + val: element.slice(0, -1).replace(/''/g, "'") + }) + } else { + newValueArray.push({ + checked: true, + val: element.replace(/''/g, "'") + }) + } + }) + } + temp['value'] = this.helperService.deepClone(newValueArray) + } else { + temp['value'] = obj.RAW_VALUE.slice(1, -1).replace(/''/g, "'") + } + } else { + if (obj.OPERATOR_NM === 'IN' || obj.OPERATOR_NM === 'NOT IN') { + const newValueArray: { checked: boolean; val: any }[] = [] + const valueString = obj.RAW_VALUE.slice(1, -1) + const valueArray = valueString.split(',') + valueArray.forEach((element: string, index: number) => { + newValueArray.push({ + checked: true, + val: element + }) + }) + temp['value'] = this.helperService.deepClone(newValueArray) + } else if (obj.OPERATOR_NM === 'BETWEEN') { + const valueArray = obj.RAW_VALUE.split(' AND ') + temp['value'] = valueArray + } else { + temp['value'] = obj.RAW_VALUE + } + } + + temp['values'] = [] + if (groupID === obj.SUBGROUP_ID) { + group.elements.push(this.helperService.deepClone(temp)) + } else { + get(globals, page).filter.clauses.queryObj.push( + this.helperService.deepClone(group) + ) + get(globals, page).filter.clauses.queryObj[groupID].clauseLogic = + subGroupLogic + get(globals, page).filter.clauses.queryObj[groupID].invalidClause = + false + groupID++ + group.elements = [] + group.elements.push(this.helperService.deepClone(temp)) + } + break + } + } + }) + if (group.elements.length > 0) { + get(globals, page).filter.clauses.queryObj.push( + this.helperService.deepClone(group) + ) + get(globals, page).filter.clauses.queryObj[groupID].clauseLogic = + subGroupLogic + get(globals, page).filter.clauses.queryObj[groupID].invalidClause = false + } + get(globals, page).filter.query = [] + } + + public async removeClause() { + let removeFlag = true + this.removeQuery.next(removeFlag) + return removeFlag + } + + public specConversion(spec: any) { + let specObj: SpecObj = {} + let namesArr = [] + namesArr = spec.map(function (item: any) { + return item.NAME.toUpperCase() + }) + if (spec instanceof Array) { + for (let index = 0; index < namesArr.length; index++) { + if (spec[index].TYPE === 1) { + specObj[namesArr[index]] = { + colType: 'num', + colLength: spec[index].LENGTH + } + } else { + specObj[namesArr[index]] = { + colType: 'string', + colLength: spec[index].LENGTH + } + } + } + } + return specObj + } + + setSubmitReady() { + let ready = true + this.setSubmit.next(ready) + } + + parseFormats($dataFormats: $DataFormats) { + const formats: { + [key: string]: any + } = {} + const vars = $dataFormats.vars + + for (let col of Object.keys(vars)) { + const type = vars[col].type + const length = vars[col].length + + if (type === 'num') { + formats[col] = 'best.' + } else if (type === 'char') { + formats[col] = `$char${length}.` + } + } + + return formats + } +} diff --git a/client/src/app/services/sas-viya.service.ts b/client/src/app/services/sas-viya.service.ts new file mode 100644 index 0000000..b751679 --- /dev/null +++ b/client/src/app/services/sas-viya.service.ts @@ -0,0 +1,100 @@ +import { HttpClient } from '@angular/common/http' +import { Injectable } from '@angular/core' +import { Observable } from 'rxjs' +import { Collection } from '../viya-api-explorer/models/collection.model' +import { AppStoreService } from './app-store.service' +import { ViyaApis } from '../viya-api-explorer/models/viya-apis.models' + +@Injectable({ + providedIn: 'root' +}) +export class SasViyaService { + // Viya APIs + public viyaApis: ViyaApis = { + Analytics_Insights: { + insights: '/insights' + }, + Visualisation: { + reports: '/reports', + reportImages: '/reportImages', + reportTransforms: '/reportTransforms', + visualAnalytics: '/visualAnalytics' + }, + Compute: { + jobs: '/jobDefinitions', + jobExecution: '/jobExecution' + }, + Decision_Management: { + modelManagement: '/modelManagement', + modelRepository: '/modelRepository', + modelPublish: '/modelPublish', + microanalyticScore: '/microanalyticScore', + dataMining: '/dataMining', + businessRules: '/businessRules', + referenceData: '/referenceData', + treatmentDefinitions: '/treatmentDefinitions', + subjectContacts: '/subjectContacts', + decisionsRuntimeBuilder: '/decisionsRuntimeBuilder' + }, + Core_Services: { + folders: '/folders', + files: '/files', + annotations: '/annotations', + authorization: '/authorization', + relationships: '/relationships', + SASLogon: '/SASLogon' + }, + Automated_Machine_Learning: { + mlPipelineAutomation: '/mlPipelineAutomation' + }, + Other: { + identities: '/identities' + } + } + + private serverUrl: string = '' + + constructor( + private http: HttpClient, + private appStoreService: AppStoreService + ) { + const adapterConfig = this.appStoreService.getDcAdapterSettings() + + this.serverUrl = adapterConfig?.serverUrl || '' + + //example + this.getByCollection('jobs').subscribe((res) => { + console.log('res', res) + }) + } + + /** + * + * @returns All Viya API collections that we support + */ + getAllCollections() { + return this.viyaApis + } + + /** + * Used for clicking trough collections / apis + * @param url collection/api endpoint url + * @returns + */ + getByUrl(url: string): Observable { + return this.http.get(`${this.serverUrl}${url}`, { + withCredentials: true + }) + } + + /** + * We refer collection as starting point /jobs /folders etc. + * @param apiCollection + * @returns + */ + getByCollection(apiCollection: string): Observable { + return this.http.get(`${this.serverUrl}${apiCollection}`, { + withCredentials: true + }) + } +} diff --git a/client/src/app/services/sas.service.ts b/client/src/app/services/sas.service.ts new file mode 100644 index 0000000..4006b7b --- /dev/null +++ b/client/src/app/services/sas.service.ts @@ -0,0 +1,495 @@ +import { Injectable, EventEmitter } from '@angular/core' + +import SASjs, { UploadFile } from '@sasjs/adapter' +import { BehaviorSubject } from 'rxjs' +import { UserService } from '../shared/user.service' + +import { Router } from '@angular/router' +import { EventService } from './event.service' +import { SasjsService } from './sasjs.service' +import { SASjsApiDriveFolderContents } from '../models/sasjs-api/SASjsApiDriveFolderContents.model' +import { ServerType } from '@sasjs/utils/types/serverType' +import { DcAdapterSettings } from '../models/DcAdapterSettings' +import { AppStoreService } from './app-store.service' +import { LoggerService } from './logger.service' +import { RequestWrapperOptions } from '../models/RequestWrapperOptions' + +@Injectable({ + providedIn: 'root' +}) +export class SasService { + public loadStartupServiceEmitter: EventEmitter = new EventEmitter() + public incorrectSiteIdEmitter: EventEmitter = new EventEmitter() + public requestSiteIdEmitter: EventEmitter = new EventEmitter() + + private sasjsAdapter: SASjs = new SASjs() + private dcAdapterSettings: DcAdapterSettings | undefined + public serverType: any + private appLocCheckPending: boolean = false + + public shouldLogin = new BehaviorSubject(false) + private license_site_id = new BehaviorSubject(null) + + constructor( + private appStoreService: AppStoreService, + private userService: UserService, + private eventService: EventService, + private sasjsService: SasjsService, + private loggerService: LoggerService, + private router: Router + ) {} + + public sasServiceInit() { + this.dcAdapterSettings = this.appStoreService.getDcAdapterSettings() + + this.sasjsService.setup() + + if (!this.dcAdapterSettings) { + this.eventService.showInfoModal( + 'Error', + 'Adapter settings (index.html) are not present.' + ) + return + } + + this.sasjsAdapter = new SASjs(this.dcAdapterSettings) + + switch (this.dcAdapterSettings.serverType) { + case ServerType.SasViya: { + this.checkViyaDeploy(this.dcAdapterSettings.appLoc || '') + break + } + case ServerType.Sas9: { + this.loadStartupServiceEmitter.emit() + break + } + case ServerType.Sasjs: { + this.checkSasjsDeploy() + break + } + } + + if (this.getSasjsConfig().loginMechanism === 'Redirected') { + this.shouldLogin.subscribe((shouldLogin) => { + if (shouldLogin) { + this.sasjsAdapter.logIn().then((res) => { + console.log('res', res) + }) + } + }) + } + } + + public request( + url: string, + data: any, + config?: any, + wrapperOptions?: RequestWrapperOptions + ): Promise { + url = 'services/' + url + + if (!wrapperOptions) wrapperOptions = {} + + // If debug is on it will print what is going inside the adapter + this.loggerService.logRequestData(url, data) + + return new Promise((resolve, reject) => { + this.sasjsAdapter + .request(url, data, config, () => { + this.shouldLogin.next(true) + }) + .then( + (res: any) => { + if (res.login === false) { + this.shouldLogin.next(true) + reject(false) + } + + if (!this.userService.user && res.MF_GETUSER) { + this.userService.user = { + username: res.MF_GETUSER + } + } + + if (res.SYSSITE) { + this.requestSiteIdEmitter.emit(res.SYSSITE) + + const licenseSiteId = this.getLicenseSiteId() + + if (licenseSiteId.length > 0) { + if (!this.getLicenseSiteId().includes(res.SYSSITE)) { + this.incorrectSiteIdEmitter.emit(res.SYSSITE) + } + } + } + + if (res.status === 404) { + reject({ MESSAGE: res.body || 'SAS Responded with error' }) + } + + if (typeof res.sasjsAbort !== 'undefined') { + const abortRes = res + const abortMsg = abortRes.sasjsAbort[0].MSG + const macMsg = abortRes.sasjsAbort[0].MAC + + if ( + abortMsg.includes( + 'Data_Controller_Settings(StoredProcess) not found' + ) + ) { + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + + reject({ error: abortMsg }) + + return + } + + if (!wrapperOptions?.suppressSuccessAbortModal) { + this.eventService.showAbortModal( + url.replace('services/', ''), + abortMsg, + { + SYSWARNINGTEXT: abortRes.SYSWARNINGTEXT, + SYSERRORTEXT: abortRes.SYSERRORTEXT, + MAC: macMsg + } + ) + } + + reject({ error: abortMsg }) + } + + resolve(res) + }, + (err: { error: ErrorBody | undefined }) => { + console.error(err) + + if (err.error) { + let errorMessage: string | undefined = err.error.message + let log: string | undefined + + if (err.error.details && err.error.details.log) { + log = err.error.details.log + } + + // If not a single useful info is returned from adapter + // We display that it's `unknown` SAS service error + if (!errorMessage || errorMessage.trim().length < 1) { + errorMessage = 'SAS Service error ocurred' + } + + // Otherwise we display error message from adapter + if (!wrapperOptions?.suppressErrorAbortModal) { + this.eventService.showAbortModal( + url, + errorMessage, + { LOG: log }, + 'Request error' + ) + } + reject({ error: errorMessage }) + } + + reject(err) + } + ) + }) + } + + public uploadFile(sasService: string, files: UploadFile[], params: any) { + return this.sasjsAdapter.uploadFile(sasService, files, params) + } + + public async login(username: string, password: string) { + const clientId = + this.getServerType() === ServerType.Sasjs ? 'clientID1' : undefined + + return this.sasjsAdapter + .logIn(username, password, clientId) + .then( + (res: { isLoggedIn: boolean; userName: string }) => { + if (res.isLoggedIn) { + this.userService.user = { username: res.userName } + + if (this.appLocCheckPending) { + this.checkViyaDeploy(this.dcAdapterSettings?.appLoc || '') + this.appLocCheckPending = false + } + } + + this.shouldLogin.next(!res.isLoggedIn) + return res.isLoggedIn + }, + (err: any) => { + console.error(err) + this.shouldLogin.next(true) + return false + } + ) + .catch((e: any) => { + if (e === 403) { + console.error('Invalid host') + } + return false + }) + } + + public getLicenseSiteId(): string[] { + return this.license_site_id.value || [] + } + + public setLicenseSiteId(value: string | string[]) { + if (typeof value === 'object') { + this.license_site_id.next(value) + } else { + this.license_site_id.next([value]) + } + } + + public async checkSasjsDeploy() { + const sasjsConfig = this.getSasjsConfig() + const configuratorFolder = `${sasjsConfig.appLoc}/services/admin` + + this.sasjsService.getFolderContentsFromDrive(configuratorFolder).subscribe( + (contents: SASjsApiDriveFolderContents) => { + if (contents.files.includes('makedata.sas')) { + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + } else { + this.loadStartupServiceEmitter.emit() + + if (this.router.url.includes('deploy')) this.router.navigateByUrl('/') + } + }, + (err: any) => { + if (err.error.includes('Unauthorized')) { + this.shouldLogin.next(true) + + this.shouldLogin.subscribe((res: boolean) => { + if (res === false) location.reload() + }) + } else if (err.error.includes(`Folder doesn't exist.`)) { + console.warn( + 'SASjs SAS services are not present on the current appLoc.' + ) + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + } + } + ) + } + + // Required type is NodeJS.Timeout + // But NodeJS is not available in browser so we have to go with any + checkingInterval: any + public async sasjsMakedataChecking(): Promise { + return new Promise(async (resolve, reject) => { + this.checkingInterval = setInterval(async () => { + this.sasjsMakedataSuccessfull() + .then((success: boolean) => { + if (!!success) { + clearInterval(this.checkingInterval) + resolve(success) + } + }) + .catch((err: any) => { + clearInterval(this.checkingInterval) + reject(err) + }) + }, 1000) + }) + } + + private async sasjsMakedataSuccessfull(): Promise { + return new Promise((resolve, reject) => { + const sasjsConfig = this.getSasjsConfig() + const configuratorFolder = `${sasjsConfig.appLoc}/services/admin` + + this.sasjsService + .getFolderContentsFromDrive(configuratorFolder) + .subscribe( + (contents: SASjsApiDriveFolderContents) => { + if (!contents.files.includes('makedata.sas')) { + resolve(true) + } else { + resolve(false) + } + }, + (err: any) => { + if (err.error.includes(`Folder doesn't exist.`)) { + reject() + } + } + ) + }) + } + + public async checkViyaDeploy(path: string) { + const getFolderExistsInAdapter = + typeof this.sasjsAdapter.getFolder !== 'undefined' + + let appLocExists: boolean = false + + if (getFolderExistsInAdapter) { + appLocExists = await this.appLocCheck(path) + } else { + appLocExists = await this.appLocCheckPreAxiosdAdapter(path) + } + + if (appLocExists) { + this.loadStartupServiceEmitter.emit() + } + } + + public appLocCheck(path: string): Promise { + return new Promise(async (resolve, reject) => { + let statusNotFound: boolean = false + + let res: any + + try { + res = await this.sasjsAdapter.getFolder(path) + } catch (err: any) { + if (err.name === 'LoginRequiredError') { + this.appLocCheckPending = true + this.shouldLogin.next(true) + + resolve(false) + } else { + statusNotFound = true + } + } + + if (statusNotFound) { + console.warn('Viya services are not present on the current appLoc.') + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + return resolve(false) + } + + resolve(true) + }) + } + + /** + * This is a function written before axios adapter where we + * are getting the folder directly from DC. axios adapter + * has getFolder() function that provides the folder. + * @param path The path of the folder of which details we are getting + */ + public appLocCheckPreAxiosdAdapter(path: string): Promise { + return new Promise((resolve, reject) => { + let url = `/folders/folders/@item?path=${path}` + let statusNotFound: boolean = false + + return fetch(url) + .then((res) => { + if (res.status === 404) { + statusNotFound = true + } + + return res.text() + }) + .then((res) => { + if (this.isLoginRequired(res)) { + this.appLocCheckPending = true + this.shouldLogin.next(true) + } else { + if (statusNotFound) { + console.warn( + 'Viya services are not present on the current appLoc.' + ) + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + return resolve(false) + } + + let jsonResponse: any = null + + try { + jsonResponse = JSON.parse(res) + } catch (ex) {} + + if (jsonResponse) { + if (jsonResponse.httpStatusCode) { + if (jsonResponse.httpStatusCode === 404) { + console.warn( + 'Viya services are not present on the current appLoc.' + ) + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + return resolve(false) + } + } + } + + resolve(true) + } + }) + .catch((error: any) => { + resolve(false) + }) + }) + } + + private isLoginRequired(response: string) { + const pattern: RegExp = //gm + const matches = pattern.test(response) + return matches + } + + public logout() { + this.sasjsAdapter.logOut().then(() => { + location.reload() + }) + } + + public getSasjsConfig() { + return this.sasjsAdapter.getSasjsConfig() + } + + public getSasRequests() { + return this.sasjsAdapter.getSasRequests() + } + + public setDebugState(state: boolean) { + this.sasjsAdapter.setDebugState(state) + } + + public getSasjsInstance() { + return this.sasjsAdapter + } + + public getServerType(): string { + const sasjsConfig = this.sasjsAdapter.getSasjsConfig() + + if (sasjsConfig.serverType) { + return sasjsConfig.serverType + } + + return 'SASVIYA' + } + + public getExecutionPath() { + const sasjsConfig = this.sasjsAdapter.getSasjsConfig() + + switch (sasjsConfig.serverType) { + case ServerType.SasViya: { + return sasjsConfig.pathSASViya + } + case ServerType.Sas9: { + return sasjsConfig.pathSAS9 + } + case ServerType.Sasjs: { + return sasjsConfig.pathSASJS + } + } + } +} + +interface ErrorBody { + message: string + details: any + raw: any +} diff --git a/client/src/app/services/sasjs.service.ts b/client/src/app/services/sasjs.service.ts new file mode 100644 index 0000000..65a6646 --- /dev/null +++ b/client/src/app/services/sasjs.service.ts @@ -0,0 +1,89 @@ +import { HttpClient } from '@angular/common/http' +import { Injectable } from '@angular/core' +import { Observable } from 'rxjs' +import { + SASjsApiDriveFileTree, + SASjsApiTree +} from '../models/sasjs-api/SASjsApiDriveFileTree.model' +import { SASjsApiDriveFolderContents } from '../models/sasjs-api/SASjsApiDriveFolderContents.model' +import { SASjsApiServerInfo } from '../models/sasjs-api/SASjsApiServerInfo.model' +import { AppStoreService } from './app-store.service' + +@Injectable({ + providedIn: 'root' +}) +export class SasjsService { + private url: string = '' + private driveUrl: string = '' + + private httpOptions = { + withCredentials: true + } + + constructor( + private http: HttpClient, + private appStoreService: AppStoreService + ) {} + + setup() { + const adapterConfig = this.appStoreService.getDcAdapterSettings() + + this.url = `${adapterConfig?.serverUrl || ''}/SASjsApi` + this.driveUrl = `${this.url}/drive` + } + + getServerInfo(): Observable { + return this.http.get(`${this.url}/info`) + } + + getFileFromDrive(filePath: string) { + return this.http.get( + `${this.driveUrl}/file/?_filePath=${filePath}`, + this.httpOptions + ) + } + + getFolderContentsFromDrive( + folderPath: string + ): Observable { + return this.http.get( + `${this.driveUrl}/folder?_folderPath=${folderPath}`, + this.httpOptions + ) + } + + getFileTreeFromDrive(): Observable { + return this.http.get( + `${this.driveUrl}/filetree`, + this.httpOptions + ) + } + + getFileFromFileTree(filePath: string) { + return new Promise((resolve, reject) => { + this.getFileTreeFromDrive().subscribe( + (fileTree: SASjsApiDriveFileTree) => { + const tree = fileTree.tree + + const found = this.findInTree(tree, filePath) + + resolve(found) + } + ) + }) + } + + private findInTree(tree: SASjsApiTree, filePath: string) { + if (tree.relativePath === filePath) { + return tree + } + + for (let branch of tree.children) { + const found: any = this.findInTree(branch, filePath) + + if (found) { + return found + } + } + } +} diff --git a/client/src/app/shared/abort-modal/info-modal.component.html b/client/src/app/shared/abort-modal/info-modal.component.html new file mode 100644 index 0000000..d222bac --- /dev/null +++ b/client/src/app/shared/abort-modal/info-modal.component.html @@ -0,0 +1,69 @@ + + + + + diff --git a/client/src/app/shared/abort-modal/info-modal.component.scss b/client/src/app/shared/abort-modal/info-modal.component.scss new file mode 100644 index 0000000..3c80372 --- /dev/null +++ b/client/src/app/shared/abort-modal/info-modal.component.scss @@ -0,0 +1,43 @@ +.clr-abort-modal { + ::ng-deep { + .modal { + z-index: 2050; + } + + .modal-title-wrapper { + width: 100%; + } + + .modal { + z-index: 2050; + } + } +} + +.modal-title { + position: relative; +} + +.sasService { + position: absolute; + top: 0px; + right: 10px; + margin: 0; +} + +.modal-footer { + position: relative; + border-top: 1px solid #dcdcdc; +} + +.systext { + overflow: auto; + margin-top: 20px; + padding: 10px 0; + border-top: 1px solid #dcdcdc; + + p { + margin-top: 0; + word-wrap: break-word; + } +} \ No newline at end of file diff --git a/client/src/app/shared/abort-modal/info-modal.component.ts b/client/src/app/shared/abort-modal/info-modal.component.ts new file mode 100644 index 0000000..0cc7f53 --- /dev/null +++ b/client/src/app/shared/abort-modal/info-modal.component.ts @@ -0,0 +1,77 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import { Router } from '@angular/router' +import { ServerType } from '@sasjs/utils/types/serverType' +import { EventService } from 'src/app/services/event.service' +import { HelperService } from 'src/app/services/helper.service' +import { SasService } from 'src/app/services/sas.service' +import { AbortDetails, InfoModal } from '../../models/InfoModal' + +@Component({ + selector: 'app-info-modal', + templateUrl: './info-modal.component.html', + styleUrls: ['./info-modal.component.scss'] +}) +export class InfoModalComponent implements OnInit { + @Output() onConfirmModalClick: EventEmitter = new EventEmitter() + @Input() data: InfoModal = new InfoModal() + @Input() forceReload: boolean = false + + public modalEnabled: boolean = true + + public defaultData: InfoModal = { + modalTitle: 'Abort Message', + sasService: null, + message: '', + details: new AbortDetails() + } + + constructor( + private helperService: HelperService, + private eventService: EventService, + private sasService: SasService, + private router: Router + ) {} + + ngOnInit() { + let newData: InfoModal = { + ...this.defaultData, + ...this.data + } + + this.data = newData + } + + showConfiguratorButton(sasService: string | null) { + const sasjsConfig = this.sasService.getSasjsConfig() + + return ( + sasService?.includes('startupservice') && + sasjsConfig.serverType === ServerType.Sas9 + ) + } + + closeAbortModal() { + this.onConfirmModalClick.emit() + } + + openConfigurator() { + this.eventService.startupDataLoaded() + this.router.navigateByUrl('/deploy') + this.closeAbortModal() + } + + downloadLog() { + this.helperService.downloadTextFile( + `${this.data.sasService}-LOG`, + this.data.details?.LOG || 'Error parsing the log' + ) + } + + openRequestsModal() { + this.eventService.openRequestsModal() + } + + reload() { + location.reload() + } +} diff --git a/client/src/app/shared/alerts/alert.ts b/client/src/app/shared/alerts/alert.ts new file mode 100644 index 0000000..2bc9021 --- /dev/null +++ b/client/src/app/shared/alerts/alert.ts @@ -0,0 +1,20 @@ +interface AlertInterface { + type: string + message: string + err?: any + closed: boolean +} + +export class Alert implements AlertInterface { + public type: string + public message: string + public err: any + public closed: boolean + + constructor(type: string, message: string, err?: any) { + this.type = type + this.message = message + this.err = err + this.closed = false + } +} diff --git a/client/src/app/shared/alerts/alerts.component.html b/client/src/app/shared/alerts/alerts.component.html new file mode 100644 index 0000000..a71a021 --- /dev/null +++ b/client/src/app/shared/alerts/alerts.component.html @@ -0,0 +1,15 @@ + + +
+ + {{ alert.message }} + +
+
+
diff --git a/client/src/app/shared/alerts/alerts.component.scss b/client/src/app/shared/alerts/alerts.component.scss new file mode 100644 index 0000000..e99e00b --- /dev/null +++ b/client/src/app/shared/alerts/alerts.component.scss @@ -0,0 +1,3 @@ +clr-alerts { + display: block; +} diff --git a/client/src/app/shared/alerts/alerts.component.ts b/client/src/app/shared/alerts/alerts.component.ts new file mode 100644 index 0000000..c8a5136 --- /dev/null +++ b/client/src/app/shared/alerts/alerts.component.ts @@ -0,0 +1,34 @@ +import { Component, OnInit } from '@angular/core' +import { Subscription } from 'rxjs' +import { Alert } from './alert' +import { AlertsService } from './alerts.service' + +@Component({ + selector: 'app-alerts', + templateUrl: './alerts.component.html', + styleUrls: ['./alerts.component.scss'] +}) +export class AlertsComponent implements OnInit { + public alerts: Array = [] + public hasOpenAlert: boolean = false + + private alertsSub: Subscription = new Subscription() + + constructor(private _alertsService: AlertsService) {} + + ngOnInit() { + this.alertsSub = this._alertsService.alerts.subscribe((alert: Alert) => { + this.alerts.push(alert) + + this.hasOpenAlert = true + + if (alert.err) { + console.error(alert.err) + } + }) + } + + public onAlertClose() { + this.hasOpenAlert = this.alerts.some((alert) => !alert.closed) + } +} diff --git a/client/src/app/shared/alerts/alerts.service.ts b/client/src/app/shared/alerts/alerts.service.ts new file mode 100644 index 0000000..39bfa5c --- /dev/null +++ b/client/src/app/shared/alerts/alerts.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core' +import { Subject } from 'rxjs' + +import { Alert } from './alert' + +@Injectable() +export class AlertsService { + public alerts: Subject = new Subject() + + constructor() {} +} diff --git a/client/src/app/shared/autocomplete/autocomplete.component.html b/client/src/app/shared/autocomplete/autocomplete.component.html new file mode 100644 index 0000000..e67d4df --- /dev/null +++ b/client/src/app/shared/autocomplete/autocomplete.component.html @@ -0,0 +1,52 @@ +
+ + +
+ +
+
+ +
+ + +
+
diff --git a/client/src/app/shared/autocomplete/autocomplete.component.scss b/client/src/app/shared/autocomplete/autocomplete.component.scss new file mode 100644 index 0000000..64ba1f4 --- /dev/null +++ b/client/src/app/shared/autocomplete/autocomplete.component.scss @@ -0,0 +1,53 @@ +.input-val { + border: 0px; + background: #fbf8f8; + border-bottom: 1px solid #999999; +} + +input { + width: 100%; + outline: none; + + &::-webkit-calendar-picker-indicator { + margin-top: -5px; + } +} + +.autocomplete-wrapper { + .overlay { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: 1500; + } + + .datalist { + position: fixed; + background: white; + box-shadow: 0px 3px 10px -1px #0000002b; + overflow: auto; + z-index: 2000; + + ::ng-deep { + option { + padding: 5px 10px; + cursor: pointer; + + &:hover { + background: #0000000f; + } + + &.focused { + background: #0000000f; + } + } + } + } + + .load-more { + text-align: center; + border-top: 1px solid #e6e6e6; + } +} \ No newline at end of file diff --git a/client/src/app/shared/autocomplete/autocomplete.component.ts b/client/src/app/shared/autocomplete/autocomplete.component.ts new file mode 100644 index 0000000..362d049 --- /dev/null +++ b/client/src/app/shared/autocomplete/autocomplete.component.ts @@ -0,0 +1,306 @@ +import { + AfterViewInit, + ChangeDetectorRef, + Component, + EventEmitter, + HostListener, + Input, + OnInit, + Output, + ViewChild +} from '@angular/core' + +export type OnLoadingMoreEvent = { + loadMoreFinished: (moreExists: boolean) => void +} + +@Component({ + selector: 'app-autocomplete', + templateUrl: './autocomplete.component.html', + styleUrls: ['./autocomplete.component.scss'] +}) +export class AutocompleteComponent implements OnInit, AfterViewInit { + @ViewChild('input') inputElement: any + + @Input() inputId: string = '' + @Input() placeholder: string = '' + @Input() value: string = '' + @Input() disabled: boolean = false + @Input() type: string = 'text' + @Input() autocomplete: string = 'off' + @Input() tabindex: string = '' + @Input() emitOnlySelected: boolean = false + @Input() enableLoadMore: boolean = false + + @Output() onInputKeydown: EventEmitter = new EventEmitter() + @Output() onInputChange: EventEmitter = new EventEmitter() + @Output() valueChange: EventEmitter = new EventEmitter() + @Output() onLoadingMore: EventEmitter = new EventEmitter() + + datalistOpen: boolean = false + afterOpenLockDelay: number = 150 + afterOpenLockDelayTimeout: any + afterOpenLock: boolean = false + + inputFocused: boolean = false + inputClientRect: { + width?: number + bottom?: number + } = {} + innerHeight: number | undefined + datalistCloseTimeout: any + preventDatalistClose: boolean = false + + loadingMore: boolean = false + + constructor(private cdr: ChangeDetectorRef) {} + + ngOnInit(): void {} + + ngAfterViewInit(): void { + setTimeout(() => { + this.calculateInputPosition() + }, 500) + } + + onInputFired(event?: any, emitEvent?: boolean, initiator?: 'click') { + this.openDatalist(initiator !== 'click') + this.unselectAllOptions() + this.filterOptionsList() + + if (!this.emitOnlySelected || emitEvent) { + this.onInputChange.emit({ target: { value: this.value } }) + this.valueChange.emit(this.value) + } + } + + onInputClick(event: any) { + this.openDatalist() + } + + openDatalist(lockDelay: boolean = true) { + this.datalistOpen = true + + if (lockDelay) { + this.afterOpenLock = true + + this.afterOpenLockDelayTimeout = setTimeout(() => { + this.afterOpenLock = false + }, this.afterOpenLockDelay) + } + } + + closeDatalist() { + clearTimeout(this.afterOpenLockDelayTimeout) + this.afterOpenLock = false + this.datalistOpen = false + } + + resetDatalistFilter() { + this.filterOptionsList(true) + } + + onInputFocusin(event: any) { + this.inputFocused = true + } + + onInputFocusout(event: any) { + this.inputFocused = false + + this.setToCloseDatalist() + } + + onInputMouseenter(event: any) { + // If width not set it means calculation failed on init (input was hidden) + if (!this.inputClientRect.width) this.calculateInputPosition() + } + + filterOptionsList(showAll?: boolean) { + const options = document.querySelectorAll( + `#datalist_${this.inputId} option` + ) + + for (let i = 0; i < options.length; i++) { + const option = options[i] + + if (this.value.length === 0) { + option.classList.remove('hidden') + + continue + } + + if (showAll) { + option.classList.remove('hidden') + + continue + } + + const optionLabel = (option as any).innerText || '' + const optionValue = (option as any).value || '' + const combined = optionLabel + optionValue + + if (combined?.toLowerCase().includes(this.value.toLowerCase())) { + option.classList.remove('hidden') + } else { + option.classList.add('hidden') + } + } + } + + setToCloseDatalist() { + this.datalistCloseTimeout = setTimeout(() => { + if (this.preventDatalistClose || this.afterOpenLock) return + + this.closeDatalist() + this.unselectAllOptions() + this.resetDatalistFilter() + }, 100) + } + + calculateInputPosition() { + const inputElement = this.inputElement.nativeElement + const clientRect = inputElement?.getBoundingClientRect() + + if (clientRect.width > 0 && clientRect.height > 0) { + this.inputClientRect = { + width: clientRect.width, + bottom: clientRect.bottom + } + } + + this.innerHeight = window.innerHeight + } + + onDataListMouseEnter(event: any) { + this.preventDatalistClose = true + } + + onDataListMouseLeave(event: any) { + this.preventDatalistClose = false + this.inputElement.nativeElement.focus() + } + + onDataListScroll(event: any) { + this.setToCloseDatalist() + } + + onDataListClick(event: any) { + const clickedOption = event.target + const itemType = clickedOption.dataset?.type + + if (itemType === 'load-more') { + this.loadMore() + return + } + + if (clickedOption.tagName === 'OPTION') { + this.setOptionValue(clickedOption.innerText, clickedOption.value) + return + } + } + + loadMore() { + this.onLoadingMore.emit({ + loadMoreFinished: (moreExists: boolean) => { + this.loadingMore = false + this.enableLoadMore = moreExists + } + }) + this.loadingMore = true + } + + setOptionValue(label: string, value: string) { + if (label || value) { + if (!value) value = label + } + + if (value) { + this.preventDatalistClose = false + this.value = value + this.onInputFired(null, true, 'click') + this.setToCloseDatalist() + } + } + + onMainKeydown(event: KeyboardEvent) { + switch (event.key) { + case 'ArrowUp': { + this.getOptionsMoveFocus('up') + break + } + case 'ArrowDown': { + this.getOptionsMoveFocus('down') + break + } + case 'Enter': { + this.selectFocusedOption() + break + } + } + } + + onInputKeyup(event: any) { + if (!this.datalistOpen) { + return true + } + + // We prevent propagation of Escape event + // since it would close modal also if input is + // inside of it (or trigger any other actions that are listening on escape) + if (event.key === 'Escape') { + event.stopPropagation() + event.stopImmediatePropagation() + + this.setToCloseDatalist() + + return false + } + } + + unselectAllOptions() { + const options = document.querySelectorAll( + `#datalist_${this.inputId} option` + ) + + for (let i = 0; i < options.length; i++) { + options[i].classList.remove('focused') + } + } + + selectFocusedOption() { + const option = document.querySelector( + `#datalist_${this.inputId} option.focused` + ) + + if (option) this.onDataListClick({ target: option }) + + this.setToCloseDatalist() + } + + getOptionsMoveFocus(direction: 'up' | 'down') { + const options = document.querySelectorAll( + `#datalist_${this.inputId} option:not(.hidden)` + ) + let focusedIndex = 0 + + for (let i = 0; i < options.length; i++) { + const option = options[i] + + if (option.classList.contains('focused')) { + focusedIndex = direction === 'down' ? i + 1 : i - 1 + if (focusedIndex < 0) focusedIndex = options.length - 1 + if (focusedIndex > options.length - 1) focusedIndex = 0 + option.classList.remove('focused') + + break + } + } + + options[focusedIndex].classList.add('focused') + } + + @HostListener('window:resize', ['$event']) + onResize(event: any) { + this.calculateInputPosition() + } +} diff --git a/client/src/app/shared/autocomplete/autocomplete.module.ts b/client/src/app/shared/autocomplete/autocomplete.module.ts new file mode 100644 index 0000000..c07ac20 --- /dev/null +++ b/client/src/app/shared/autocomplete/autocomplete.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { AutocompleteComponent } from './autocomplete.component' + +@NgModule({ + declarations: [AutocompleteComponent], + imports: [CommonModule, ClarityModule, CommonModule, FormsModule], + exports: [AutocompleteComponent] +}) +export class AutocompleteModule {} diff --git a/client/src/app/shared/contact-link/contact-link.component.html b/client/src/app/shared/contact-link/contact-link.component.html new file mode 100644 index 0000000..a572894 --- /dev/null +++ b/client/src/app/shared/contact-link/contact-link.component.html @@ -0,0 +1,6 @@ +support@datacontroller.io diff --git a/client/src/app/shared/contact-link/contact-link.component.scss b/client/src/app/shared/contact-link/contact-link.component.scss new file mode 100644 index 0000000..50bcc2f --- /dev/null +++ b/client/src/app/shared/contact-link/contact-link.component.scss @@ -0,0 +1,3 @@ +.unset { + color: unset; +} \ No newline at end of file diff --git a/client/src/app/shared/contact-link/contact-link.component.ts b/client/src/app/shared/contact-link/contact-link.component.ts new file mode 100644 index 0000000..9366b44 --- /dev/null +++ b/client/src/app/shared/contact-link/contact-link.component.ts @@ -0,0 +1,14 @@ +import { Component, Input, OnInit } from '@angular/core' + +@Component({ + selector: 'contact-link', + templateUrl: './contact-link.component.html', + styleUrls: ['./contact-link.component.scss'] +}) +export class ContactLinkComponent implements OnInit { + @Input() classes: string = '' + + constructor() {} + + ngOnInit(): void {} +} diff --git a/client/src/app/shared/dataset-info/dataset-info.component.html b/client/src/app/shared/dataset-info/dataset-info.component.html new file mode 100644 index 0000000..1dbd076 --- /dev/null +++ b/client/src/app/shared/dataset-info/dataset-info.component.html @@ -0,0 +1,43 @@ + + + + + diff --git a/client/src/app/shared/dataset-info/dataset-info.component.scss b/client/src/app/shared/dataset-info/dataset-info.component.scss new file mode 100644 index 0000000..ab05241 --- /dev/null +++ b/client/src/app/shared/dataset-info/dataset-info.component.scss @@ -0,0 +1,16 @@ +.modal-body { + clr-tabs { + max-height: 70vh; + } + + ::ng-deep { + .tab-content { + width: 100%; + overflow: auto; + + .datagrid-outer-wrapper { + width: 100%; + } + } + } +} \ No newline at end of file diff --git a/client/src/app/shared/dataset-info/dataset-info.component.ts b/client/src/app/shared/dataset-info/dataset-info.component.ts new file mode 100644 index 0000000..9b87ca9 --- /dev/null +++ b/client/src/app/shared/dataset-info/dataset-info.component.ts @@ -0,0 +1,63 @@ +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges +} from '@angular/core' +import { DSMeta } from 'src/app/models/sas/editors-getdata.model' +import { DSMetaGroupped } from './models/dsmeta-groupped.model' + +@Component({ + selector: 'app-dataset-info', + templateUrl: './dataset-info.component.html', + styleUrls: ['./dataset-info.component.scss'] +}) +export class DatasetInfoComponent implements OnInit, OnChanges { + @Input() open: boolean = false + @Input() dsmeta: DSMeta[] = [] + + @Output() openChange = new EventEmitter() + + dsmetaGroupped: DSMetaGroupped[] = [] + + constructor() {} + + ngOnInit(): void {} + + ngOnChanges(changes: SimpleChanges): void { + if (changes.dsmeta?.currentValue?.length > 0) { + this.parseDSMeta() + } + } + + parseDSMeta() { + this.dsmetaGroupped = [] + + for (let info of this.dsmeta) { + let groupIndex = this.dsmetaGroupped.findIndex( + (x) => x.group === info.ODS_TABLE + ) + + if (groupIndex < 0) + groupIndex = + this.dsmetaGroupped.push({ + group: info.ODS_TABLE, + dsmeta: [] + }) - 1 + + this.dsmetaGroupped[groupIndex].dsmeta.push(info) + } + } + + onOpenChange(open: boolean) { + this.open = open + this.openChange.emit(open) + } + + onCloseClick() { + this.onOpenChange(false) + } +} diff --git a/client/src/app/shared/dataset-info/models/dsmeta-groupped.model.ts b/client/src/app/shared/dataset-info/models/dsmeta-groupped.model.ts new file mode 100644 index 0000000..3b545a8 --- /dev/null +++ b/client/src/app/shared/dataset-info/models/dsmeta-groupped.model.ts @@ -0,0 +1,6 @@ +import { DSMeta } from 'src/app/models/sas/editors-getdata.model' + +export interface DSMetaGroupped { + group: string + dsmeta: DSMeta[] +} diff --git a/client/src/app/shared/dc-tree/dc-tree.component.html b/client/src/app/shared/dc-tree/dc-tree.component.html new file mode 100644 index 0000000..3fd5145 --- /dev/null +++ b/client/src/app/shared/dc-tree/dc-tree.component.html @@ -0,0 +1,161 @@ + + +
+ + + +
+
+ + + +

+ + {{ library.LIBRARYNAME }} +

+ + +
+ + + +
+
+ + + + + + + + To unlock all tables, contact support@datacontroller.io + + + + + +
+ + + +
+
+ + + + +
+
+
+
+
+
+ +
+ Loading... +
diff --git a/client/src/app/shared/dc-tree/dc-tree.component.scss b/client/src/app/shared/dc-tree/dc-tree.component.scss new file mode 100644 index 0000000..b5e368f --- /dev/null +++ b/client/src/app/shared/dc-tree/dc-tree.component.scss @@ -0,0 +1,17 @@ +clr-tree-node button { + white-space: nowrap; +} + +clr-tree { + ::ng-deep { + .clr-tree-node-content-container { + &:focus { + .clr-treenode-link { + background: #e8e8e8; + background: var(--clr-tree-link-hover-color, #e8e8e8); + text-decoration: none; + } + } + } + } +} \ No newline at end of file diff --git a/client/src/app/shared/dc-tree/dc-tree.component.ts b/client/src/app/shared/dc-tree/dc-tree.component.ts new file mode 100644 index 0000000..b1769fb --- /dev/null +++ b/client/src/app/shared/dc-tree/dc-tree.component.ts @@ -0,0 +1,226 @@ +import { + AfterViewInit, + Component, + EventEmitter, + HostListener, + Input, + OnChanges, + OnInit, + Output, + QueryList, + SimpleChanges, + ViewChildren +} from '@angular/core' +import { HelperService } from 'src/app/services/helper.service' +import { LicenceService } from 'src/app/services/licence.service' +import { globals } from 'src/app/_globals' +import { LibraryClickEmitter } from './models/LibraryClickEmitter' +import { TableClickEmitter } from './models/TableClickEmitter' + +@Component({ + selector: 'dc-tree', + templateUrl: './dc-tree.component.html', + styleUrls: ['./dc-tree.component.scss'] +}) +export class DcTreeComponent implements OnInit, AfterViewInit, OnChanges { + // REFACTOR NOTICE + // This component ideally should be used in whole app instead of `clr-tree` being copied again in every component + + @ViewChildren('searchLibTreeInput') + searchLibInputList: QueryList = new QueryList() + + @Output() tableOnClickEmitter = new EventEmitter() + @Output() libraryOnClickEmitter = new EventEmitter() + + @Input() hasColumns: boolean = false + @Input() paging: boolean = true + @Input() libraryList: any[] | undefined + public librariesSearch: string = '' + + public lib: any = '' + public table: any = '' + public column: string | undefined + + public librariesPaging: boolean = false + + public licenceState = this.licenceService.licenceState + + constructor( + private helperService: HelperService, + private licenceService: LicenceService + ) {} + + ngOnInit(): void {} + + ngAfterViewInit(): void { + setTimeout(() => { + this.searchLibInputList.first.nativeElement.focus() + }) + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.libraryList?.currentValue) { + if (this.libraryList) { + this.helperService.displayLibraries(this.libraryList) + } + } + } + + treeOnFilter(array: any, arrToFilter: string) { + this.helperService.treeOnFilter(array, arrToFilter) + } + + libraryOnFilter() { + this.helperService.libraryOnFilter( + this.libraryList, + this.librariesSearch, + 'LIBRARYNAME' + ) + + globals.lineage.librariesSearch = this.librariesSearch + } + + treeNodeClicked(event: any, item: any, tree: any) { + if (event.target.title === 'Collapse') { + this.collapseTreeItems(tree, item) + } + } + + libraryOnClick(libid: string, library: any, libTreeNode: any) { + library['inForeground'] = true //When we programatically call this function, we make sure it is visible in the sidebar + + const focusTableSearch = () => + setTimeout(() => + libTreeNode.contentContainer.nativeElement.parentElement + .querySelector('input') + .focus() + ) + + if (!library['tables']) { + library['loadingTables'] = true + + this.libraryOnClickEmitter.emit({ libid, library, tablesLoaded: false }) + + const interval = setInterval(() => { + if (!library['loadingTables']) { + focusTableSearch() + + clearInterval(interval) + } + }, 500) + } else { + library['expanded'] = !library['expanded'] + + this.libraryOnClickEmitter.emit({ libid, library, tablesLoaded: true }) + } + + if (library['expanded']) { + focusTableSearch() + } + + this.collapseTreeItems(this.libraryList, library) + } + + public async tableOnClick(tableuri: string, libTable: any, library: any) { + this.helperService.debounceCall(50, () => { + if (!this.hasColumns) { + this.tableOnClickEmitter.emit({ + tableuri, + libTable, + library, + columnsLoaded: false + }) + + return + } + + if (!libTable['columns']) { + libTable['expanded'] = !libTable['expanded'] + libTable['loadingColumns'] = true + this.table = tableuri + + this.tableOnClickEmitter.emit({ + tableuri, + libTable, + library, + columnsLoaded: false + }) + } else { + libTable['expanded'] = !libTable['expanded'] + + if (libTable['expanded'] === true) { + this.table = tableuri + + this.tableOnClickEmitter.emit({ + tableuri, + libTable, + library, + columnsLoaded: true + }) + } + } + + this.collapseTreeItems(library['tables'], libTable) + }) + } + + columnOnClick(libColumn: any, library: any, libTable: any) { + this.lib = library.LIBRARYID + this.table = libTable.TABLEURI + this.column = libColumn.COLURI + } + + public libTabActive(library: string, table: string) { + if (!this.lib || !this.table) { + return false + } + + return library === this.lib && table === this.table + } + + public libColumnActive(libColumnUri: string) { + if (!this.column) { + return false + } + + let splitedLibColumnUri = libColumnUri.split('\\') + let splitedColumnUri = this.column.split('\\') + + return ( + splitedLibColumnUri[splitedLibColumnUri.length - 1] == + splitedColumnUri[splitedColumnUri.length - 1] + ) + } + + public collapseTreeItems(tree: any, itemToSkip: any) { + tree.forEach((item: any) => { + if (JSON.stringify(item) !== JSON.stringify(itemToSkip)) { + item['expanded'] = false + } + }) + } + + public loadMoreLibraries() { + if (!this.librariesPaging) { + this.librariesPaging = true + + this.helperService.displayLibraries(this.libraryList, true) + this.librariesPaging = false + } + } + + @HostListener('scroll', ['$event']) + handleScroll(event: Event) { + let element = event.target as HTMLElement + + if (element) { + // When list scrolled to the bottom, load more libraries + if ( + element.scrollTop >= + element.scrollHeight - element.offsetHeight - 10 + ) { + this.loadMoreLibraries() + } + } + } +} diff --git a/client/src/app/shared/dc-tree/dc-tree.module.ts b/client/src/app/shared/dc-tree/dc-tree.module.ts new file mode 100644 index 0000000..655ebd4 --- /dev/null +++ b/client/src/app/shared/dc-tree/dc-tree.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { DcTreeComponent } from './dc-tree.component' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { DirectivesModule } from 'src/app/directives/directives.module' + +@NgModule({ + declarations: [DcTreeComponent], + imports: [ + CommonModule, + ClarityModule, + CommonModule, + FormsModule, + DirectivesModule + ], + exports: [DcTreeComponent] +}) +export class DcTreeModule {} diff --git a/client/src/app/shared/dc-tree/models/LibraryClickEmitter.ts b/client/src/app/shared/dc-tree/models/LibraryClickEmitter.ts new file mode 100644 index 0000000..a99dcc0 --- /dev/null +++ b/client/src/app/shared/dc-tree/models/LibraryClickEmitter.ts @@ -0,0 +1,7 @@ +import { Saslibs } from 'src/app/models/sas/public-viewlibs.model' + +export interface LibraryClickEmitter { + libid: string + library: Saslibs + tablesLoaded: boolean +} diff --git a/client/src/app/shared/dc-tree/models/TableClickEmitter.ts b/client/src/app/shared/dc-tree/models/TableClickEmitter.ts new file mode 100644 index 0000000..7a22d9f --- /dev/null +++ b/client/src/app/shared/dc-tree/models/TableClickEmitter.ts @@ -0,0 +1,8 @@ +import { Saslibs } from 'src/app/models/sas/public-viewlibs.model' + +export interface TableClickEmitter { + tableuri: string + libTable: string + columnsLoaded: boolean + library: Saslibs +} diff --git a/client/src/app/shared/dc-validator/dc-validator.ts b/client/src/app/shared/dc-validator/dc-validator.ts new file mode 100644 index 0000000..7f04abf --- /dev/null +++ b/client/src/app/shared/dc-validator/dc-validator.ts @@ -0,0 +1,461 @@ +import { isSpecialMissing } from '@sasjs/utils/input/validators' +import Handsontable from 'handsontable' +import { CellProperties } from 'handsontable/settings' +import { + autocompleteValidator, + dateValidator, + timeValidator +} from 'handsontable/validators' +import { $DataFormats } from 'src/app/models/sas/editors-getdata.model' +import { DQData, SASParam } from '../../models/TableData' +import { Col } from './models/col.model' +import { + DcValidation, + DcValidationRuleUpdate +} from './models/dc-validation.model' +import { DQRule, DQRuleTypes } from './models/dq-rules.model' +import { getDqDataCols } from './utils/getDqDataCols' +import { mergeColsRules } from './utils/mergeColsRules' +import { parseColType } from './utils/parseColType' +import { dqValidate } from './validations/dq-validation' +import { specialMissingNumericValidator } from './validations/hot-custom-validators' + +export class DcValidator { + private rules: DcValidation[] = [] + private dqrules: DQRule[] = [] + private dqdata: DQData[] = [] + private sasparams: SASParam | undefined + private hiddenColumns: number[] = [] + private primaryKeys: string[] = [] + private hotInstance: Handsontable | undefined + + constructor( + sasparams: SASParam, + $dataFormats: $DataFormats, + cols: Col[], + dqRules: DQRule[], + dqData: DQData[], + hotInstance?: Handsontable + ) { + this.sasparams = sasparams + this.hotInstance = hotInstance + this.rules = parseColType(sasparams.COLTYPE) + this.rules = mergeColsRules(cols, this.rules, $dataFormats) + this.dqrules = dqRules + this.dqdata = dqData + this.primaryKeys = sasparams.PK.split(' ') + + this.updateDqData() + this.setupValidations() + } + + getRules(): DcValidation[] { + return this.rules + } + + getRule(selector: string | number): DcValidation | undefined { + const index = this.getRuleIndex(selector) + + return this.rules[index] + } + + getHiddenColumns(): number[] { + return this.hiddenColumns + } + + updateRule(selector: string | number, value: DcValidationRuleUpdate) { + let index = this.getRuleIndex(selector) + + this.rules[index] = { + ...this.rules[index], + ...value + } + } + + removeRule(selector: string | number) { + const index = this.getRuleIndex(selector) + + this.rules.splice(index, 1) + } + + /** + * DQ Rules values comes from MPE_VALIDATIONS table + * @param col column name (optional) - if not provided all DQ Rules will be returned + * @returns array of DQRUles for given col name + */ + getDqDetails(col?: string): DQRule[] { + if (!col) return this.dqrules + + return this.dqrules.filter((dqrule: DQRule) => dqrule.BASE_COL === col) + } + + /** + * Checks if given column is or is not included in the current DATA QUALITY rules + * + * @param col column name + */ + isDqCol(col: string): boolean { + // My refactored solution + return !!this.dqrules.find((dqrule: DQRule) => dqrule.BASE_COL === col) + } + + /** + * Checks if the given column has the provided dqrules + * @param dqrules returns true if any of provided rules match + */ + hasDqRules( + col: string, + dqrules: DQRuleTypes[], + matchAll: boolean = false + ): boolean { + if (matchAll) { + return ( + this.dqrules.filter( + (x) => x.BASE_COL === col && dqrules.includes(x.RULE_TYPE) + ).length === dqrules.length + ) + } else { + return !!this.dqrules.find( + (x) => x.BASE_COL === col && dqrules.includes(x.RULE_TYPE) + ) + } + } + + /** + * Retrieves dropdown source for given dc validation rule + * The values comes from MPE_SELECTBOX table + * @param rule + */ + getDqDropdownSource(rule: DcValidation): string[] | number[] { + let details: any[] = [] + + this.dqrules.forEach((element: DQRule) => { + if ( + element.BASE_COL.toString() === rule.data && + rule.data.toString() && + [ + 'HARDSELECT', + 'SOFTSELECT', + 'HARDSELECT_HOOK', + 'SOFTSELECT_HOOK' + ].includes(element.RULE_TYPE.toString()) + ) { + this.dqdata + .filter((dqdata: DQData) => dqdata.BASE_COL === element.BASE_COL) + .forEach((data: any) => { + /** + * If column type is numeric, we want to populate dropdown with numeric array + * So we will convert it before pushing to array. + */ + if (rule.type && rule.type === 'numeric') { + details.push(Number(data['RULE_DATA'])) + } else { + details.push(data['RULE_DATA']) + } + }) + } + }) + + return details + } + + /** + * SOFTSELECT is not defined in DQ RULES + * This function fetches it's values and pushes in the DQ RULES array with SOFTSELECT type + * Those values are used also for HARDSELECT, only difference is HARDSELECT has strict=true + */ + updateDqData() { + if (this.dqdata.length > 0) { + let dqDataCols: string[] = getDqDataCols(this.dqdata) + + dqDataCols.forEach((dqCol: string) => { + let rulePresent = false + + if (this.dqrules.length > 0) { + this.dqrules.forEach((dqRule: DQRule) => { + if ( + dqRule.BASE_COL === dqCol && + (dqRule.RULE_TYPE === 'SOFTSELECT' || + dqRule.RULE_TYPE === 'HARDSELECT') + ) { + rulePresent = true + } + }) + } + + if (!rulePresent) { + this.dqrules.push({ + BASE_COL: dqCol, + RULE_TYPE: 'SOFTSELECT', + RULE_VALUE: dqCol, + X: 1 + }) + } + }) + } + } + + /** + * It will execute validator, by creating the dummy instance of HOT + * because validator function requires it in it's context + * We need this function to be able to REUSE the validation that is done in HOT + * For exmaple in EDIT RECROD MODAL + * @param columnRules column rule for which to run validation + * @param value value against which validation is done + * @param callback true if valid - false if invalid + */ + executeHotValidator = ( + columnRules: DcValidation, + value: any, + callback?: (valid: boolean) => void + ) => { + const cellProperties: CellProperties = { + ...columnRules, + validator: undefined, + correctFormat: false, + row: 0, + col: 0, + instance: new Handsontable(document.createElement('div'), {}), + visualRow: 0, + visualCol: 0, + prop: 0 + } + + if (value === undefined || value === null) value = '' + + if ( + !columnRules || + !columnRules.validator || + typeof columnRules.validator !== 'function' + ) { + if (callback) callback(false) + return + } + + columnRules.validator.call(cellProperties, value, (valid: boolean) => { + if (callback) callback(valid) + }) + } + + /** + * It will populate columns dropdowns for which data is found + * Also validator for every column is assigned + */ + private setupValidations() { + for (let i = 0; i < this.rules.length; i++) { + const ruleColName = this.rules[i].data || '' + + if (ruleColName === '_____DELETE__THIS__RECORD_____') { + continue + } + + /** + * Populate dropdowns SOFTSELECT, HARDSELECT + */ + if (this.isDqCol(ruleColName)) { + let source: string[] | number[] = this.getDqDropdownSource( + this.rules[i] + ) + + if (source.length > 0) { + this.rules[i].source = source + this.rules[i].type = 'autocomplete' + this.rules[i].filter = false + } + + if (this.hasDqRules(ruleColName, ['SOFTSELECT'])) { + this.rules[i].strict = false + } + + if (this.hasDqRules(ruleColName, ['HARDSELECT'])) { + this.rules[i].strict = true + } + + if (this.hasDqRules(ruleColName, ['SOFTSELECT_HOOK'])) { + this.rules[i].strict = false + } + + if (this.hasDqRules(ruleColName, ['HARDSELECT_HOOK'])) { + this.rules[i].strict = true + } + + if (this.hasDqRules(ruleColName, ['NOTNULL'])) { + this.rules[i].allowEmpty = false + } + } + + // Correct format comes as STRING from SAS. That could be also fixed on SAS side. + if ((this.rules[i].correctFormat as any) === 'true') { + this.rules[i].correctFormat = true + } + + const self = this + + this.setDefaultValidator(self, i) + this.setColumnLevelSecurity(i) + } + + // If CLS is true, we hide `delete column` + if (this.sasparams?.CLS_FLAG) this.hiddenColumns.push(0) + } + + private setDefaultValidator(self: any, i: number) { + this.rules[i].validator = function ( + value: any, + callback: (valid: boolean) => void + ) { + const col = self.rules[i].data?.toString() + const colType = self.rules[i].type || '' + let handsontableValid = null + + // We call handsontable predefined validators, if it returns false, we validate as FALSE + // If return is true, we validate with our custom DQ validations + + // Because of dynamic cell validation, that will change the type of cell to dropdown + // `rules[i].colType` could be different type (eg. numeric). So we check if current cell is dropdown, to call HOT native dropdown validator + if (this.editor === 'autocomplete') { + self + .getHandsontableValidator('autocomplete') + .call(this, value, (valid: boolean) => { + handsontableValid = valid + }) + + if (!handsontableValid) { + console.warn( + `HOT Native Validation (autocomplete) - invalid (Value: ${value})` + ) + callback(false) + return + } + } + + // Now the regular type native HOT validation + self + .getHandsontableValidator(colType) + .call(this, value, (valid: boolean) => { + handsontableValid = valid + }) + + if (!handsontableValid) { + console.warn(`HOT Native Validation - invalid (Value: ${value})`) + callback(false) + return + } + + if (!self.lengthCheck(value, self.rules[i].length, colType)) { + console.warn(`Length Validation - invalid (Value: ${value})`) + callback(false) + return + } + + if (self.isDqCol(col || '')) { + const dqValid = dqValidate(self.getDqDetails(col || ''), value) + + if (!dqValid) { + console.warn(`DQ Validation - invalid (Value: ${value})`) + callback(false) + return + } + } + + callback(true) + } + } + + // Validation for length or for size in bytes if col type is numeric + // True means valid + private lengthCheck( + value: any, + ruleLength: number, + colType: string + ): boolean { + if (isSpecialMissing(value)) return true + if (value === undefined || value === null) return true + if (ruleLength === undefined || ruleLength === null) return true + + switch (colType) { + case 'numeric': { + if (ruleLength === 8) return true + + if (ruleLength < 3 || ruleLength > 8) { + console.warn( + 'invalid length from SAS, rule length can only be an integer between 3-8' + ) + return false + } + + if (!Number.isInteger(ruleLength)) { + console.warn( + 'invalid length from SAS, rule length can only be an integer between 3-8' + ) + return false + } + + const isFloat = Number(value) === value && value % 1 !== 0 + if (ruleLength < 8 && isFloat) { + console.warn( + 'reduced length numerics cannot contain decimals else precision will be affected' + ) + return false + } + + // values for following cases are taken from https://v8doc.sas.com/sashtml/win/numvar.htm + switch (ruleLength) { + case 3: + return value <= 8192 // 2^13 + case 4: + return value <= 2097152 // 2^21 + case 5: + return value <= 536870912 // 2^29 + case 6: + return value <= 137438953472 // 2^37 + case 7: + return value <= 35184372088832 // 2^45 + } + } + default: { + return value.toString().length <= ruleLength + } + } + } + + private getHandsontableValidator(type: string) { + switch (type) { + case 'autocomplete': + return autocompleteValidator + case 'numeric': + return specialMissingNumericValidator + case 'date': + return dateValidator + case 'time': + return timeValidator + default: + return (value: any, callback: any) => (callback ? callback(true) : null) + } + } + + private getRuleIndex(col: string | number): number { + if (typeof col === 'number') return col + + return this.rules.findIndex((rule: DcValidation) => rule.data === col) + } + + private setColumnLevelSecurity(index: number) { + if (!this.sasparams?.CLS_FLAG) return + + const rule = this.rules[index] + + // Primary Key variables must always be visible and read-only + if (this.primaryKeys.includes(rule.data)) rule.clsRule = 'READ' + + if (rule.clsRule === 'HIDE') this.hiddenColumns.push(index) + + if (rule.clsRule === 'READ') rule.readOnly = true + + if (rule.clsRule === 'EDIT') { + rule.readOnly = false + const hiddenIndex = this.hiddenColumns.indexOf(index) + this.hiddenColumns.splice(hiddenIndex, 1) + } + } +} diff --git a/client/src/app/shared/dc-validator/models/col.model.ts b/client/src/app/shared/dc-validator/models/col.model.ts new file mode 100644 index 0000000..6f4c7a1 --- /dev/null +++ b/client/src/app/shared/dc-validator/models/col.model.ts @@ -0,0 +1,12 @@ +export interface Col { + NAME: string + VARNUM: number + LABEL: string + FMTNAME: string + DDTYPE: string + TYPE: string + CLS_RULE: string + MEMLABEL: string + DESC: string + LONGDESC: string +} diff --git a/client/src/app/shared/dc-validator/models/dc-validation.model.ts b/client/src/app/shared/dc-validator/models/dc-validation.model.ts new file mode 100644 index 0000000..797c364 --- /dev/null +++ b/client/src/app/shared/dc-validator/models/dc-validation.model.ts @@ -0,0 +1,21 @@ +import Handsontable from 'handsontable' + +export interface HotColumnSettings extends Handsontable.ColumnSettings { + data: string +} + +export interface DcColumnSettings { + length?: number + format?: number + valid?: boolean + desc?: string + clsRule?: string +} + +export interface DcValidation extends HotColumnSettings, DcColumnSettings {} + +export interface DcValidationRuleUpdate + extends Handsontable.ColumnSettings, + DcColumnSettings { + data?: string +} diff --git a/client/src/app/shared/dc-validator/models/dq-rules.model.ts b/client/src/app/shared/dc-validator/models/dq-rules.model.ts new file mode 100644 index 0000000..deb380d --- /dev/null +++ b/client/src/app/shared/dc-validator/models/dq-rules.model.ts @@ -0,0 +1,16 @@ +export interface DQRule { + BASE_COL: string + RULE_TYPE: DQRuleTypes + RULE_VALUE: string + X: number +} + +export type DQRuleTypes = + | 'SOFTSELECT' + | 'HARDSELECT' + | 'SOFTSELECT_HOOK' + | 'HARDSELECT_HOOK' + | 'NOTNULL' + | 'CASE' + | 'MINVAL' + | 'MAXVAL' diff --git a/client/src/app/shared/dc-validator/tests/dc-validator.spec.ts b/client/src/app/shared/dc-validator/tests/dc-validator.spec.ts new file mode 100644 index 0000000..56d24ff --- /dev/null +++ b/client/src/app/shared/dc-validator/tests/dc-validator.spec.ts @@ -0,0 +1,486 @@ +import { $DataFormats } from 'src/app/models/sas/editors-getdata.model' +import { DQData, SASParam } from 'src/app/models/TableData' +import { DcValidator } from '../dc-validator' +import { Col } from '../models/col.model' +import { DQRule } from '../models/dq-rules.model' + +describe('DC Validator', () => { + it('should create an instance of validator with correct rules', () => { + const sasparams: SASParam = example_sasparams + const cols: Col[] = example_cols + const dqRules: DQRule[] = example_dqRules + const dqData: DQData[] = example_dqData + const $dataFormats: $DataFormats = example_dataformats + + const dcValidator: DcValidator = new DcValidator( + sasparams, + $dataFormats, + cols, + dqRules, + dqData + ) + + // Check if COLS merged with FORMATS + expect(cols[0].TYPE).toEqual('char') + + // Get all + const validationRules = dcValidator.getRules() + expect(validationRules).toHaveSize( + JSON.parse(`[${example_COLTYPE}]`).length + ) + + // Get col with notnull validation + const someNumRule = dcValidator.getRule('SOME_NUM') + // Check allowEmpty - it is notnull rule so allowEmpty should be false + expect(someNumRule?.allowEmpty).toBeFalse() + + // Get col with notnull validation + const someDateRule = dcValidator.getRule('SOME_DATE') + // Check correctFormat - it comes from SAS - should be true + expect(someDateRule?.correctFormat).toBeTrue() + + // Get col with dropdown, check if merging sas data is correct + const someDropdownRule = dcValidator.getRule('SOME_DROPDOWN') + // Check source + expect(someDropdownRule?.source).toHaveSize(4) + // Check description + expect(someDropdownRule?.desc).toEqual('dropdown_desc') + // Check length + expect(someDropdownRule?.length).toEqual(128) + // Check strict - it is softselect so strict should be false + expect(someDropdownRule?.strict).toBeFalse() + + // Get col with dropdown with 'HARDSELECT' rule + const someDropdownHardRule = dcValidator.getRule('SOME_DROPDOWN_HARD') + // Check strict - it is hardselect so strict should be true + expect(someDropdownHardRule?.strict).toBeTrue() + }) + + it('should create an instance of validator and execute its functions', () => { + const sasparams: SASParam = example_sasparams + const cols: Col[] = example_cols + const dqRules: DQRule[] = example_dqRules + const dqData: DQData[] = example_dqData + const $dataFormats: $DataFormats = example_dataformats + + const dcValidator: DcValidator = new DcValidator( + sasparams, + $dataFormats, + cols, + dqRules, + dqData + ) + + // Get one + const someNumRules = dcValidator.getRule('SOME_NUM') + expect(someNumRules?.data).toEqual('SOME_NUM') + + // Update one + dcValidator.updateRule('SOME_NUM', { desc: 'updated_desc' }) + const someNumUpdated = dcValidator.getRule('SOME_NUM') + expect(someNumUpdated?.desc).toEqual('updated_desc') + + // Remove one + dcValidator.removeRule('SOME_TIME') + expect(dcValidator.getRule('SOME_TIME')).toBeUndefined() + + // Test data quality functions + expect(dcValidator.getDqDetails()).toHaveSize(dqRules.length) + expect(dcValidator.getDqDetails('non_existant')).toHaveSize(0) + expect(dcValidator.getDqDetails('SOME_NUM')).toHaveSize(2) + expect(dcValidator.isDqCol('SOME_NUM')).toBeTrue() + expect(dcValidator.isDqCol('non_existant')).toBeFalse() + expect( + dcValidator.getDqDropdownSource(dcValidator.getRule('SOME_DROPDOWN')!) + ).toEqual([ + 'Option 1', + 'Option 2', + 'Option 3', + 'This is a long option. This option is very long. It is optional, though.' + ]) + }) + + it('should test hot validator', () => { + const sasparams: SASParam = example_sasparams + const cols: Col[] = example_cols + const dqRules: DQRule[] = example_dqRules + const dqData: DQData[] = example_dqData + const $dataFormats: $DataFormats = example_dataformats + + const dcValidator: DcValidator = new DcValidator( + sasparams, + $dataFormats, + cols, + dqRules, + dqData + ) + + // NOTNULL Validation + const someNumRule = dcValidator.getRule('SOME_NUM') + + dcValidator.executeHotValidator(someNumRule!, 2, (valid: boolean) => { + expect(valid).toBeTrue() + }) + dcValidator.executeHotValidator(someNumRule!, null, (valid: boolean) => { + expect(valid).toBeFalse() + }) + dcValidator.executeHotValidator(someNumRule!, '', (valid: boolean) => { + expect(valid).toBeFalse() + }) + dcValidator.executeHotValidator(someNumRule!, 'ss', (valid: boolean) => { + expect(valid).toBeFalse() + }) + //Special missings + dcValidator.executeHotValidator(someNumRule!, 's', (valid: boolean) => { + expect(valid).toBeTrue() + }) + dcValidator.executeHotValidator(someNumRule!, '.s', (valid: boolean) => { + expect(valid).toBeTrue() + }) + dcValidator.executeHotValidator(someNumRule!, '.', (valid: boolean) => { + expect(valid).toBeTrue() + }) + dcValidator.executeHotValidator(someNumRule!, '..', (valid: boolean) => { + expect(valid).toBeFalse() + }) + dcValidator.executeHotValidator(someNumRule!, '._', (valid: boolean) => { + expect(valid).toBeTrue() + }) + + // MINVAL, MAXVAL Validation + const shortNumRule = dcValidator.getRule('SOME_SHORTNUM') + + dcValidator.executeHotValidator(shortNumRule!, 2, (valid: boolean) => { + expect(valid).toBeTrue() + }) + dcValidator.executeHotValidator(shortNumRule!, 1, (valid: boolean) => { + expect(valid).toBeFalse() + }) + dcValidator.executeHotValidator(shortNumRule!, 4, (valid: boolean) => { + expect(valid).toBeFalse() + }) + dcValidator.executeHotValidator(shortNumRule!, 's', (valid: boolean) => { + expect(valid).toBeFalse() // Special missings are lowest numbers, if any MINVAL is set, special missing is always lower + }) + + // CASE validation + const someCharRule = dcValidator.getRule('SOME_CHAR') + + dcValidator.executeHotValidator( + someCharRule!, + 'UPPER', + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + dcValidator.executeHotValidator( + someCharRule!, + 'lower', + (valid: boolean) => { + expect(valid).toBeFalse() + } + ) + dcValidator.executeHotValidator( + someCharRule!, + undefined, + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + dcValidator.executeHotValidator(someCharRule!, null, (valid: boolean) => { + expect(valid).toBeTrue() + }) + + const someCharLowRule = dcValidator.getRule('SOME_CHAR_LOW') + + dcValidator.executeHotValidator( + someCharLowRule!, + 'lower', + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + + dcValidator.executeHotValidator( + someCharLowRule!, + 'UPPER', + (valid: boolean) => { + expect(valid).toBeFalse() + } + ) + + const someCharAnyRule = dcValidator.getRule('SOME_CHAR_ANY') + + dcValidator.executeHotValidator( + someCharAnyRule!, + 'any', + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + + dcValidator.executeHotValidator( + someCharAnyRule!, + null, + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + + dcValidator.executeHotValidator( + someCharAnyRule!, + undefined, + (valid: boolean) => { + expect(valid).toBeTrue() + } + ) + }) +}) + +const example_dqData = [ + { + BASE_COL: 'SOME_DROPDOWN', + RULE_VALUE: 'SOME_DROPDOWN', + RULE_DATA: 'Option 1', + SELECTBOX_ORDER: 1 + }, + { + BASE_COL: 'SOME_DROPDOWN', + RULE_VALUE: 'SOME_DROPDOWN', + RULE_DATA: 'Option 2', + SELECTBOX_ORDER: 2 + }, + { + BASE_COL: 'SOME_DROPDOWN', + RULE_VALUE: 'SOME_DROPDOWN', + RULE_DATA: 'Option 3', + SELECTBOX_ORDER: 2 + }, + { + BASE_COL: 'SOME_DROPDOWN', + RULE_VALUE: 'SOME_DROPDOWN', + RULE_DATA: + 'This is a long option. This option is very long. It is optional, though.', + SELECTBOX_ORDER: 3 + } +] + +const example_dqRules: any = [ + { + BASE_COL: 'SOME_NUM', + RULE_TYPE: 'NOTNULL', + RULE_VALUE: ' ', + X: 0 + }, + { + BASE_COL: 'SOME_NUM', + RULE_TYPE: 'HARDSELECT_HOOK', + RULE_VALUE: 'services/validations/mpe_x_test.some_num', + X: 0 + }, + { + BASE_COL: 'SOME_SHORTNUM', + RULE_TYPE: 'MINVAL', + RULE_VALUE: '2', + X: 0 + }, + { + BASE_COL: 'SOME_DROPDOWN_HARD', // It contains both HARD and SOFTSELECT rules, HARDSELECT has the priority + RULE_TYPE: 'HARDSELECT', + RULE_VALUE: ' ', + X: 0 + }, + { + BASE_COL: 'SOME_DROPDOWN_HARD', // It contains both HARD and SOFTSELECT rules, HARDSELECT has the priority + RULE_TYPE: 'SOFTSELECT', + RULE_VALUE: ' ', + X: 0 + }, + { + BASE_COL: 'SOME_SHORTNUM', + RULE_TYPE: 'MAXVAL', + RULE_VALUE: '3', + X: 0 + }, + { + BASE_COL: 'SOME_CHAR', + RULE_TYPE: 'CASE', + RULE_VALUE: 'UPCASE', + X: 0 + }, + { + BASE_COL: 'SOME_CHAR_LOW', + RULE_TYPE: 'CASE', + RULE_VALUE: 'LOWCASE', + X: 0 + } +] + +const example_cols = [ + { + CLS_RULE: 'READ', + DDTYPE: 'CHARACTER', + DESC: 'dropdown_desc', + TYPE: '', + FMTNAME: '', + LABEL: 'SOME_DROPDOWN', + LONGDESC: '', + MEMLABEL: '', + NAME: 'SOME_DROPDOWN', + VARNUM: 3 + }, + { + CLS_RULE: 'READ', + DDTYPE: 'NUMERIC', + DESC: '', + TYPE: '', + FMTNAME: '', + LABEL: 'SOME_NUM', + LONGDESC: '', + MEMLABEL: '', + NAME: 'SOME_NUM', + VARNUM: 4 + } +] + +const example_COLTYPE = ` +{ + "data":"_____DELETE__THIS__RECORD_____", + "type":"dropdown", + "source":[ + "No", + "Yes" + ] +}, +{ + "data":"PRIMARY_KEY_FIELD", + "type":"numeric", + "format":"0" +}, +{ + "data":"SOME_CHAR" +}, +{ + "data":"SOME_CHAR_LOW" +}, +{ + "data":"SOME_CHAR_ANY" +}, +{ + "data":"SOME_DROPDOWN" +}, +{ + "data":"SOME_DROPDOWN_HARD" +}, +{ + "data":"SOME_NUM", + "type":"numeric", + "format":"0" +}, +{ + "data":"SOME_DATE", + "type":"date", + "dateFormat":"YYYY-MM-DD", + "correctFormat":"true" +}, +{ + "data":"SOME_DATETIME", + "type":"date", + "dateFormat":"YYYY-MM-DD HH:mm:ss.SSS", + "correctFormat":"true" +}, +{ + "data":"SOME_TIME", + "type":"time", + "timeFormat":"HH:mm:ss.SSS", + "correctFormat":"true" +}, +{ + "data":"SOME_SHORTNUM", + "type":"numeric", + "format":"0" +}, +{ + "data":"SOME_BESTNUM", + "type":"numeric", + "format":"0" +}` + +const example_sasparams = { + CLS_FLAG: 0, + COLHEADERS: 'head1 head2', + COLTYPE: example_COLTYPE, + DTTMVARS: 'dttm vars', + DTVARS: 'dt vars', + FILTER_TEXT: 'filter text', + LOADTYPE: 'load type', + PK: 'primary key', + PKCNT: 0, + RK_FLAG: 0, + TMVARS: 'string' +} + +const example_dataformats = { + vars: { + _____DELETE__THIS__RECORD_____: { + format: '$3.', + label: '_____DELETE__THIS__RECORD_____', + length: '3', + type: 'char' + }, + PRIMARY_KEY_FIELD: { + format: 'best.', + label: 'PRIMARY_KEY_FIELD', + length: '8', + type: 'num' + }, + SOME_CHAR: { + format: '$32767.', + label: 'SOME_CHAR', + length: '32767', + type: 'char' + }, + SOME_DROPDOWN: { + format: '$128.', + label: 'SOME_DROPDOWN', + length: '128', + type: 'char' + }, + SOME_NUM: { + format: 'best.', + label: 'SOME_NUM', + length: '8', + type: 'num' + }, + SOME_DATE: { + format: '$200.', + label: 'SOME_DATE', + length: '200', + type: 'char' + }, + SOME_DATETIME: { + format: '$200.', + label: 'SOME_DATETIME', + length: '200', + type: 'char' + }, + SOME_TIME: { + format: '$200.', + label: 'SOME_TIME', + length: '200', + type: 'char' + }, + SOME_SHORTNUM: { + format: 'best.', + label: 'SOME_SHORTNUM', + length: '4', + type: 'num' + }, + SOME_BESTNUM: { + format: 'BEST.', + label: 'SOME_BESTNUM', + length: '8', + type: 'num' + } + } +} diff --git a/client/src/app/shared/dc-validator/tests/dqValidation.spec.ts b/client/src/app/shared/dc-validator/tests/dqValidation.spec.ts new file mode 100644 index 0000000..1b5a878 --- /dev/null +++ b/client/src/app/shared/dc-validator/tests/dqValidation.spec.ts @@ -0,0 +1,128 @@ +import { DQRule } from '../models/dq-rules.model' +import { dqValidate } from '../validations/dq-validation' + +describe('DC Validator - dq validation', () => { + it('should validate MINVAL value', () => { + const validValue = 5 + const validValue2 = 6 + const invalidValue = 2 + const invalidStringValue = '2' + const numericStringValue = '5' + const numericSpecialMissingValue = 's' + + const dqRules: DQRule[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'MINVAL', + RULE_VALUE: '5', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + expect(dqValidate(dqRules, validValue2)).toBeTrue() + expect(dqValidate(dqRules, invalidValue)).toBeFalse() + expect(dqValidate(dqRules, invalidStringValue)).toBeFalse() + expect(dqValidate(dqRules, numericStringValue)).toBeTrue() + expect(dqValidate(dqRules, numericSpecialMissingValue)).toBeFalse() + }) + + it('should validate MAXVAL value', () => { + const validValue = 5 + const validValue2 = 4 + const invalidValue = 6 + const numericStringValue = '4' + const numericSpecialMissingValue = 's' + const invalidStringValue = '6' + + const dqRules: DQRule[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'MAXVAL', + RULE_VALUE: '5', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + expect(dqValidate(dqRules, validValue2)).toBeTrue() + expect(dqValidate(dqRules, invalidValue)).toBeFalse() + expect(dqValidate(dqRules, invalidStringValue)).toBeFalse() + expect(dqValidate(dqRules, numericStringValue)).toBeTrue() + expect(dqValidate(dqRules, numericSpecialMissingValue)).toBeTrue() + }) + + it('should validate UPCASE value', () => { + const validValue = 'VAL' + const invalidValue = 'val' + const numberValue = 1 + + const dqRules: DQRule[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'CASE', + RULE_VALUE: 'UPCASE', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + expect(dqValidate(dqRules, invalidValue)).toBeFalse() + expect(dqValidate(dqRules, numberValue)).toBeFalse() + }) + + it('should validate LOWCASE value', () => { + const validValue = 'val' + const invalidValue = 'VAL' + const numberValue = 1 + + const dqRules: DQRule[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'CASE', + RULE_VALUE: 'LOWCASE', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + expect(dqValidate(dqRules, invalidValue)).toBeFalse() + expect(dqValidate(dqRules, numberValue)).toBeFalse() + }) + + it('should validate NOTNULL value', () => { + const validValue = '1' + const validValue2 = 1 + const invalidValue = '' + const invalidValue2 = null + + const dqRules: DQRule[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'NOTNULL', + RULE_VALUE: ' ', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + expect(dqValidate(dqRules, validValue2)).toBeTrue() + expect(dqValidate(dqRules, invalidValue)).toBeFalse() + expect(dqValidate(dqRules, invalidValue2)).toBeFalse() + }) + + it('should return true if rule not found', () => { + const validValue = 5 + + const dqRules: any[] = [ + { + BASE_COL: 'test', + RULE_TYPE: 'NOT_EXIST', + RULE_VALUE: '5', + X: 0 + } + ] + + expect(dqValidate(dqRules, validValue)).toBeTrue() + }) +}) diff --git a/client/src/app/shared/dc-validator/tests/getHotDataSchema.spec.ts b/client/src/app/shared/dc-validator/tests/getHotDataSchema.spec.ts new file mode 100644 index 0000000..814e21c --- /dev/null +++ b/client/src/app/shared/dc-validator/tests/getHotDataSchema.spec.ts @@ -0,0 +1,11 @@ +import { getHotDataSchema } from '../utils/getHotDataSchema' + +describe('DC Validator - hot data schema', () => { + it('should return correct value for col type', () => { + expect(getHotDataSchema('numeric')).toEqual(0) + expect( + getHotDataSchema('autocomplete', { data: '', source: [1, 2, 3] }) + ).toEqual(1) + expect(getHotDataSchema('missing')).toEqual('') + }) +}) diff --git a/client/src/app/shared/dc-validator/tests/mergeSpecRules.spec.ts b/client/src/app/shared/dc-validator/tests/mergeSpecRules.spec.ts new file mode 100644 index 0000000..14f2aff --- /dev/null +++ b/client/src/app/shared/dc-validator/tests/mergeSpecRules.spec.ts @@ -0,0 +1,48 @@ +import { Col } from '../models/col.model' +import { DcValidation } from '../models/dc-validation.model' +import { mergeColsRules } from '../utils/mergeColsRules' + +describe('DC Validator - merge spec rules', () => { + it('should return array of merged specs', () => { + const rules: DcValidation[] = [ + { + data: 'test_col' + } + ] + const cols: Col[] = [ + { + NAME: 'test_col', + MEMLABEL: 'string', + DESC: 'test_desc', + LONGDESC: 'string', + TYPE: '', + CLS_RULE: 'cls_rule', + VARNUM: 0, + LABEL: 'string', + FMTNAME: 'string', + DDTYPE: 'string' + } + ] + const $dataFormats: any = { + vars: { + test_col: { + format: 'best.', + label: 'PRIMARY_KEY_FIELD', + length: '8', + type: 'test_type' + } + } + } + const expected: DcValidation[] = [ + { + data: 'test_col', + desc: 'test_desc', + clsRule: 'cls_rule', + length: 8 + } + ] + + expect(mergeColsRules(cols, rules, $dataFormats)).toEqual(expected) + expect(cols[0].TYPE).toEqual('test_type') + }) +}) diff --git a/client/src/app/shared/dc-validator/tests/parseColType.spec.ts b/client/src/app/shared/dc-validator/tests/parseColType.spec.ts new file mode 100644 index 0000000..ba80f7e --- /dev/null +++ b/client/src/app/shared/dc-validator/tests/parseColType.spec.ts @@ -0,0 +1,23 @@ +import { HotColumnSettings } from '../models/dc-validation.model' +import { parseColType } from '../utils/parseColType' + +describe('DC Validator - parse col type', () => { + it('should return array of parsed json', () => { + const colTypeString = + '{"data":"test","test2":"test2"}, {"data":"test3","test4":"test4"}' + const expected: HotColumnSettings[] = [ + { data: 'test', test2: 'test2' }, + { data: 'test3', test4: 'test4' } + ] + + expect(parseColType(colTypeString)).toEqual(expected) + }) + + it('should return empty array for invalid json', () => { + const colTypeString = + '{"test":"test""test:"test2"}, {"test3":"test3","test4":"test4"}' + const expected: HotColumnSettings[] = [] + + expect(parseColType(colTypeString)).toEqual(expected) + }) +}) diff --git a/client/src/app/shared/dc-validator/utils/getDqDataCols.ts b/client/src/app/shared/dc-validator/utils/getDqDataCols.ts new file mode 100644 index 0000000..67fe00c --- /dev/null +++ b/client/src/app/shared/dc-validator/utils/getDqDataCols.ts @@ -0,0 +1,11 @@ +import { DQData } from 'src/app/models/TableData' + +export const getDqDataCols = (dqData: DQData[]): string[] => { + const cols: string[] = [] + + dqData.forEach((element: DQData) => { + if (!cols.includes(element.BASE_COL)) cols.push(element.BASE_COL) + }) + + return cols +} diff --git a/client/src/app/shared/dc-validator/utils/getHotDataSchema.ts b/client/src/app/shared/dc-validator/utils/getHotDataSchema.ts new file mode 100644 index 0000000..0bc8283 --- /dev/null +++ b/client/src/app/shared/dc-validator/utils/getHotDataSchema.ts @@ -0,0 +1,29 @@ +import { DcValidation } from '../models/dc-validation.model' + +const schemaTypeMap: { [key: string]: any } = { + numeric: 0, + default: '' +} + +/** + * Schema defines the default values for given types. For example when new row is added. + */ +export const getHotDataSchema = ( + type: string | undefined, + cellValidation?: DcValidation +): any => { + if (!type) return schemaTypeMap.default + + switch (type) { + case 'autocomplete': { + return cellValidation && cellValidation.source + ? (cellValidation.source as string[] | number[])[0] + : [] + } + default: { + if (schemaTypeMap.hasOwnProperty(type)) return schemaTypeMap[type] + + return schemaTypeMap.default + } + } +} diff --git a/client/src/app/shared/dc-validator/utils/mergeColsRules.ts b/client/src/app/shared/dc-validator/utils/mergeColsRules.ts new file mode 100644 index 0000000..46d5174 --- /dev/null +++ b/client/src/app/shared/dc-validator/utils/mergeColsRules.ts @@ -0,0 +1,34 @@ +import { $DataFormats } from 'src/app/models/sas/editors-getdata.model' +import { Col } from '../models/col.model' +import { DcValidation } from '../models/dc-validation.model' + +/** + * Merging old validation params from sasparams with cols params + * @param sasparams sasparams coming from SAS + * @param cols cols coming from SAS + * @param rules rules to be updated + * @returns + */ +export const mergeColsRules = ( + cols: Col[], + rules: DcValidation[], + $dataFormats: $DataFormats +): DcValidation[] => { + for (let col of cols) { + const rule = rules.find((x: DcValidation) => x.data === col.NAME) + const colFormats = $dataFormats.vars[col.NAME] + + // Update COLS fields - it's passed by reference so this will update main object in editor component + // DATE and TIME types are always numeric + if (colFormats) + col.TYPE = ['DATE', 'DATETIME', 'TIME'].includes(col.DDTYPE) + ? 'num' + : colFormats.type + + if (rule && col.DESC) rule.desc = col.DESC + if (rule && colFormats.length) rule.length = parseInt(colFormats.length) + if (rule && col.CLS_RULE) rule.clsRule = col.CLS_RULE + } + + return rules +} diff --git a/client/src/app/shared/dc-validator/utils/parseColType.ts b/client/src/app/shared/dc-validator/utils/parseColType.ts new file mode 100644 index 0000000..57e4d0d --- /dev/null +++ b/client/src/app/shared/dc-validator/utils/parseColType.ts @@ -0,0 +1,16 @@ +import { HotColumnSettings } from '../models/dc-validation.model' + +/** + * From sas we get a string instead of array of objects, in that string `[]` are missing so + * before parsing JSON we need to add them. + * + * @param coltype string (objects) that comes from sas + * @returns JSON Handsontable.ColumnSettings[] + */ +export const parseColType = (coltype: string): HotColumnSettings[] => { + try { + return JSON.parse(`[${coltype}]`) + } catch (err: any) { + return [] + } +} diff --git a/client/src/app/shared/dc-validator/validations/dq-validation.ts b/client/src/app/shared/dc-validator/validations/dq-validation.ts new file mode 100644 index 0000000..b393efc --- /dev/null +++ b/client/src/app/shared/dc-validator/validations/dq-validation.ts @@ -0,0 +1,71 @@ +import { DQRule } from '../models/dq-rules.model' +import { specialMissingNumericValidator } from './hot-custom-validators' + +const dqValidation: { + [key: string]: (value: any, ruleValue: string | number) => boolean +} = { + CASE: (value: any, ruleValue: string | number): boolean => { + switch (ruleValue) { + case 'UPCASE': { + if ([undefined, null].includes(value)) return true + + return ( + typeof value === 'string' && + value.toString() === value.toString().toUpperCase() + ) + } + case 'LOWCASE': { + if ([undefined, null].includes(value)) return true + + return ( + typeof value === 'string' && + value.toString() === value.toString().toLowerCase() + ) + } + } + + return true + }, + MINVAL: (value: any, ruleValue: string | number): boolean => { + const isValidNumeric = specialMissingNumericValidator(value) + const numValue = parseFloat(value) + + // If it's validNumeric and it is NaN it means it is special numeric, and those are always less then any + // min value set + if (isValidNumeric && isNaN(numValue)) return false + + return numValue >= Number(ruleValue.toString()) + }, + MAXVAL: (value: any, ruleValue: string | number): boolean => { + const isValidNumeric = specialMissingNumericValidator(value) + const numValue = parseFloat(value) + + if (isValidNumeric && isNaN(numValue)) return true + + return numValue <= Number(ruleValue.toString()) + }, + NOTNULL: (value: any, ruleValue: string | number): boolean => { + return value !== undefined && value !== null && value.toString().length > 0 + } +} + +export const dqValidate = (dqRules: DQRule[], value: any): boolean => { + for (let detail of dqRules) { + if (dqValidation[detail.RULE_TYPE]) { + if (!dqValidation[detail.RULE_TYPE](value, detail.RULE_VALUE)) { + console.warn( + `DQ Invalid Reason: ${ + detail.RULE_TYPE + }\nValue: ${value})\nRule Value: ${ + detail.RULE_VALUE.length > 0 && detail.RULE_VALUE !== ' ' + ? detail.RULE_VALUE + : 'Not defined' + }` + ) + return false + } + } + } + + return true +} diff --git a/client/src/app/shared/dc-validator/validations/hot-custom-validators.ts b/client/src/app/shared/dc-validator/validations/hot-custom-validators.ts new file mode 100644 index 0000000..af621cb --- /dev/null +++ b/client/src/app/shared/dc-validator/validations/hot-custom-validators.ts @@ -0,0 +1,24 @@ +import { isSpecialMissing } from '@sasjs/utils/input/validators' + +/** + * Custom validator for numeric field that contains speical missings + */ +export function specialMissingNumericValidator( + value: any, + callback?: (valid: boolean) => void +) { + if (value === undefined || value === null) { + if (callback) callback(true) + return true + } + + if (!isNaN(value) && isFinite(value)) { + if (callback) callback(true) + return true + } + + const valid = isSpecialMissing(value) + + if (callback) callback(valid) + return valid +} diff --git a/client/src/app/shared/loading-indicator/loading-indicator.component.html b/client/src/app/shared/loading-indicator/loading-indicator.component.html new file mode 100644 index 0000000..bf6e1d4 --- /dev/null +++ b/client/src/app/shared/loading-indicator/loading-indicator.component.html @@ -0,0 +1,45 @@ +
+ + + + + + +

+ {{ request.program }} +   + loading + loaded + failed +

+
+
+
diff --git a/client/src/app/shared/loading-indicator/loading-indicator.component.scss b/client/src/app/shared/loading-indicator/loading-indicator.component.scss new file mode 100644 index 0000000..50fb4c5 --- /dev/null +++ b/client/src/app/shared/loading-indicator/loading-indicator.component.scss @@ -0,0 +1,51 @@ +// there are no clear instructions how to use Clarity ui variables +$clr-header-height: 2.5rem; +$clr-dark-gray: #565656; +$clr-red: #c92100; +$clr-yellow: rgb(233, 191, 4); +$clr-green: #60b515; + + +.loading-indicator { + line-height: $clr-header-height; + height: $clr-header-height; + display: flex; + align-items: center; + + .spinner { + vertical-align: middle; + } + + clr-signpost-content { + line-height: 24px; + color: $clr-dark-gray; + cursor: auto; + + p { + margin-top: 10px; + display: flex; + justify-content: space-between; + + &:first-child { + margin-top: 0; + } + &:last-child { + margin-bottom: 0; + } + + span { + margin-left: 10px; + + &.running { + color: $clr-yellow; + } + &.success { + color: $clr-green; + } + &.fail { + color: $clr-red; + } + } + } + } +} diff --git a/client/src/app/shared/loading-indicator/loading-indicator.component.ts b/client/src/app/shared/loading-indicator/loading-indicator.component.ts new file mode 100644 index 0000000..ecc90f8 --- /dev/null +++ b/client/src/app/shared/loading-indicator/loading-indicator.component.ts @@ -0,0 +1,23 @@ +import { Component, OnDestroy, OnInit } from '@angular/core' +import { Subscription } from 'rxjs' + +import { Service } from '../service.interface' + +@Component({ + selector: 'app-loading-indicator', + templateUrl: './loading-indicator.component.html', + styleUrls: ['./loading-indicator.component.scss'] +}) +export class LoadingIndicatorComponent implements OnInit, OnDestroy { + public loading: boolean = false + public requests: Service[] = [] + private _loadingSub: Subscription = new Subscription() + + constructor() {} + + ngOnInit(): void {} + + ngOnDestroy(): void { + this._loadingSub.unsubscribe() + } +} diff --git a/client/src/app/shared/login/login.component.html b/client/src/app/shared/login/login.component.html new file mode 100644 index 0000000..cced25c --- /dev/null +++ b/client/src/app/shared/login/login.component.html @@ -0,0 +1,49 @@ + diff --git a/client/src/app/shared/login/login.component.scss b/client/src/app/shared/login/login.component.scss new file mode 100644 index 0000000..3f0daf1 --- /dev/null +++ b/client/src/app/shared/login/login.component.scss @@ -0,0 +1,127 @@ +.sideBarProps { + background: #314351!important; + color: #e0e0e0; +} + +.sideBarProps h2, .sideBarProps h3, .sideBarProps h4, .sideBarProps h5, .sideBarProps input { + color: #e0e0e0; +} + +.sideBarProps button { + border-color: wheat!important; +} + +.sideBarProps a { + color: #e0e0e0; +} + +.login-sidebar-wrapper { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + pointer-events: none; + z-index: 10000; + + >* { + pointer-events: auto; + } + + .login-sidebar { + width: 400px; + position: absolute; + top: 0; + bottom: 0; + left: 0; + background: #fff; + border-right: 1px solid #ddd; + padding: 40px; + + form.login { + z-index: 101; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + + .title { + font-size: 32px; + letter-spacing: normal; + line-height: 36px; + .welcome { + margin-top: 36px; + } + } + + .login-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding: 48px 0 0 0; + + >* { + margin: 6px 0 18px 0; + } + } + } + + -webkit-transform: translateX(-400px); + transform: translateX(-400px); + + transition: -webkit-transform .3s ease; + transition: transform .3s ease; + transition: transform .3s ease, -webkit-transform .3s ease; + } + + &.active { + .login-sidebar { + -webkit-transform: translateX(0); + transform: translateX(0); + z-index: 101; + } + .overlay { + display: block; + } + } + + .overlay { + display: none; + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100%; + + background: rgba(33, 33, 33, .5); + z-index: 100; + } +} + +::ng-deep .login-sidebar-wrapper .login-group { + .clr-control-container, .username, .password { + width: 100%; + } + + .clr-input-wrapper { + max-width: none; + } + + button { + max-width: none; + } +} + +.login-logo { + max-width: 200px +} \ No newline at end of file diff --git a/client/src/app/shared/login/login.component.ts b/client/src/app/shared/login/login.component.ts new file mode 100644 index 0000000..12faa40 --- /dev/null +++ b/client/src/app/shared/login/login.component.ts @@ -0,0 +1,86 @@ +import { Component, OnInit, OnDestroy } from '@angular/core' +import { LoggerService } from '../../services/logger.service' +import { Subscription } from 'rxjs' + +import { SasService } from '../../services/sas.service' + +interface User { + user: string | null + pass: string | null +} + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'] +}) +export class LoginComponent implements OnInit, OnDestroy { + private _subscription: Subscription = new Subscription() + public isActive: boolean | undefined + public loading: boolean = false + public alertClosed: boolean = true + public errorMsg: string | undefined + public data: User = { + user: null, + pass: null + } + + constructor( + private sasService: SasService, + private loggerService: LoggerService + ) {} + + ngOnInit() { + let sasjsConfig = this.sasService.getSasjsConfig() + + if (sasjsConfig.loginMechanism !== 'Redirected') { + this._subscription = this.sasService.shouldLogin.subscribe( + (shouldLogin) => { + this.isActive = shouldLogin + + let bodyEl = document.querySelector('body') + + if (!bodyEl) return + + if (shouldLogin) { + bodyEl.classList.add('should-login') + } else { + bodyEl.classList.remove('should-login') + } + } + ) + } + } + + ngOnDestroy() { + this._subscription.unsubscribe() + } + + public submit() { + if (this.loading) { + return + } + + this.loading = true + + if (this.data.user && this.data.pass) { + this.sasService.login(this.data.user, this.data.pass).then( + (isLoggedIn: any) => { + this.loading = false + + if (!isLoggedIn) { + this.errorMsg = 'Username or password invalid' + this.alertClosed = false + } + }, + (err: any) => { + this.loggerService.log(err) + + this.loading = false + this.errorMsg = err + this.alertClosed = false + } + ) + } + } +} diff --git a/client/src/app/shared/requests-modal/requests-modal.component.html b/client/src/app/shared/requests-modal/requests-modal.component.html new file mode 100644 index 0000000..39b55ec --- /dev/null +++ b/client/src/app/shared/requests-modal/requests-modal.component.html @@ -0,0 +1,221 @@ + + + + diff --git a/client/src/app/shared/requests-modal/requests-modal.component.scss b/client/src/app/shared/requests-modal/requests-modal.component.scss new file mode 100644 index 0000000..a410079 --- /dev/null +++ b/client/src/app/shared/requests-modal/requests-modal.component.scss @@ -0,0 +1,83 @@ +::ng-deep { + .requests-modal .modal-header .close clr-icon { + display: block !important; + } + + .requests-modal .modal-content { + padding: 20px 10px 5px 10px; + } + + .work-tables-dropdown button { + color: var(--clr-nav-link-color, #8c8c8c) !important; + } + + .stack-view { + height: auto !important; + + //Following lines will fix clarity (requests modal white) issue. + //Clarity version that has issue is: v12 + mask-image: none !important; + -webkit-mask-image: none !important; + } + + .content { + clr-icon { + margin-bottom: 5px; + } + + pre { + word-break: break-all; + white-space: pre-wrap; + max-height: initial; + overflow: visible; + border: 0; + } + + .stack-block-label { + // Clarity before V3 ----- + // display: none; + + // Clarity V3 ----- + width: 100%; + padding-left: .6rem !important; + + .stack-view-key { + display: none !important; + } + } + } + + .err-links { + .clr-treenode-children { + max-height: 55px; + overflow: auto; + } + } +} + +.dropdown-item { + &.selected { + background: #d8e3e9; + } +} + +.log-wrapper { + min-height: 50px; + padding: 10px; + margin-top: 10px; + + white-space: pre-wrap; + border-radius: 3px; + + border: 1px solid #e2e2e2; + background-color: #fbfbfb; + + height: 48vh; + overflow: auto; +} + +.no-reqs { + border-top: 1px solid #0000001a; + padding-top: 5px; + text-align: center; +} \ No newline at end of file diff --git a/client/src/app/shared/requests-modal/requests-modal.component.ts b/client/src/app/shared/requests-modal/requests-modal.component.ts new file mode 100644 index 0000000..2db0a83 --- /dev/null +++ b/client/src/app/shared/requests-modal/requests-modal.component.ts @@ -0,0 +1,172 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' +import { SASjsRequest } from '@sasjs/adapter' +import * as moment from 'moment' +import { HelperService } from 'src/app/services/helper.service' +import { LoggerService } from '../../services/logger.service' +import { SasService } from '../../services/sas.service' + +interface SASjsRequestExtended extends SASjsRequest { + parsedTimestamp?: string + logErrors?: string[] + logWarnings?: string[] + selectedTable?: string +} + +@Component({ + selector: 'app-requests-modal', + templateUrl: './requests-modal.component.html', + styleUrls: ['./requests-modal.component.scss'] +}) +export class RequestsModalComponent implements OnInit { + private _opened: boolean = false + get opened(): boolean { + return this._opened + } + @Input() + set opened(value: boolean) { + this._opened = value + if (value) this.modalOpened() + + this.loggerService.log(this.sasjsRequests) + } + + @Output() openedChange = new EventEmitter() + + public sasLogActive: boolean = true + public sasSourceCodeActive: boolean = false + public sasGeneratedCodeActive: boolean = false + public tablesActive: boolean = false + + public sasjsConfig = this.sasService.getSasjsConfig() + public sasjsRequests: SASjsRequestExtended[] = [] + public workTables: any + + constructor( + private sasService: SasService, + private loggerService: LoggerService, + private helperService: HelperService + ) {} + + ngOnInit(): void {} + + public parseLogTimestamp(timestamp: any) { + return `${this.formatTimestamp(timestamp)} ${this.timestampFromNow( + timestamp + )}` + } + + public cutAppLoc(link: string) { + return link.replace(this.sasjsConfig.appLoc + '/', '') + } + + public formatTimestamp(timestamp: any) { + return moment(timestamp).format() + ? moment(timestamp).format('dddd, MMMM Do YYYY, h:mm:ss a') + : timestamp + } + + public timestampFromNow(timestamp: any) { + return moment(timestamp).format() ? ` (${moment(timestamp).fromNow()})` : '' + } + + public modalOpenChange(state: any) { + this.opened = state + this.openedChange.emit(this.opened) + } + + public modalOpened() { + this.sasjsRequests = this.sasService.getSasRequests() + + for (let request of this.sasjsRequests) { + this.parseErrorsAndWarnings(request) + + request.serviceLink = this.cutAppLoc(request.serviceLink) + request.parsedTimestamp = this.parseLogTimestamp(request.timestamp) + } + } + + public goToLogLine( + linkingLine: string, + requestStackId: string, + type: string + ) { + let allLines: any = document.querySelectorAll( + `#${requestStackId} .log-wrapper.saslog font` + ) + let logWrapper: any = document.querySelector( + `#${requestStackId} .log-wrapper.saslog` + ) + + for (let line of allLines) { + if (line.textContent.includes(linkingLine)) { + logWrapper.scrollTop = line.offsetTop - logWrapper.offsetTop + line.style.backgroundColor = '#61a2202b' + + setTimeout(() => { + line.style = '' + }, 3000) + } + } + } + + public async parseErrorsAndWarnings(req: any) { + if (!req || !req.logFile || typeof req.logFile !== 'string') return + if (req['logErrors'] !== undefined || req['logWarnings'] !== undefined) + return + + let errorLines = [] + let warningLines = [] + + let logLines = req.logFile.split('\n') + + for (let i = 0; i < logLines.length; i++) { + if (/<.*>ERROR/gm.test(logLines[i])) { + let errorLine = logLines[i].substring( + logLines[i].indexOf('E'), + logLines[i].length - 1 + ) + errorLines.push(errorLine) + } else if (/^ERROR/gm.test(logLines[i])) { + errorLines.push(logLines[i]) + + logLines[i] = '' + logLines[i] + '' + } + + if (/<.*>WARNING/gm.test(logLines[i])) { + let warningLine = logLines[i].substring( + logLines[i].indexOf('W'), + logLines[i].length - 1 + ) + warningLines.push(warningLine) + } else if (/^WARNING/gm.test(logLines[i])) { + warningLines.push(logLines[i]) + + logLines[i] = '' + logLines[i] + '' + } + } + + this.loggerService.log(warningLines) + + req.logFile = logLines.join('\n') + req.logErrors = errorLines + req.logWarnings = warningLines + } + + downloadLog(logFile: string) { + const timestamp = new Date().valueOf() + this.helperService.downloadTextFile(`logFile-${timestamp}`, logFile) + } + + downloadSourceCode(sourceCode: string) { + const timestamp = new Date().valueOf() + this.helperService.downloadTextFile(`sourceCode-${timestamp}`, sourceCode) + } + + downloadGeneratedCode(generatedCode: string) { + const timestamp = new Date().valueOf() + this.helperService.downloadTextFile( + `generatedCode-${timestamp}`, + generatedCode + ) + } +} diff --git a/client/src/app/shared/service.interface.ts b/client/src/app/shared/service.interface.ts new file mode 100644 index 0000000..416e904 --- /dev/null +++ b/client/src/app/shared/service.interface.ts @@ -0,0 +1,5 @@ +export interface Service { + program: string + running: boolean + successful?: boolean +} diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts new file mode 100644 index 0000000..24aafef --- /dev/null +++ b/client/src/app/shared/shared.module.ts @@ -0,0 +1,48 @@ +import { NgModule, OnInit } from '@angular/core' +import { CommonModule } from '@angular/common' +import { FormsModule } from '@angular/forms' +import { ClarityModule } from '@clr/angular' +import { RouterModule } from '@angular/router' + +import { LoadingIndicatorComponent } from './loading-indicator/loading-indicator.component' +import { LoginComponent } from './login/login.component' +import { UserService } from './user.service' +import { AlertsService } from './alerts/alerts.service' +import { UserNavDropdownComponent } from './user-nav-dropdown/user-nav-dropdown.component' +import { AlertsComponent } from './alerts/alerts.component' +import { TermsComponent } from './terms/terms.component' +import { DirectivesModule } from '../directives/directives.module' +import { DatasetInfoComponent } from './dataset-info/dataset-info.component' +import { ContactLinkComponent } from './contact-link/contact-link.component' + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + RouterModule, + ClarityModule, + DirectivesModule + ], + declarations: [ + LoadingIndicatorComponent, + LoginComponent, + UserNavDropdownComponent, + AlertsComponent, + TermsComponent, + DatasetInfoComponent, + ContactLinkComponent + ], + exports: [ + LoadingIndicatorComponent, + LoginComponent, + UserNavDropdownComponent, + AlertsComponent, + TermsComponent, + DatasetInfoComponent, + ContactLinkComponent + ], + providers: [UserService, AlertsService] +}) +export class SharedModule implements OnInit { + ngOnInit(): void {} +} diff --git a/client/src/app/shared/sidebar/sidebar.component.html b/client/src/app/shared/sidebar/sidebar.component.html new file mode 100644 index 0000000..12625b2 --- /dev/null +++ b/client/src/app/shared/sidebar/sidebar.component.html @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + +

Edit

+ + + + + + +
diff --git a/client/src/app/shared/sidebar/sidebar.component.scss b/client/src/app/shared/sidebar/sidebar.component.scss new file mode 100644 index 0000000..6b2f4cc --- /dev/null +++ b/client/src/app/shared/sidebar/sidebar.component.scss @@ -0,0 +1,79 @@ +$sidebarWidth: 272px; + +clr-vertical-nav { + width: $sidebarWidth; + min-width: $sidebarWidth; + height: 100%; + max-width: 375px; + position: relative; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.12); + background-color: white !important; + + .sun-dropdown { + min-height: 36px + } + + .nav-tree { + height: 100%; + overflow-y: auto; + } + + &.closed { + margin-left: -$sidebarWidth; + } + + .resize-handle { + position: absolute; + top: 0; + bottom: 0; + right: -3px; + border-right: 4px solid #80b441; + cursor: col-resize; + opacity: 0; + transition: all 0.1s ease-in-out; + + &:hover { + opacity: .5; + } + + &.resizing { + opacity: 1; + } + } + + &.resizing { + transition: none !important; + } +} + +.nav-divider { + border: 0; + border-top: 1px solid #d3d3d3; + margin-bottom: 0; +} + +.page-title { + margin: 0; + font-size: 18px; + text-align: center; +} +.zero-margin{ + margin: 0px; +} +.user-nav-btn{ + padding: 0px; + padding-left: 2px; + padding-right: 2px; +} + +#sidebarNav { + z-index: 200; +} + +@media (max-width: 767px) { //768 + #sidebarNav { + position: absolute; + bottom: 0; + top: 0; + } +} \ No newline at end of file diff --git a/client/src/app/shared/sidebar/sidebar.component.ts b/client/src/app/shared/sidebar/sidebar.component.ts new file mode 100644 index 0000000..b2a57db --- /dev/null +++ b/client/src/app/shared/sidebar/sidebar.component.ts @@ -0,0 +1,119 @@ +import { + Component, + OnInit, + HostListener, + ViewChild, + ElementRef, + EventEmitter, + Output +} from '@angular/core' +import { Router } from '@angular/router' +import { EventService } from '../../services/event.service' +import { SasService } from '../../services/sas.service' +import { SASjsConfig } from '@sasjs/adapter' +import { globals } from '../../_globals' + +@Component({ + selector: 'app-sidebar', + templateUrl: './sidebar.component.html', + styleUrls: ['./sidebar.component.scss'] +}) +export class SidebarComponent implements OnInit { + @ViewChild('sidebarNav') sidebarNav!: ElementRef + + @Output() scrolledToBottom: EventEmitter = new EventEmitter() + + public sidebarOpen: boolean = true + public sidebarWidth: number | null = null + public sidebarMaxWidth: number | null = null + public resizing: boolean = false + public sasjsConfig: SASjsConfig = new SASjsConfig() + public serverType: string + + constructor( + private _router: Router, + private eventService: EventService, + private _sasService: SasService + ) { + this.sasjsConfig = this._sasService.getSasjsConfig() + this.serverType = this._sasService.getServerType() + } + + ngOnInit() { + this.eventService.onSidebarToggle.subscribe((res: any) => { + if (res) { + this.sidebarOpen = res['open'] + } else { + this.sidebarOpen = !this.sidebarOpen + } + + this.eventService.dispatchEvent('resize') + }) + } + + public onTreeScroll(event: any) { + let element = event.target + + if (element.scrollTop >= element.scrollHeight - element.offsetHeight - 10) { + this.scrolledToBottom.emit() + } + } + + public isMainRoute(route: string): boolean { + return this._router.url.includes(route) + } + + public getSubPage() { + let url = this._router.url.split('/') + + return url[2] + } + + public navigateToViewer() { + globals.viewer.currentSelection = '' + this._router.navigateByUrl('/view/data') + } + + public resizeStart() { + this.resizing = true + + let body = document.getElementsByTagName('body')[0] + body.style.cssText = 'user-select: none' + } + + public resizeEnd() { + this.resizing = false + + let body = document.getElementsByTagName('body')[0] + body.style.cssText = '' + } + + @HostListener('document:mousemove', ['$event']) + onMouseMove(e: any) { + if (this.resizing) { + this.sidebarWidth = e.clientX + + let sidebarNavigationEl = document.getElementsByClassName('nav-tree')[0] + + if (this.sidebarWidth) { + if (this.isOverflown(sidebarNavigationEl)) { + this.sidebarMaxWidth = + this.sidebarWidth >= 375 + ? this.sidebarWidth + 10 + : this.sidebarMaxWidth + } + } + } + } + + @HostListener('document:mouseup', ['$event']) + onMouseUp(e: any) { + if (this.resizing) { + this.resizeEnd() + } + } + + isOverflown(element: any) { + return element.scrollWidth > element.clientWidth + } +} diff --git a/client/src/app/shared/soft-select/soft-select.component.html b/client/src/app/shared/soft-select/soft-select.component.html new file mode 100644 index 0000000..42b9500 --- /dev/null +++ b/client/src/app/shared/soft-select/soft-select.component.html @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + diff --git a/client/src/app/shared/soft-select/soft-select.component.scss b/client/src/app/shared/soft-select/soft-select.component.scss new file mode 100644 index 0000000..223faec --- /dev/null +++ b/client/src/app/shared/soft-select/soft-select.component.scss @@ -0,0 +1,31 @@ +.input-val { + border: 0px; + background: #fbf8f8; + border-bottom: 1px solid #999999; +} + +input { + width: 100%; + outline: none; + + &::-webkit-calendar-picker-indicator { + margin-top: -5px; + } +} + +clr-date-container { + position: relative; + margin-top: 2px !important; + + ::ng-deep { + .clr-input-group-icon-action { + position: absolute; + right: -5px; + } + + input::-webkit-calendar-picker-indicator { + margin-right: 20px; + margin-top: -5px; + } + } +} \ No newline at end of file diff --git a/client/src/app/shared/soft-select/soft-select.component.ts b/client/src/app/shared/soft-select/soft-select.component.ts new file mode 100644 index 0000000..94c7aa7 --- /dev/null +++ b/client/src/app/shared/soft-select/soft-select.component.ts @@ -0,0 +1,88 @@ +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges, + ViewChild +} from '@angular/core' +import { OnLoadingMoreEvent } from '../autocomplete/autocomplete.component' + +@Component({ + selector: 'app-soft-select', + templateUrl: './soft-select.component.html', + styleUrls: ['./soft-select.component.scss'] +}) +export class SoftSelectComponent implements OnInit, OnChanges { + @Input() inputId: string = '' + @Input() label: string | undefined + @Input() value: Date | string | null = '' + @Input() disabled: boolean = false + @Input() type: string = 'text' + @Input() disableSoftselect: boolean = false + @Input() emitOnlySelected: boolean = false + @Input() enableLoadMore: boolean = false + + @Output() valueChange: EventEmitter = new EventEmitter() + @Output() onInputEvent: EventEmitter = new EventEmitter() + @Output() focusinInput: EventEmitter = new EventEmitter() + @Output() onAutocompleteLoadingMore: EventEmitter = + new EventEmitter() + + @ViewChild('input') inputElement: any + + temp: Date | string | null = '' + inputFocused: boolean = false + + constructor() {} + + ngOnChanges(changes: SimpleChanges): void { + if ( + changes.value && + changes.value.currentValue !== changes.value.previousValue + ) + this.valueChange.emit(changes.value.currentValue) + } + + ngOnInit(): void {} + + autocompleteLoadingMore(event: OnLoadingMoreEvent) { + this.onAutocompleteLoadingMore.emit(event) + } + + onInputFired(event: any) { + const value = event.target.value + + this.temp = value + + this.valueChange.emit(value) + this.onInputEvent.emit(event) + } + + onDateInputFired(value: any) { + this.temp = value + + this.valueChange.emit(value) + this.onInputEvent.emit(value) + } + + onInputMouseOut() { + if (this.disableSoftselect) return + + this.value = this.temp + this.temp = '' + } + + onInputMouseOver() { + if (this.disableSoftselect) return + + this.temp = !!this.value ? this.value : '' + this.value = '' + } + + onFocusinInput(event: any) { + this.focusinInput.emit(event) + } +} diff --git a/client/src/app/shared/terms/terms.component.html b/client/src/app/shared/terms/terms.component.html new file mode 100644 index 0000000..cc73a84 --- /dev/null +++ b/client/src/app/shared/terms/terms.component.html @@ -0,0 +1,36 @@ +
+
+ End User License Agreement +

+ Welcome to Data Controller for SAS! Please review and accept agreement + below in order to proceed. +

+
+
+ +
+ + + + + + +
+
diff --git a/client/src/app/shared/terms/terms.component.scss b/client/src/app/shared/terms/terms.component.scss new file mode 100644 index 0000000..f4c5c83 --- /dev/null +++ b/client/src/app/shared/terms/terms.component.scss @@ -0,0 +1,29 @@ +:host { + height: 100%; + background: #f5f6ff; +} + +.clr-checkbox-wrapper { + &.disabled { + opacity: 0.5; + } +} + + +.card { + height: 100%; + display: flex; + flex-direction: column; + margin-top: 0; + + .card-block { + flex: 1; + overflow: auto; + + background-color: #f4f4f4; + } +} + +.accept-checkbox { + padding: 10px 15px +} \ No newline at end of file diff --git a/client/src/app/shared/terms/terms.component.ts b/client/src/app/shared/terms/terms.component.ts new file mode 100644 index 0000000..d23519d --- /dev/null +++ b/client/src/app/shared/terms/terms.component.ts @@ -0,0 +1,89 @@ +import { + AfterViewInit, + Component, + ElementRef, + OnInit, + ViewChild +} from '@angular/core' +import { SasService } from '../../services/sas.service' +import * as marked from 'marked' +import { EULA } from 'src/environments/_eula' + +@Component({ + selector: 'app-terms', + templateUrl: './terms.component.html', + styleUrls: ['./terms.component.scss'] +}) +export class TermsComponent implements OnInit, AfterViewInit { + @ViewChild('markdownCard') markdownCard!: ElementRef + + public agreeChecked: boolean = false + public agreeBoxLocked: boolean = true + public agreeClicked: boolean = false + + public eula_markdown = EULA + + constructor(private sasService: SasService) {} + + ngOnInit(): void { + const md = marked.marked.setOptions({}) + this.eula_markdown = md.parse(this.eula_markdown) + } + + ngAfterViewInit(): void { + // We will fire SCROLL event that will recalculate and enable checkbox in case when + // licence is short and no scroll is present + setTimeout(() => { + if (this.markdownCard) + this.markdownCard.nativeElement.dispatchEvent(new CustomEvent('scroll')) + }) + } + + termsAgreeChange() { + if (!this.agreeChecked) { + return + } + + this.agreeBoxLocked = true + this.agreeClicked = true + + let table = { SASControlTable: [{ ACCEPTED: 'yes' }] } + + this.sasService + .request(`public/registeruser`, table) + .then((res: any) => { + if (res.return && res.return[0] && res.return[0].MSG === 'SUCCESS') { + location.reload() + } + }) + .catch((err: any) => err) + .finally(() => { + //Timeout is added to improve UX + //Without it, spinner would stop, and after one second app is reloaded + //at that point it gives false impresion that accepting didn't work + //with timeout spinner is visible all the time until page reloads + setTimeout(() => { + this.agreeBoxLocked = false + this.agreeClicked = false + this.agreeChecked = false + }, 1000) + }) + } + + onCardBlockScroll(event: any) { + if (!this.agreeClicked) { + let card_block_el: any = event.target + + if (card_block_el) { + let pos = card_block_el.scrollTop + card_block_el.offsetHeight + let max = card_block_el.scrollHeight - 20 + + if (pos >= max) { + this.agreeBoxLocked = false + } else { + this.agreeBoxLocked = true + } + } + } + } +} diff --git a/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.html b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.html new file mode 100644 index 0000000..95c236c --- /dev/null +++ b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.html @@ -0,0 +1,121 @@ + + + +
+ + + + + + +
+ + SAS Requests + + + + + Documentation + + + +
+ + System + + + Log Out + + + +
+
+
+ +
diff --git a/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.scss b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.scss new file mode 100644 index 0000000..3a32544 --- /dev/null +++ b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.scss @@ -0,0 +1,157 @@ +// it must be a better way to read clarity variables... +//@import '../../../../node_modules/@clr/ui/src/utils/helpers.clarity'; + +//@import '../../../../node_modules/@clr/ui/src/color/utils/colors.clarity'; +//@import '../../../../node_modules/@clr/ui/src/color/utils/contrast-cache.clarity'; +//@import '../../../../node_modules/@clr/ui/src/color/utils/helpers.clarity'; + +//@import '../../../../node_modules/@clr/ui/src/utils/variables.clarity'; + +$clr-header-height: 3rem; +$clr-near-white: #fafafa; +$clr-dark-gray: #565656; +$clr-light-gray: #eee; + +.copyRight { + margin-top: 10px; + + span { + word-break: break-word; + white-space: pre-wrap; + width: 100%; + text-align: center; + line-height: 1.5; + } +} + +.app-nav-dropdown { + //left padding for branding is also 24px + padding-right: 15px; + line-height: $clr-header-height; + height: $clr-header-height; + + >button.dropdown-toggle { + color: $clr-near-white; + position: relative; + + &:after { + content: ""; + background-color: $clr-near-white; + opacity: .15; + left: 0; + position: absolute; + width: 1px; + height: 40px; + top: 10px; + } + + .badge { + &.hidden { + visibility: hidden; + } + } + } + + clr-dropdown-menu { + color: $clr-dark-gray; + padding-bottom: 0; + + .separator { + margin: 10px 0; + border-bottom: 1px solid gray; + // border-bottom: 1px solid $clr-dark-gray; + } + + .dropdown-item { + display: flex; + flex-direction: row; + align-items: center; + position: relative; + height: 45px; + line-height: 40px; + + span.dropdown-text{ + color: $clr-dark-gray; + } + + .badge { + position: absolute; + top: 15px; + right: 26px; + margin-right: 0; + } + + &.debug-switch-item { + padding: 0; + } + + .toggle-switch { + margin: 0; + width: 100%; + height: 100%; + justify-content: center; + } + + .clr-logout{ + position: absolute; + right: 20px; + top: 15px; + } + + ::ng-deep { + .clr-control-container { + width: 100%; + height: 100%; + } + + clr-toggle-wrapper { + width: 100%; + margin: 0; + height: 100%; + padding: 10px 20px; + } + + input { + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + cursor: pointer; + } + + .clr-toggle-wrapper input[type=checkbox]+label::after { + transition: none !important; + } + } + } + } + +} + +.debug-toggle-label { + padding-left: 42px; +} + +@media (max-width: 768px){ + .sidenav-content{ + a.nav-link.active { + color: inherit; + padding: 15px; + background: #565656; + } + } +} +.nav-link.d-block{ + span.badge{ + position: absolute; + } + +} +.avatar-img{ + width: 40px; + height: 40px; + margin-left: 10px; + border-radius: 50px; +} \ No newline at end of file diff --git a/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.ts b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.ts new file mode 100644 index 0000000..fdea8f5 --- /dev/null +++ b/client/src/app/shared/user-nav-dropdown/user-nav-dropdown.component.ts @@ -0,0 +1,90 @@ +import { Component, OnInit, OnDestroy } from '@angular/core' +import { Subscription } from 'rxjs' +import { UserService } from '../user.service' +import { VERSION } from '../../../environments/version' +import { SasService } from '../../services/sas.service' +import { SASjsConfig } from '@sasjs/adapter' +import { EventService } from '../../services/event.service' +import { Router } from '@angular/router' + +@Component({ + selector: 'app-user-nav-dropdown', + templateUrl: './user-nav-dropdown.component.html', + styleUrls: ['./user-nav-dropdown.component.scss'] +}) +export class UserNavDropdownComponent implements OnInit, OnDestroy { + public userName: string = 'Not logged in' + private reqSub: Subscription = new Subscription() + private userSub: Subscription = new Subscription() + + public appLogs: Array = [] + public debugLogs: Array = [] + public failedReqs: Array = [] + public sasErrors: Array = [] + + public isViya: boolean = false + public sasjsConfig: SASjsConfig = new SASjsConfig() + public requestsCount: number = 0 + public commitVer: string = '' + + constructor( + private userService: UserService, + private sasService: SasService, + private eventService: EventService, + public router: Router + ) {} + + ngOnInit(): void { + this.userSub = this.userService.userChange.subscribe((user) => { + this.userName = user.username + }) + + this.sasjsConfig = this.sasService.getSasjsConfig() + if (this.sasjsConfig.serverType === 'SASVIYA') { + this.isViya = true + } + this.commitVer = (VERSION.tag || '').replace('v', '') + '.' + VERSION.hash + } + + ngOnDestroy(): void { + this.reqSub.unsubscribe() + this.userSub.unsubscribe() + } + + openRequestsModal() { + this.eventService.openRequestsModal() + } + + onDebugModeChange(dropdownItem?: any): void { + if (this.sasjsConfig) { + this.sasService.setDebugState(this.sasjsConfig.debug) + } + } + + public onDebugRowClick(evt: Event, dropdownToggle: any): void { + evt.stopPropagation() + + setTimeout(() => { + dropdownToggle.click() + }, 300) + } + + public logout(evt: any): void { + evt.preventDefault() + + try { + this.sasService.logout() + } catch (err) { + // TODO: handle error - show something to user + console.error(err) + } + } + + public getPictureUrl() { + return `${this.sasjsConfig.serverUrl}/identities/users/${this.userName}/avatar/content` + } + + get isDeployPage() { + return this.router.url.includes('deploy') + } +} diff --git a/client/src/app/shared/user.interface.ts b/client/src/app/shared/user.interface.ts new file mode 100644 index 0000000..c256163 --- /dev/null +++ b/client/src/app/shared/user.interface.ts @@ -0,0 +1,4 @@ +export interface User { + username: string + pictureUrl?: string +} diff --git a/client/src/app/shared/user.service.ts b/client/src/app/shared/user.service.ts new file mode 100644 index 0000000..4e782d6 --- /dev/null +++ b/client/src/app/shared/user.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core' +import { Subject } from 'rxjs' +import { User } from './user.interface' + +@Injectable() +export class UserService { + private _user!: User + public userChange: Subject = new Subject() + + constructor() {} + + public set user(user) { + this._user = user + this.userChange.next(user) + } + + public get user() { + return this._user + } +} diff --git a/client/src/app/shared/viewboxes/models/viewbox-hot-table.model.ts b/client/src/app/shared/viewboxes/models/viewbox-hot-table.model.ts new file mode 100644 index 0000000..6bba18c --- /dev/null +++ b/client/src/app/shared/viewboxes/models/viewbox-hot-table.model.ts @@ -0,0 +1,10 @@ +import { HotTableInterface } from 'src/app/models/HotTable.interface' + +export interface ViewboxHotTable extends HotTableInterface { + allColHeaders: string[] + $dataformats: any + colHeadersHidden: string[] + colHeadersVisible: string[] + headerPks: string[] + cols: any +} diff --git a/client/src/app/shared/viewboxes/models/viewbox-table.model.ts b/client/src/app/shared/viewboxes/models/viewbox-table.model.ts new file mode 100644 index 0000000..552b83d --- /dev/null +++ b/client/src/app/shared/viewboxes/models/viewbox-table.model.ts @@ -0,0 +1,7 @@ +import { ViewboxHotTable } from './viewbox-hot-table.model' + +export interface ViewboxTable { + viewboxId: number + viewboxLibDataset: string + hotTable: ViewboxHotTable +} diff --git a/client/src/app/shared/viewboxes/models/viewbox.model.ts b/client/src/app/shared/viewboxes/models/viewbox.model.ts new file mode 100644 index 0000000..2529724 --- /dev/null +++ b/client/src/app/shared/viewboxes/models/viewbox.model.ts @@ -0,0 +1,21 @@ +import { QueryClause } from 'src/app/models/TableData' + +export interface Viewbox { + id: number + library: string + table: string + width: number + height: number + x: number + y: number + focused?: boolean + query?: QueryClause[] + filterText?: string + columns?: number[] + filter_pk?: string + minimized?: boolean + collapsed?: boolean + loadingData?: boolean + searchNumeric?: boolean + searchLoading?: boolean +} diff --git a/client/src/app/shared/viewboxes/viewboxes.component.html b/client/src/app/shared/viewboxes/viewboxes.component.html new file mode 100644 index 0000000..ca68c3a --- /dev/null +++ b/client/src/app/shared/viewboxes/viewboxes.component.html @@ -0,0 +1,452 @@ + + + + + + + +
+
+
+ + #{{ viewbox.id }} {{ viewbox.library }}.{{ viewbox.table }} + + +
+ + + + +
+
+ +
+
+
+ + + + Loading... + +
+ + + + + + + +
+ + +
+
+
+ +
+ + +
+
+
+ + + + + + diff --git a/client/src/app/shared/viewboxes/viewboxes.component.scss b/client/src/app/shared/viewboxes/viewboxes.component.scss new file mode 100644 index 0000000..05f9f47 --- /dev/null +++ b/client/src/app/shared/viewboxes/viewboxes.component.scss @@ -0,0 +1,287 @@ +.licence-notice { + font-size: 14px; + display: block; + opacity: 0.6;} + +clr-modal.root-modal { + ::ng-deep { + .modal-body-wrapper { + height: calc(100% - 60px); + } + + .modal-content { + height: 80vh; + } + } + + .modal-footer { + padding: 0; + } + + .modal-body { + max-height: 100%; + height: 100%; + } + + z-index: 1300; +} + +dc-tree { + overflow: auto; + flex: 1; +} + +.tooltip-long { + word-break: break-word; +} + +.add-new { + width: 50%; + padding-right: 5px; +} + +.viewbox-limit-notice { + opacity: .7; + color: #E74C3C +} + +.currently-open { + width: 50%; + + .open-viewbox { + cursor: pointer; + padding: 3px 5px; + + &.selected { + background: #3c85002e; + } + + &:hover { + background: #e8e8e8; + } + } +} + +.viewboxes-container { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + pointer-events: none; + z-index: 999; // make it 1020 if there are issues +} + +.viewbox { + min-width: 200px; + min-height: 200px; + position: fixed; + left: 0; + top: 0; + pointer-events: all; + + display: flex; + flex-direction: column; + + border-top-left-radius: 3px; + border-top-right-radius: 3px; + + box-shadow: 0px 0px 10px -3px black; + + &.focused { + z-index: 1100; + outline: none; + } + + .content { + border: 1px solid #0000004d; + background: white; + height: 100%; + width: 100%; + flex: 1; + overflow-x: auto; + } + + .drag-handle { + width: 100%; + min-height: 20px; + background-color: #3c8500; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + + color: #fff; + padding: 0 5px; + + pointer-events: all; + + .table-title { + white-space: pre-wrap; + word-break: break-all; + } + + .actions { + display: flex; + min-width: 35px; + + clr-icon { + cursor: pointer; + margin-left: 5px; + + &:hover { + transform: scale(1.3); + } + } + } + } + + .click-icon { + cursor: pointer; + + &:hover { + transform: scale(1.3); + } + } + + .dragHandle { + position: absolute; + // bottom: -8px; + // right: -8px; + // background-color: black; + } + + .dragHandle.corner { + width: 15px; + height: 15px; + cursor: nwse-resize; + } + + .dragHandle.right { + width: 2px; + height: 100%; + cursor: ew-resize; + } + + .dragHandle.bottom { + height: 2px; + width: 100%; + cursor: ns-resize; + } + +} + +.cols-search { + width: 100%; + margin-top: 5px; + + border: 1px solid #00000047; + border-radius: 3px; +} + +.cols-list { + border: solid 1px #ccc; + min-height: 60px; + background: white; + border-radius: 4px; + overflow: hidden; + display: block; + width: 400px; + max-width: 100%; + margin-top: 5px; +} + +.col-box { + padding: 2px 10px; + border-bottom: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + box-sizing: border-box; + cursor: move; + background: white; + font-size: 14px; + + &.search:focus { + background: #0000001a; + } + + &.primaryKeyHeaderStyle { + background: #306b0024; + } +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); + z-index: 1300 !important; +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.col-box:last-child { + border: none; +} + +.cols-list.cdk-drop-list-dragging .col-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +// FIXME +// Let's leave it here for a reference if there +// is an issue with viewboxes/filter modal overlaying +// we will remove it if no issues found +// clr-modal.filter-modal { +// ::ng-deep { +// .modal { +// z-index: 1210 !important; +// } +// } +// } + +.disabled { + opacity: 0.5; + transform: none !important; + pointer-events: none; +} + +.filter-active { + color: #0072a3; +} + +hot-table { + ::ng-deep { + .firstColumnHeaderStyle button.changeType { + display: none; + } + + .handsontable tbody th.ht__highlight, .handsontable thead th.ht__highlight { + &.primaryKeyHeaderStyle { + background: #306b00b0; + } + } + + .primaryKeyHeaderStyle { + background: #306b006e; + } + + th.readonlyCell { + div { + opacity: 0.4; + } + } + + td.readonlyCell { + opacity: 0.5 + } + } +} \ No newline at end of file diff --git a/client/src/app/shared/viewboxes/viewboxes.component.ts b/client/src/app/shared/viewboxes/viewboxes.component.ts new file mode 100644 index 0000000..9566441 --- /dev/null +++ b/client/src/app/shared/viewboxes/viewboxes.component.ts @@ -0,0 +1,1304 @@ +import { + CdkDragDrop, + CdkDragEnd, + CdkDragMove, + moveItemInArray, + transferArrayItem +} from '@angular/cdk/drag-drop' +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + EventEmitter, + Input, + NgZone, + OnDestroy, + OnInit, + Output, + QueryList, + ViewChildren +} from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { HotTableRegisterer } from '@handsontable/angular' +import { SASjsConfig } from '@sasjs/adapter' +import Handsontable from 'handsontable' +import { cloneDeep } from 'lodash-es' +import { Subscription } from 'rxjs' +import { FilterQuery, FilterGroup } from 'src/app/models/FilterQuery' +import { Libinfo } from 'src/app/models/sas/common/Libinfo' +import { PublicViewtablesServiceResponse } from 'src/app/models/sas/public-viewtables.model' +import { EventService } from 'src/app/services/event.service' +import { HelperService } from 'src/app/services/helper.service' +import { LicenceService } from 'src/app/services/licence.service' +import { LoggerService } from 'src/app/services/logger.service' +import { SasStoreService } from 'src/app/services/sas-store.service' +import { SasService } from 'src/app/services/sas.service' +import { AutocompleteComponent } from 'src/app/shared/autocomplete/autocomplete.component' +import { LibraryClickEmitter } from 'src/app/shared/dc-tree/models/LibraryClickEmitter' +import { TableClickEmitter } from 'src/app/shared/dc-tree/models/TableClickEmitter' +import { mergeColsRules } from 'src/app/shared/dc-validator/utils/mergeColsRules' +import { globals, initFilter } from 'src/app/_globals' +import { ViewboxHotTable } from './models/viewbox-hot-table.model' +import { ViewboxTable } from './models/viewbox-table.model' +import { Viewbox } from './models/viewbox.model' + +@Component({ + selector: 'app-viewboxes', + templateUrl: './viewboxes.component.html', + styleUrls: ['./viewboxes.component.scss'] +}) +export class ViewboxesComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChildren('resizeBox') resizeBoxQuery!: QueryList //make query list, handle multiple + @ViewChildren('dragHandleCorner') + dragHandleCornerQuery!: QueryList + + private _viewboxModal: boolean = false + get viewboxModal(): boolean { + return this._viewboxModal + } + @Input() set viewboxModal(value: boolean) { + // If feature is disabled, prevent modal show up and show demo notice + if (this.licenceState.value.viewbox === false && !!value) { + this.eventService.showDemoLimitModal('Viewboxes') + this.viewboxModalChange.emit(false) + return + } + this._viewboxModal = value + + if (!!value) this.unsetSelectedViewbox() + } + @Output() viewboxModalChange: EventEmitter = + new EventEmitter() + + public libraries!: Array + public tables: any + public libinfo: Libinfo[] | null = null + public librariesLoading: boolean = true + + public viewboxes: Viewbox[] = [] + + public selectedViewbox: Viewbox | undefined + public selectedViewboxTable: ViewboxTable | undefined + + public defaultConfig: Viewbox = { + id: -1, + library: '', + table: '', + width: 500, + height: 300, + x: 0, + y: 150, + columns: [] + } + + public sasjsConfig: SASjsConfig = new SASjsConfig() + + public hotTableDefault: ViewboxHotTable = { + data: [], + headerPks: [], + $dataformats: {}, + allColHeaders: [], + colHeadersHidden: [], + colHeadersVisible: [], + colHeaders: [], + contextMenu: ['copy_with_column_headers', 'copy_column_headers_only'], + copyPaste: { + copyColumnHeaders: true, + copyColumnHeadersOnly: true + }, + columns: [], + cols: [], + height: '100%', + settings: {}, + hiddenColumns: true, + manualColumnMove: false, + afterGetColHeader: undefined, + licenseKey: undefined, + dropdownMenu: undefined + } + public viewboxTables: ViewboxTable[] = [] + private hotTableRegisterer: HotTableRegisterer + + public filteringViewbox: Viewbox | undefined + + public filter: boolean = false + public filterLoading: boolean = false + public clauses: any + public nullVariables: boolean = false + public filterLibds: string | undefined + public _query: Subscription | undefined + + public licenceState = this.licenceService.licenceState + public Infinity = Infinity + + public maxViewboxes: number = + this.licenceState.value.viewbox_limit === Infinity + ? 6 + : this.licenceState.value.viewbox_limit || 6 + + constructor( + private ngZone: NgZone, + private licenceService: LicenceService, + private sasService: SasService, + private eventService: EventService, + private sasStoreService: SasStoreService, + private loggerService: LoggerService, + private helperService: HelperService, + private router: Router, + private activatedRoute: ActivatedRoute, + private cdf: ChangeDetectorRef + ) { + this.hotTableRegisterer = new HotTableRegisterer() + } + + ngOnInit(): void { + // Load libraries + this.sasStoreService + .viewLibs() + .then((res: any) => { + this.libraries = res.saslibs + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + .finally(() => { + this.librariesLoading = false + }) + + // Listen for filtering data + this._query = this.sasStoreService.query.subscribe((query: any) => { + this.clauses = query.obj + this.filterLibds = query.libds + }) + + this.sasjsConfig = this.sasService.getSasjsConfig() + + this.licenceService.hot_license_key.subscribe( + (hot_license_key: string | undefined) => { + this.hotTableDefault.licenseKey = hot_license_key + } + ) + + const viewboxesQueryParam = + this.activatedRoute.snapshot.queryParams.viewboxes + + if (viewboxesQueryParam) { + if (this.licenceState.value.viewbox === false) { + setTimeout(() => + this.eventService.showDemoLimitModal('Linking Viewboxes') + ) + this.router.navigate([], { + relativeTo: this.activatedRoute, + queryParams: {} + }) + } else { + this.viewboxes = this.decodeUrlData(viewboxesQueryParam) + + setTimeout(() => { + this.setAllHandleTransform() + }) + } + } + + this.reLoadViewboxtables(this.viewboxes) + } + + ngAfterViewInit(): void { + //set handles for box resize + } + + // Maximum number of open viewboxes reached + get viewboxLimitReached(): boolean { + return this.viewboxes.length >= this.maxViewboxes + } + + clrModalOpenChange(open: boolean) { + this.viewboxModalChange.emit(open) + } + + libraryOnClick(data: LibraryClickEmitter) { + if (!data.tablesLoaded) + this.loadTables(data.library.LIBRARYREF, data.library) + } + + /** + * Adding new Viewbox - Fired when table is selected from the `dc-tree` + * @param data Selected table data coming from the `dc-tree` + */ + async tableOnClick(data: TableClickEmitter) { + if (this.viewboxLimitReached) return + + const viewbox = { + ...this.defaultConfig, + table: data.libTable, + library: data.library.LIBRARYNAME, + loadingData: true, + filter_pk: '0', + id: this.viewboxes.length + 1, + x: window.innerWidth - this.defaultConfig.width, + y: 150 + } + + this.viewboxes.push(viewbox) + + setTimeout(() => { + this.setAllHandleTransform() + }) + + const libDataset = `${data.library.LIBRARYREF}.${data.libTable}` + + await this.loadData(libDataset, viewbox) + + viewbox.loadingData = false + this.eventService.dispatchEvent('resize') //Force HOT refresh + this.snapToGrid() //it will call viewboxChanged + } + + /** + * Laods tables to populate `dc-tree` + * @param lib + * @param library + */ + loadTables(lib: string, library?: any) { + this.sasStoreService + .viewTables(lib) + .then((res: PublicViewtablesServiceResponse) => { + let tables = res.mptables.map(function (item: any) { + return item.MEMNAME + }) + + this.libinfo = res.libinfo || [] + this.tables = tables + + if (library) { + library['tables'] = tables + library['libinfo'] = this.libinfo + library['loadingTables'] = false + + if (tables.length > 0) library['expanded'] = true + } + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + } + + /** + * Re-loads data particular Viewbox (preserving the filtering PK) + * @param libDataset library.table + * @param viewbox viewbox to reload data for + * @returns Promise + */ + async reloadData(libDataset: string, viewbox: Viewbox) { + return new Promise((resolve, reject) => { + let viewboxTable = this.viewboxTables.find( + (vbt) => vbt.viewboxId === viewbox.id + ) + + this.sasStoreService + .viewData(libDataset, parseInt(viewbox.filter_pk || '0')) + .then((res: any) => { + if (viewboxTable) { + viewboxTable.hotTable.data = res.viewdata + + resolve(null) + } else { + resolve(null) + } + }) + .catch(() => { + reject() + }) + }) + } + + /** + * Initial data load for particular Viewbox + * If data has been already found for particular Viewbox + * and filtering is not active it will return stored data + * instead of sending new request + * + * @param libDataset library.table + * @param viewbox + * @returns Empty Promise - used for awaiting only + */ + async loadData(libDataset: string, viewbox: Viewbox): Promise { + return new Promise((resolve, reject) => { + let existingViewboxTable: boolean = false + + let viewboxTable = this.viewboxTables.find( + (vbt) => vbt.viewboxId === viewbox.id + ) + if (viewboxTable && (viewbox.filter_pk === '0' || !viewbox.filter_pk)) + resolve() + + this.sasStoreService + .viewData(libDataset, parseInt(viewbox.filter_pk || '0')) + .then((res: any) => { + if (!viewboxTable) { + viewboxTable = { + viewboxId: viewbox.id, + viewboxLibDataset: libDataset, + hotTable: cloneDeep(this.hotTableDefault) + } + } else { + existingViewboxTable = true + } + + viewboxTable.hotTable.data = res.viewdata + viewboxTable.hotTable.$dataformats = res.$viewdata + viewboxTable.hotTable.cols = res.cols + + mergeColsRules(viewboxTable.hotTable.cols, [], res.$viewdata) + + let columns: any[] = [] + let colArr: string[] = [] + + for (let key in res.viewdata[0]) { + if (key) { + colArr.push(key) + } + } + + for (let index = 0; index < colArr.length; index++) { + columns.push({ data: colArr[index] }) + } + + viewboxTable.hotTable.headerPks = cloneDeep( + res.sasparams[0].PK_FIELDS.split(' ') + ) + viewboxTable.hotTable.allColHeaders = colArr.filter( + (col) => !viewboxTable!.hotTable.headerPks.includes(col) + ) + viewboxTable.hotTable.colHeadersHidden = cloneDeep( + viewboxTable.hotTable.allColHeaders + ) + viewboxTable.hotTable.colHeadersVisible = colArr.filter((col) => + viewboxTable!.hotTable.headerPks.includes(col) + ) + + viewboxTable.hotTable.colHeaders = colArr + viewboxTable.hotTable.columns = columns + + if (viewbox.columns && viewbox.columns.length > 0) { + viewboxTable.hotTable.manualColumnMove = viewbox.columns + + viewbox.columns?.map((col: number, index: number) => { + const colProp = colArr[col] + const hiddenColIndex = + viewboxTable!.hotTable.colHeadersHidden.indexOf(colProp) + + if (hiddenColIndex > -1) { + viewboxTable!.hotTable.colHeadersHidden.splice( + hiddenColIndex, + 1 + ) + viewboxTable!.hotTable.colHeadersVisible[index] = colProp + } + }) + } else { + viewboxTable.hotTable.colHeadersVisible.push( + ...viewboxTable.hotTable.colHeadersHidden.splice(0, 10) + ) + } + + viewboxTable.hotTable.colHeadersVisible = + viewboxTable.hotTable.colHeadersVisible.filter((x) => x) //remove empty slots + + if (!existingViewboxTable) this.viewboxTables.push(viewboxTable) + + viewbox.query = this.helperService.deepClone(res.query) + viewbox.filterText = res.sasparams[0].FILTER_TEXT + + setTimeout(() => { + this.updateHotColumns( + viewboxTable!.hotTable.colHeadersHidden || [], + viewbox.id + ) + + // HOT Settings are bound in HTML but some settings due to timing issues + // requires to be updated after the HOT is instanced + // after the update `render` method is called + const hotInstance = this.getViewboxHotInstance(viewbox.id) + + hotInstance?.updateSettings({ + manualColumnMove: viewboxTable!.hotTable.manualColumnMove, + afterGetColHeader: (col: number, th: any) => { + const column = hotInstance?.colToProp(col) as string + + // header columns styling - primary keys + const isPKCol = + column && + viewboxTable!.hotTable.headerPks.indexOf(column) > -1 + + if (isPKCol) th.classList.add('primaryKeyHeaderStyle') + } + }) + hotInstance?.render() + + if (this.selectedViewbox) { + this.resetSelectedViewbox(viewbox) + } + }) + + resolve() + }) + .catch((err: any) => { + this.loggerService.error(err) + + reject() + }) + }) + } + + /** + * Reloads SAS data for each viewbox that exists + * @param viewboxes viewboxes array + */ + reLoadViewboxtables(viewboxes: Viewbox[]) { + viewboxes.map((viewbox: Viewbox) => { + const libDataset = `${viewbox.library}.${viewbox.table}` + viewbox.loadingData = true + + this.loadData(libDataset, viewbox).then(() => { + viewbox.loadingData = false + }) + }) + } + + // HOT cols max width + maxWidthCheker(width: any, col: any) { + if (width > 200) return 200 + else return width + } + + /** + * Used to pair `Viewbox` with it's data + * Which is stored in different array - ViewboxTables + * @param viewbox + */ + getViewboxTableIndex(viewbox: Viewbox): number { + const index = this.viewboxTables.findIndex( + (x) => x.viewboxId === viewbox.id + ) + + return index + } + + /** + * Viewbox resize + * @param dragHandle + * @param target + */ + resize( + dragHandle: HTMLElement, + target: HTMLElement + ): { width: number; height: number } { + const dragRect = dragHandle.getBoundingClientRect() + const targetRect = target.getBoundingClientRect() + + const width = dragRect.left - targetRect.left + dragRect.width + const height = dragRect.top - targetRect.top + dragRect.height + + target.style.width = width + 'px' + target.style.height = height + 'px' + + this.setAllHandleTransform() + + this.helperService.debounceCall(1000, () => { + this.viewboxChanged() + this.eventService.dispatchEvent('resize') + }) + + return { + width, + height + } + } + + /** + * Calls `resize()` outside of angular zone + * Running functions via #runOutsideAngular allows you to escape Angular's + * zone and do work that doesn't trigger Angular change-detection or is subject + * to Angular's error handling. + * @param dragHandle + * @param resizeBox + * @param viewbox + * @param $event + */ + dragMove( + dragHandle: HTMLElement, + resizeBox: any, + viewbox: Viewbox, + $event: CdkDragMove + ) { + this.ngZone.runOutsideAngular(() => { + const newDimnesion = this.resize(dragHandle, resizeBox) + + viewbox.width = newDimnesion.width + viewbox.height = newDimnesion.height + }) + } + + /** + * Sets the 'resize' handle in the correct corner position of the all boxes + */ + setAllHandleTransform() { + this.resizeBoxQuery.forEach((resizeBox: ElementRef) => { + const rect = resizeBox.nativeElement.getBoundingClientRect() + const handleId = `handle_${resizeBox.nativeElement.id}` + + const dragHandleCorner = this.dragHandleCornerQuery.find( + (el, i) => el.nativeElement.id === handleId + ) + this.setHandleTransform(dragHandleCorner?.nativeElement, rect, 'both') + }) + } + + /** + * Sets the 'resize' handle in the correct corner position of the box + */ + setHandleTransform( + dragHandle: HTMLElement, + targetRect: ClientRect | DOMRect, + position: 'x' | 'y' | 'both' + ) { + const dragRect = dragHandle.getBoundingClientRect() + let translateX = targetRect.width - dragRect.width + let translateY = targetRect.height - dragRect.height + + //Fine tune + translateX += 5 + translateY += 5 + + if (position === 'x') { + dragHandle.style.transform = `translate(${translateX}px, 0)` + } + + if (position === 'y') { + dragHandle.style.transform = `translate(0, ${translateY}px)` + } + + if (position === 'both') { + dragHandle.style.transform = `translate(${translateX}px, ${translateY}px)` + } + } + + /** + * When clicked on Viewbox, it will focus it + * Focused Viewbox is always bring to top + * @param viewbox + */ + focusViewbox(viewbox: Viewbox) { + this.viewboxes.map((vbox) => { + vbox.focused = false + }) + + viewbox.focused = true + } + + /** + * On drag end Viewbox position is updated + * As well as the URL + * @param event + * @param viewbox + */ + viewboxDragEnded(event: CdkDragEnd, viewbox: Viewbox) { + let element = event.source.getRootElement() + let boundingClientRect = element.getBoundingClientRect() + + viewbox.x = boundingClientRect.left + viewbox.y = boundingClientRect.top + + this.viewboxChanged() + } + + /** + * Snap to grid calculates the best grid possible + * for given screen width and height + * Configurable options are (in PX): + * gap - gaps between boxes and left/right sides + * topOffset - clearance on the top + * bottomOffset - clearance on the bottom + */ + snapToGrid() { + const windowWidth = window.innerWidth + const windowHeight = window.innerHeight + + const gap = 5 //px configurable + const topOffset = 250 //px configurable + const bottomOffset = 60 //px configurable + + const elementsInTopRow = Math.ceil(this.viewboxes.length / 2) + const elementsInBottomRow = Math.floor(this.viewboxes.length / 2) + const noOfGapsTop = elementsInTopRow + 1 + const noOfGapsBottom = elementsInBottomRow + 1 + const viewboxWidthTop = (windowWidth - gap * noOfGapsTop) / elementsInTopRow + const viewboxWidthBottom = + (windowWidth - gap * noOfGapsBottom) / elementsInBottomRow + + const viewboxHeight = (windowHeight - topOffset - bottomOffset) / 2 + + let x = 0 + let y = topOffset + let height = viewboxHeight + let viewbox_i = 0 + let row_i = 0 + + for (let i = 0; i < this.viewboxes.length; i++) { + let viewbox = this.viewboxes[i] + let topRow = !(i > elementsInTopRow - 1) + const width = topRow ? viewboxWidthTop : viewboxWidthBottom + if (!topRow && row_i === 0) { + viewbox_i = 0 + row_i++ + x = 0 + } + + viewbox.x = gap + x + viewbox_i * (width + gap) + viewbox.y = y + row_i * (height + gap) + viewbox.width = width + viewbox.height = height + + viewbox_i++ + } + + this.viewboxChanged() + + setTimeout(() => { + this.setAllHandleTransform() + }) + } + + minimizeAll() { + this.viewboxes.forEach((viewbox: Viewbox) => { + viewbox.minimized = true + }) + + this.viewboxChanged() + } + + restoreAll() { + this.viewboxes.forEach((viewbox: Viewbox) => { + viewbox.minimized = false + }) + + this.viewboxChanged() + } + + /** + * Resets Viewbox to default position (top right corner) + * @param viewbox + */ + resetPosSize(viewbox: Viewbox) { + viewbox.x = window.innerWidth - this.defaultConfig.width + viewbox.y = this.defaultConfig.y + viewbox.width = this.defaultConfig.width + viewbox.height = this.defaultConfig.height + this.viewboxChanged() + } + + minimize(viewbox: Viewbox) { + viewbox.minimized = true + + this.viewboxChanged() + } + + restore(viewbox: Viewbox) { + viewbox.minimized = false + + this.viewboxChanged() + } + + collapse(viewbox: Viewbox) { + viewbox.collapsed = true + this.viewboxChanged() + } + + expand(viewbox: Viewbox) { + viewbox.collapsed = false + this.viewboxChanged() + } + + /** + * Close Viewbox and remove it's data stored in `paired ViewboxTable array` + * @param viewbox + */ + close(viewbox: Viewbox) { + const index = this.viewboxes.findIndex((vb) => vb.id === viewbox.id) + + const viewtableIndex = this.viewboxTables.findIndex( + (vbt) => vbt.viewboxId === viewbox.id + ) + + if (index > -1) this.viewboxes.splice(index, 1) + if (viewtableIndex > -1) this.viewboxTables.splice(viewtableIndex, 1) + + if (this.selectedViewbox?.id === viewbox.id) { + this.unsetSelectedViewbox() + } + + globals.viewboxes[viewbox.id] = this.helperService.deepClone(initFilter) + + this.viewboxChanged() + } + + /** + * Selects Viewbox in the Viewbox Manager for the columns to be configurated + * @param viewbox + */ + selectViewbox(viewbox: Viewbox) { + if ( + this.selectedViewboxTable === undefined && + this.selectedViewbox === undefined + ) { + this.resetSelectedViewbox(viewbox) + } else { + if (viewbox.id === this.selectedViewbox?.id) { + this.unsetSelectedViewbox() + } else { + this.resetSelectedViewbox(viewbox) + } + } + } + + /** + * Column drop called after column dragged and dropped + * for Viewbox column to be configurated + * @param event + * @returns + */ + columnsDrop(event: CdkDragDrop) { + if (!this.selectedViewboxTable?.hotTable.colHeadersHidden) return + + if (event.previousContainer === event.container) { + moveItemInArray( + event.container.data, + event.previousIndex, + event.currentIndex + ) + } else { + transferArrayItem( + event.previousContainer.data, + event.container.data, + event.previousIndex, + event.currentIndex + ) + } + + if ( + this.selectedViewboxTable.hotTable && + typeof this.selectedViewboxTable.hotTable.colHeaders === 'object' + ) { + const colProp = event.item.data + const finalIndex = event.currentIndex + + this.updateColumnOrderHot( + colProp, + finalIndex, + this.selectedViewboxTable.viewboxId + ) + } + } + + /** + * Viewbox Manager searching for columns to be added + * @param inputRef Input element + * @param value + * @param columns + */ + onColsearchChange( + inputRef: AutocompleteComponent, + value: string, + columns: string[] + ) { + const index = columns.indexOf(value) + + columns.splice(index, 1) + inputRef.value = '' + + if (this.selectedViewboxTable?.hotTable) { + this.selectedViewboxTable.hotTable.colHeadersVisible.push(value) + + this.updateHotColumns( + this.selectedViewboxTable?.hotTable.colHeadersHidden, + this.selectedViewboxTable.viewboxId + ) + + this.updateColumnOrderHot( + value, + this.selectedViewboxTable.hotTable.colHeadersVisible.length - 1, + this.selectedViewboxTable.viewboxId + ) + } + } + + /** + * Viewbox Manager removing the column + * @param column + */ + onColRemove(column: string) { + if (this.selectedViewboxTable?.hotTable) { + const index = + this.selectedViewboxTable.hotTable.colHeadersVisible.indexOf(column) + this.selectedViewboxTable.hotTable.colHeadersVisible.splice(index, 1) + this.selectedViewboxTable.hotTable.colHeadersHidden.push(column) + + this.updateHotColumns( + this.selectedViewboxTable?.hotTable.colHeadersHidden, + this.selectedViewboxTable.viewboxId + ) + + this.updateColumnOrderHot( + column, + this.selectedViewboxTable.hotTable.colHeadersVisible.length, + this.selectedViewboxTable.viewboxId + ) + } + } + + /** + * Re setting the viewbox from parameter to selected viewbox + * And sets the correct data for that viewbox + * @param viewbox + */ + resetSelectedViewbox(viewbox: Viewbox) { + this.selectedViewbox = viewbox + this.selectedViewboxTable = this.viewboxTables.find( + (vbt) => vbt.viewboxId === viewbox.id + ) + } + + unsetSelectedViewbox() { + this.selectedViewbox = undefined + this.selectedViewboxTable = undefined + } + + stopPropagation(event: any) { + event.stopPropagation() + } + + /** + * Opens filter dialog for given Viewbox + * @param viewbox + */ + openFilter(viewbox: Viewbox) { + this.selectViewbox(viewbox) + + const viewboxTable = this.viewboxTables[this.getViewboxTableIndex(viewbox)] + + this.filterLibds = `${viewbox.library}.${viewbox.table}` + this.filteringViewbox = viewbox + + this.filter = true + this.cdf.detectChanges() + + this.sasStoreService.setQueryVariables( + this.filterLibds, + viewboxTable.hotTable.cols + ) + } + + /** + * Opens table edit in new tab + * @param viewbox + */ + openTableEdit(viewbox: Viewbox) { + const libDataset = viewbox.library + '.' + viewbox.table + let url = location.href.slice(0, location.href.indexOf('#')) + url = `${url}#/editor/${libDataset}` + + window.open(url, '_blank') + } + + /** + * Resets the data in filter dialog + * It will also reset the filtering in the given Viewbox + */ + resetFilter() { + if (this.filteringViewbox) { + this.filteringViewbox.filter_pk = '0' + this.reloadTableData(this.filteringViewbox) + this.filter = false + this.viewboxChanged() + globals.viewboxes[this.filteringViewbox.id] = + this.helperService.deepClone(initFilter) + } + } + + /** + * Sending filtering request for given Viewbox + */ + sendClause() { + this.filterLoading = true + let nullVariableArr = [] + let emptyVariablesArr = [] + + // to check number of empty clauses + if (typeof this.clauses === 'undefined') { + this.nullVariables = true + this.filterLoading = false + return + } else { + let query = this.clauses.queryObj + + for (let index = 0; index < query.length; index++) { + const el = query[index].elements + nullVariableArr = el.filter(function (item: any) { + return item.variable === null + }) + if (nullVariableArr.length) { + emptyVariablesArr.push(el) + } + } + } + + if (emptyVariablesArr.length) { + this.nullVariables = true + this.filterLoading = false + return + } else { + try { + if (this.clauses !== undefined && this.filterLibds) { + const filterQuery: FilterQuery = { + groupLogic: this.clauses.groupLogic, + filterGroups: [] + } + this.clauses.queryObj.forEach((group: any) => { + const filterGroup: FilterGroup = { + filterClauses: [] + } + group.elements.forEach((clause: any) => { + filterGroup.filterClauses.push( + this.helperService.deepClone(clause) + ) + }) + filterGroup.clauseLogic = group.clauseLogic + filterQuery.filterGroups.push( + this.helperService.deepClone(filterGroup) + ) + }) + + const filterQueryClauseTable = + this.sasStoreService.createFilterQueryTable(filterQuery) + + this.sasStoreService + .saveQuery(this.filterLibds, filterQueryClauseTable) + .then((res: any) => { + const id = res.result[0].FILTER_RK + const table = res.result[0].FILTER_TABLE + + this.filteringViewbox!.filter_pk = id + this.loadData(this.filterLibds!, this.filteringViewbox!).then( + () => { + this.filter = false + this.filterLoading = false + } + ) + + this.viewboxChanged() + }) + .catch((err: any) => { + this.filterLoading = false + }) + } + } catch (error: any) { + this.filterLoading = false + } + } + } + + async searchTable(inputElement: any, viewbox: Viewbox) { + viewbox.searchLoading = true + + let searchValue = inputElement.value + + let libDataset = viewbox.library + '.' + viewbox.table + let filter_pk = parseInt(viewbox.filter_pk || '0') + + const viewboxTable = this.viewboxTables.find( + (vbt) => vbt.viewboxId === viewbox.id + ) + + if (!viewboxTable) return + + await this.sasStoreService + .viewDataSearch(searchValue, viewbox.searchNumeric, libDataset, filter_pk) + .then((res: any) => { + if (!res.sasparams && !res.viewData) { + viewbox.searchLoading = true + return + } + + viewboxTable.hotTable.data = res.viewdata + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + + viewbox.searchLoading = false + } + + async reloadTableData(viewbox: Viewbox) { + const libDataset = `${viewbox.library}.${viewbox.table}` + + viewbox.loadingData = true + + await this.reloadData(libDataset, viewbox) + + viewbox.loadingData = false + this.eventService.dispatchEvent('resize') //Force HOT refresh + } + + /** + * Updates the HOT columns Order and Visibility + * @param hiddenColProps Array of indexes of columns to be hidden + * @param viewboxId Viewbox ID for which to apply + */ + private updateHotColumns(hiddenColProps: string[], viewboxId: number) { + this.updateHiddenColumnsHot(hiddenColProps, viewboxId) + + this.setColumnOrder(viewboxId) + } + + /** + * HOT Columns ordering + * @param colProp Column name + * @param finalIndex Index of where to position it + * @param viewboxId + */ + private updateColumnOrderHot( + colProp: string, + finalIndex: number, + viewboxId: number + ) { + const hotInstance = this.getViewboxHotInstance(viewboxId) + + if (hotInstance) { + const column = hotInstance.propToCol(colProp) + const plugin = hotInstance.getPlugin('manualColumnMove') + + plugin.moveColumn(column, finalIndex) + hotInstance.render() + + this.setColumnOrder(viewboxId) + } + } + + public tableEditExists(viewbox: Viewbox) { + const editTables = globals.editor.libsAndTables + const library = viewbox.library + const table = viewbox.table + + // If this line is undefined, that means startupservice failed or similar. + if (!editTables[library]) return false + + return editTables[library].includes(table) + } + + private setColumnOrder(viewboxId: number) { + const viewbox = this.viewboxes.find((vb) => vb.id === viewboxId) + + if (viewbox) { + const columnsOrder = this.createColumnOrder(viewboxId) + viewbox.columns = columnsOrder.length > 0 ? columnsOrder : viewbox.columns + } + + this.viewboxChanged() + } + + /** + * Creating column order in such format to be encoded in URL + * @param viewboxId + */ + private createColumnOrder(viewboxId: number): number[] { + const hotInstance = this.getViewboxHotInstance(viewboxId) + if (!hotInstance) return [] + + const hotCols = hotInstance.getColHeader() as string[] + const sasCols = this.selectedViewboxTable?.hotTable.colHeaders as string[] + + if (!sasCols) return [] + + const columnsVisibleLength: number = + this.selectedViewboxTable?.hotTable?.colHeadersVisible.length || 5 //if unexpected happens limit will Be 5 columns + const columnOrder: number[] = [] + + hotCols.map((hotCol: string, index: number) => { + if (index < columnsVisibleLength) { + const indexofSasCol = sasCols.indexOf(hotCol) + + if (indexofSasCol > -1) columnOrder.push(indexofSasCol) + } + }) + + return columnOrder + } + + private updateHiddenColumnsHot(colProps: string[], viewboxId: number) { + const hotInstance = this.getViewboxHotInstance(viewboxId) + + if (hotInstance) { + const columns = colProps.map((prop: string) => { + return hotInstance.propToCol(prop) + }) + + hotInstance.updateSettings({ + hiddenColumns: { + columns: columns + } + }) + + hotInstance.render() + } + } + + /** + * + * @param viewboxId + * @returns HOT Instance from the given Viewbox + */ + private getViewboxHotInstance(viewboxId?: number): Handsontable | undefined { + if (!viewboxId) return + + const hotInstance = this.hotTableRegisterer.getInstance( + `hotInstance_viewbox_${viewboxId}` + ) + + return hotInstance + } + + /** + * Called after any Viewbox change that needs to be stored to URL + * It does the data encoding and storing to URL + */ + private viewboxChanged() { + let queryParams: any + const urlData = this.encodeUrlData(this.viewboxes) + + if (urlData.length > 0) { + queryParams = { + viewboxes: urlData + } + } + + this.router.navigate([], { + relativeTo: this.activatedRoute, + queryParams + }) + + this.prepareFilterCache() + } + + /** + * Prepare the init values to `globals` for the filtering + * that will be used in caching values later + */ + private prepareFilterCache() { + for (let viewbox of this.viewboxes) { + if (!globals.viewboxes[viewbox.id]) + globals.viewboxes[viewbox.id] = this.helperService.deepClone(initFilter) + + if (viewbox.query && viewbox.query.length > 0) { + const viewboxTable = this.viewboxTables.find( + (vbt) => vbt.viewboxId === viewbox.id + ) + const globalsPath = `viewboxes.${viewbox.id}` + + globals.viewboxes[viewbox.id].filter.query = viewbox.query + globals.viewboxes[viewbox.id].filter.libds = + viewbox.library + '.' + viewbox.table + this.sasStoreService.initializeGlobalFilterClause( + globalsPath, + viewboxTable?.hotTable.cols + ) + } + } + } + + /** + * It will encode/inject viewboxes data from URL + * Url data pattern: + * + * {id}-{library}-{table}-{width}-{height}-{x}-{y}-{collapsed}-{minimized}-{filter_pk}-{columns} + * 1-library-table-100-100-10-10-1-1;library2-table2-100-100-10-10-0-0-3-0123456 + * + * ; <- single viewbox separation symbol + */ + private encodeUrlData(viewboxes: Viewbox[]): string { + let urlData: string = '' + + viewboxes.map((viewbox: Viewbox, index: number) => { + urlData += `${viewbox.id}-${viewbox.library}-${viewbox.table}-${ + viewbox.width + }-${viewbox.height}-${viewbox.x}-${viewbox.y}-${ + viewbox.collapsed ? 1 : 0 + }-${viewbox.minimized ? 1 : 0}-${viewbox.filter_pk || 0}${ + viewbox.columns && viewbox.columns.length > 0 + ? '-' + viewbox.columns?.join(',') + : '' + }` + + if (index !== viewboxes.length - 1) urlData += ';' + }) + + return urlData + } + + /** + * It will decode/parse viewboxes data from URL + * Url data pattern: + * + * {id}-{library}-{table}-{width}-{height}-{x}-{y}-{collapsed}-{minimized}-{filter_pk}-{columns} + * 1-library-table-100-100-10-10-1-1;library2-table2-100-100-10-10-0-0-3-0123456 + * + * ; <- single viewbox separation symbol + */ + private decodeUrlData(urlData: string): Viewbox[] { + const urlDataMap = { + id: 0, + library: 1, + table: 2, + width: 3, + height: 4, + x: 5, + y: 6, + collapsed: 7, + minimized: 8, + filter_pk: 9, + columns: 10 + } + + let viewboxes: Viewbox[] = [] + + const separatedViewboxes = urlData.split(';') + + separatedViewboxes.map((viewboxString: string) => { + const viewboxDataArr = viewboxString.split('-') + + viewboxes.push({ + id: parseInt(viewboxDataArr[urlDataMap.id]), + library: viewboxDataArr[urlDataMap.library], + table: viewboxDataArr[urlDataMap.table], + width: parseInt(viewboxDataArr[urlDataMap.width]), + height: parseInt(viewboxDataArr[urlDataMap.height]), + x: parseInt(viewboxDataArr[urlDataMap.x]), + y: parseInt(viewboxDataArr[urlDataMap.y]), + collapsed: !!parseInt(viewboxDataArr[urlDataMap.collapsed]), + minimized: !!parseInt(viewboxDataArr[urlDataMap.minimized]), + columns: + viewboxDataArr[urlDataMap.columns] + ?.split(',') + .map((x) => parseInt(x)) || [], + filter_pk: viewboxDataArr[urlDataMap.filter_pk] + }) + }) + + return viewboxes + } + + ngOnDestroy(): void { + this._query?.unsubscribe() + } +} diff --git a/client/src/app/shared/viewboxes/viewboxes.module.ts b/client/src/app/shared/viewboxes/viewboxes.module.ts new file mode 100644 index 0000000..79c9bec --- /dev/null +++ b/client/src/app/shared/viewboxes/viewboxes.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { ViewboxesComponent } from './viewboxes.component' +import { QueryModule } from 'src/app/query/query.module' +import { HotTableModule } from '@handsontable/angular' +import { DragDropModule } from '@angular/cdk/drag-drop' +import { AutocompleteModule } from '../autocomplete/autocomplete.module' +import { DcTreeModule } from '../dc-tree/dc-tree.module' +import { DirectivesModule } from 'src/app/directives/directives.module' + +@NgModule({ + declarations: [ViewboxesComponent], + imports: [ + CommonModule, + ClarityModule, + CommonModule, + FormsModule, + QueryModule, + HotTableModule, + DragDropModule, + AutocompleteModule, + DcTreeModule, + DirectivesModule + ], + exports: [ViewboxesComponent] +}) +export class ViewboxesModule {} diff --git a/client/src/app/stage/stage.component.html b/client/src/app/stage/stage.component.html new file mode 100644 index 0000000..5b4b1d5 --- /dev/null +++ b/client/src/app/stage/stage.component.html @@ -0,0 +1,113 @@ +
+
+
+ Loading... +
+

Loading submitted table

+
+
+
+
+
+

Staged Data

+
+
+
+
+
+
Basic Submitted Details
+
+
+ Table Id: + + {{ tableDetails?.TABLE_ID }} + +
+ +
+ Submit Date: + + {{ tableDetails?.SUBMITTED_ON_DTTM }} + +
+
+ Review Status: + + {{ tableDetails?.REVIEW_STATUS_ID }} + +
+
+
+
+
Actions
+
+
+
+ + + + +
+
+
+
+
+ + + +
+ + +
+
+
diff --git a/client/src/app/stage/stage.component.scss b/client/src/app/stage/stage.component.scss new file mode 100644 index 0000000..f6b66d2 --- /dev/null +++ b/client/src/app/stage/stage.component.scss @@ -0,0 +1,15 @@ +.rejected { + color: #f83126; + font-weight: bold +} + +.accepted { + color: #3fc424; + font-weight: bold +} + +.baseTableLink { + cursor:pointer; + margin-top:10px; + color: #007cbb; +} \ No newline at end of file diff --git a/client/src/app/stage/stage.component.ts b/client/src/app/stage/stage.component.ts new file mode 100644 index 0000000..deaaa5e --- /dev/null +++ b/client/src/app/stage/stage.component.ts @@ -0,0 +1,164 @@ +import { Component, OnInit } from '@angular/core' +import { SasStoreService } from '../services/sas-store.service' +import { Router } from '@angular/router' +import { ActivatedRoute } from '@angular/router' +import { SasService } from '../services/sas.service' +import { EventService } from '../services/event.service' +import { AppService } from '../services/app.service' +import { HotTableInterface } from '../models/HotTable.interface' +import { LicenceService } from '../services/licence.service' + +@Component({ + selector: 'app-stage', + templateUrl: './stage.component.html', + styleUrls: ['./stage.component.scss'], + host: { + class: 'content-container' + } +}) +export class StageComponent implements OnInit { + public table_id: any + public jsParams: any + public keysArray: any + public tableDetails: any + public loaded: boolean = false + public licenceState = this.licenceService.licenceState + public hotTable: HotTableInterface = { + data: [], + colHeaders: [], + columns: [], + height: 500, + settings: {}, + licenseKey: undefined, + maxRows: this.licenceState.value.stage_rows_allowed || Infinity + } + + constructor( + private licenceService: LicenceService, + private sasStoreService: SasStoreService, + private eventService: EventService, + private route: Router, + private router: ActivatedRoute, + private sasService: SasService + ) {} + + public submittedTableScreen() { + this.route.navigateByUrl('/stage/' + this.table_id) + } + + public approveTableScreen() { + this.route.navigateByUrl('/approve/approveDet/' + this.table_id) + } + + public viewerTableScreen() { + this.route.navigateByUrl('/view/data/' + this.tableDetails.BASE_TABLE) + } + + public goBack() { + this.route.navigateByUrl('/editor/' + this.tableDetails.BASE_TABLE) + } + + public download(id: any) { + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = this.sasService.getExecutionPath() + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/auditors/getauditfile&table=' + + id + window.open(downUrl) + } + + async ngOnInit() { + this.licenceService.hot_license_key.subscribe( + (hot_license_key: string | undefined) => { + this.hotTable.licenseKey = hot_license_key + } + ) + + if (typeof this.router.snapshot.params['tableId'] !== 'undefined') { + this.table_id = this.router.snapshot.params['tableId'] + + try { + let res = await this.sasStoreService.getChangeInfo(this.table_id) + + if (!(res && res.jsparams)) + throw new Error('jsparams property is missing from response.') + + this.tableDetails = res.jsparams[0] + } catch (error: any) { + let errorObject: any = {} + + if (!error.MESSAGE) { + errorObject.MESSAGE = error + } else { + errorObject = error + } + + this.eventService.catchResponseError( + 'public/getchangeinfo', + errorObject + ) + } + + try { + let res = await this.sasStoreService.openTable(this.table_id) + + if (!(res && res.stagetable)) + throw new Error('Stagetable property is missing from response.') + + let cols = res.stagetable[0] + let colHeaders = [] + let columns: any[] = [] + + for (let key in cols) { + if (cols) { + colHeaders.push(key) + } + } + + for (let index = 0; index < colHeaders.length; index++) { + columns.push({ + data: colHeaders[index] + }) + } + + let cells = function () { + let cellProperties = { readOnly: true } + return cellProperties + } + + this.hotTable.data = res.stagetable + this.hotTable.colHeaders = colHeaders + this.hotTable.columns = columns + this.hotTable.cells = cells + + this.loaded = true + this.setFocus() + } catch (error: any) { + let errorObject: any = {} + + if (!error.MESSAGE) errorObject.MESSAGE = error + + this.eventService.catchResponseError( + 'auditors/getstagetable', + errorObject + ) + this.loaded = false + } + } + } + + private setFocus() { + setTimeout(() => { + let approvalBtn: any = window.document.getElementById('approval-btn') + if (!!approvalBtn) { + approvalBtn.focus() + } + }, 200) + } +} diff --git a/client/src/app/stage/stage.module.ts b/client/src/app/stage/stage.module.ts new file mode 100644 index 0000000..edeba81 --- /dev/null +++ b/client/src/app/stage/stage.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { StageComponent } from './stage.component' +import { HotTableModule } from '@handsontable/angular' +import { ClarityModule } from '@clr/angular' +import { RouterModule, Routes } from '@angular/router' + +const routes: Routes = [{ path: ':tableId', component: StageComponent }] + +@NgModule({ + declarations: [StageComponent], + imports: [ + CommonModule, + ClarityModule, + RouterModule.forChild(routes), + HotTableModule.forRoot() + ] +}) +export class StageModule {} diff --git a/client/src/app/submitter/submitter.component.html b/client/src/app/submitter/submitter.component.html new file mode 100644 index 0000000..f9e6547 --- /dev/null +++ b/client/src/app/submitter/submitter.component.html @@ -0,0 +1,116 @@ +
+
+
+
+ +
+
+

+ SUBMIT QUEUE +

+

+ You have {{ remained }} submissions waiting to be + approved +

+
+ +
+ Loading... +
+

Loading submitted list

+
+
+
+
+ + BASE TABLE + SUBMITTED + SUBMIT REASON + ACTION + DOWNLOAD + + {{ sub.base }} + {{ sub.submitted }} + + {{ sub.submitReason }} + + + + + + + + + + items per page + + + {{ pagination.firstItem + 1 }} - + {{ pagination.lastItem + 1 }} of + {{ pagination.totalItems }} submissions + + + +
+
+
+
+ +
+ +
+
diff --git a/client/src/app/submitter/submitter.component.scss b/client/src/app/submitter/submitter.component.scss new file mode 100644 index 0000000..452434c --- /dev/null +++ b/client/src/app/submitter/submitter.component.scss @@ -0,0 +1,15 @@ +.noBorder { + border-bottom: 1px solid transparent!important; +} + +.tooltip.tooltip-bottom-left>.tooltip-content, .tooltip .tooltip-content.tooltip-bottom-left { + background: #314351!important; +} +.tooltip.tooltip-bottom-left>.tooltip-content:before, .tooltip .tooltip-content.tooltip-bottom-left:before { + border-right: .25rem solid #314351; + border-bottom: .20833rem solid #314351; +} + +.no-submitted-tables { + height: calc(100vh - 200px); +} \ No newline at end of file diff --git a/client/src/app/submitter/submitter.component.ts b/client/src/app/submitter/submitter.component.ts new file mode 100644 index 0000000..9391b02 --- /dev/null +++ b/client/src/app/submitter/submitter.component.ts @@ -0,0 +1,127 @@ +import { Component, AfterViewInit, OnInit } from '@angular/core' +import { Subscription } from 'rxjs' +import { SasStoreService } from '../services/sas-store.service' +import { ActivatedRoute, Router } from '@angular/router' +import { SasService } from '../services/sas.service' +import { EventService } from '../services/event.service' + +interface SubmitterData { + tableId: string + base: string + submitted: string + submitReason: string + approver: string +} + +@Component({ + selector: 'app-submitter', + templateUrl: './submitter.component.html', + styleUrls: ['./submitter.component.scss'], + host: { + class: 'content-container' + } +}) +export class SubmitterComponent implements OnInit, AfterViewInit { + public remained: number = 0 + public itemsNum!: number + public submitterList!: SubmitterData[] + public loaded: boolean = false + public subReady: boolean = false + public detailsOpen: boolean = false + public submitter!: string + public submitData!: Array + private _readySub!: Subscription + private _backToSub!: Subscription + + constructor( + private sasStoreService: SasStoreService, + private eventService: EventService, + private router: Router, + private route: ActivatedRoute, + private sasService: SasService + ) {} + + public goToStage(table_id: any) { + this.router.navigateByUrl('/stage/' + table_id) + } + + public goToDetails(table_id: any) { + this.router.navigateByUrl('/submitted/' + table_id) + } + + public getDetails(sub: any, index: any) { + this.subReady = true + setTimeout(() => { + this.sasStoreService.sendDetails(sub, index, this.submitData) + }, 0) + } + + async ngOnInit() { + const tableIdParam = this.route.snapshot.params['tableId'] + + this.itemsNum = 10 + try { + let res = await this.sasStoreService.getSubmitts() + + this.remained = res.fromsas.length + if (this.remained > 0) { + this.submitter = res.fromsas[0].SUBMITTED_BY_NM + let submitterList: SubmitterData[] = res.fromsas.map(function ( + item: any + ) { + return { + tableId: item.TABLE_ID, + base: item.BASE_TABLE, + submitted: item.SUBMITTED_ON_DTTM, + submitter: item.SUBMITTED_BY_NM, + submitReason: item.SUBMITTED_REASON_TXT + } + }) + this.submitterList = submitterList + this.submitData = res.fromsas + + // Details page + if (typeof tableIdParam !== 'undefined') { + const submitterIndex = this.submitterList.findIndex( + (x) => x.tableId === tableIdParam + ) + + if (submitterIndex > -1) { + const submitter = this.submitterList[submitterIndex] + + this.getDetails(submitter, submitterIndex) + } + } + } + this.loaded = true + } catch (error) { + this.eventService.catchResponseError('editors/getsubmits', error) + } + } + + ngAfterViewInit() { + this._readySub = this.sasStoreService.setSubmit.subscribe((sub) => { + this.subReady = sub + }) + + this._backToSub = this.sasStoreService.setSubmitList.subscribe((sub) => { + this.subReady = !this.subReady + this.detailsOpen = false + }) + } + + public download(id: any) { + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = this.sasService.getExecutionPath() + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/auditors/getauditfile&table=' + + id + window.open(downUrl) + } +} diff --git a/client/src/app/system/models/app-info.model.ts b/client/src/app/system/models/app-info.model.ts new file mode 100644 index 0000000..36c00bd --- /dev/null +++ b/client/src/app/system/models/app-info.model.ts @@ -0,0 +1,5 @@ +export interface AppInfo { + adapterVersion: string + appVersion: string + buildTimestamp: string +} diff --git a/client/src/app/system/models/environment-info.model.ts b/client/src/app/system/models/environment-info.model.ts new file mode 100644 index 0000000..b44ae44 --- /dev/null +++ b/client/src/app/system/models/environment-info.model.ts @@ -0,0 +1,14 @@ +export interface EnvironmentInfo { + SYSSITE: string + SYSSCPL: string + SYSTCPIPHOSTNAME: string + SYSVLONG: string + MEMSIZE: string + SYSPROCESSMODE: string + SYSHOSTNAME: string + SYSHOSTINFOLONG: string + SYSENCODING: string + AUTOEXEC: string + ISADMIN: number + DC_ADMIN_GROUP: string +} diff --git a/client/src/app/system/system.component.html b/client/src/app/system/system.component.html new file mode 100644 index 0000000..bf7401a --- /dev/null +++ b/client/src/app/system/system.component.html @@ -0,0 +1,248 @@ +
+
+

System information

+
+
+
+
+
Environment Details
+

+ SYSSITE: {{ environmentInfo?.SYSSITE }} +

+

+ SYSSCPL: {{ environmentInfo?.SYSSCPL }} +

+

+ SYSTCPIPHOSTNAME: + {{ environmentInfo?.SYSTCPIPHOSTNAME }} +

+

+ SYSVLONG: {{ environmentInfo?.SYSVLONG }} +

+

+ MEMSIZE: {{ environmentInfo?.MEMSIZE }} +

+

+ SYSPROCESSMODE: + {{ environmentInfo?.SYSPROCESSMODE }} +

+

+ SYSHOSTNAME: + {{ environmentInfo?.SYSHOSTNAME }} +

+

+ SYSHOSTINFOLONG: + {{ environmentInfo?.SYSHOSTINFOLONG }} +

+

+ SYSENCODING: + {{ environmentInfo?.SYSENCODING }} +

+

+ AUTOEXEC: {{ environmentInfo?.AUTOEXEC }} +

+

+ DC ADMIN GROUP: + {{ environmentInfo?.DC_ADMIN_GROUP }} +

+
+ +
+
+
+ Data Controller Details +
+

+ Application version: + {{ appInfo.appVersion }} +

+

+ Build timestamp: + {{ appInfo.buildTimestamp }} +

+

+ Adapter version: + {{ appInfo.adapterVersion }} +

+

+ HTTP: {{ http ? 'YES' : 'NO' }} +

+
+
+ +
+
Licence details
+

+ Valid until: + {{ licenceInfo?.valid_until }} +

+

+ Users allowed: + {{ licenceInfo?.users_allowed }} +

+

+ Site IDs: + {{ licenceInfo?.site_id_multiple }} +

+

+ Free Tier: + {{ licenceInfo?.demo ? 'YES' : 'NO' }} +

+

+ Viewer rows limit: + {{ + licenceState.value.viewer_rows_allowed + }} +

+

+ Editor rows limit: + {{ + licenceState.value.editor_rows_allowed + }} +

+

+ Stage rows limit: + {{ + licenceState.value.stage_rows_allowed + }} +

+

+ History rows limit: + {{ + licenceState.value.history_rows_allowed + }} +

+

+ Submit rows limit: + {{ licenceState.value.submit_rows_limit }} +

+

+ Tables in library limit: + {{ + licenceState.value.tables_in_library_limit + }} +

+

+ Viewboxes limit: + {{ licenceState.value.viewbox_limit }} +

+

+ Lineage daily limit: + {{ + licenceState.value.lineage_daily_limit + }} +

+

+ Viewboxes: + {{ + licenceState.value.viewbox ? 'YES' : 'NO' + }} +

+

+ File Upload: + {{ + licenceState.value.fileUpload ? 'YES' : 'NO' + }} +

+

+ Edit record: + {{ + licenceState.value.editRecord ? 'YES' : 'NO' + }} +

+

+ Add record: + {{ + licenceState.value.addRecord ? 'YES' : 'NO' + }} +

+
+
+ +
+ + +
+ Refresh Data Lineage + + +
+ +
+ Refresh Data Catalog + + +
+ +
+ Download Configuration + + +
+ +
+ Update Licence Key + + +
+
+
+
+
+ + + + + + diff --git a/client/src/app/system/system.component.scss b/client/src/app/system/system.component.scss new file mode 100644 index 0000000..307e7db --- /dev/null +++ b/client/src/app/system/system.component.scss @@ -0,0 +1,41 @@ +.content-box { + max-width: 1289px; +} + +.sys-info { + >div { + // width: 238px; + flex: 1; + } + div:nth-child(2) { + margin: 0 30px; + } +} + +.admin-action { + display: flex; + justify-content: space-between; + align-items: center; + padding: 5px 10px; + border-radius: 6px; + border: 1px solid #dedede; + margin-bottom: 5px; + + button { + min-width: 102px; + } +} + +.dark { + color: black; +} + +@media (max-width: 993px) { + .sys-info div:nth-child(2) { + margin: 0; + } + + .sys-info div { + margin: 20px 0; + } +} \ No newline at end of file diff --git a/client/src/app/system/system.component.ts b/client/src/app/system/system.component.ts new file mode 100644 index 0000000..e956dc6 --- /dev/null +++ b/client/src/app/system/system.component.ts @@ -0,0 +1,107 @@ +import { Component, OnInit } from '@angular/core' +import moment from 'moment' +import { VERSION } from 'src/environments/version' +import { LicenseKeyData } from '../models/LicenseKeyData' +import { AppService } from '../services/app.service' +import { LicenceService } from '../services/licence.service' +import { SasService } from '../services/sas.service' +import { AppInfo } from './models/app-info.model' +import { EnvironmentInfo } from './models/environment-info.model' + +@Component({ + selector: 'app-system', + templateUrl: './system.component.html', + styleUrls: ['./system.component.scss'], + host: { + class: 'content-container' + } +}) +export class SystemComponent implements OnInit { + appInfo: AppInfo = { + adapterVersion: VERSION.adapterVersion || 'n/a', + appVersion: (VERSION.tag || '').replace('v', ''), + buildTimestamp: moment(parseInt(VERSION.timestamp)).format( + 'DD-MMM-YYYY HH:MM' + ) + } + serverType: string + environmentInfo: EnvironmentInfo | null + licenceInfo: LicenseKeyData | null + http: boolean = location.protocol === 'http:' + refreshingDataCatalog: boolean = false + refreshingDataLineage: boolean = false + response: string = 'No response' + responseModal: boolean = false + + Infinity = Infinity + + licenceState = this.licenceService.licenceState + + constructor( + private appService: AppService, + private sasService: SasService, + private licenceService: LicenceService + ) { + this.serverType = this.sasService.getServerType() + this.licenceInfo = this.licenceService.getLicenseKeyData() + this.environmentInfo = this.appService.getEnvironmentInfo() + + if (this.environmentInfo) { + this.environmentInfo.AUTOEXEC = decodeURIComponent( + this.environmentInfo.AUTOEXEC + ) + } + } + + ngOnInit(): void {} + + downloadConfiguration() { + let sasjsConfig = this.sasService.getSasjsConfig() + let storage = sasjsConfig.serverUrl + let metaData = sasjsConfig.appLoc + let path = this.sasService.getExecutionPath() + let downUrl = + storage + path + '/?_program=' + metaData + '/services/admin/exportconfig' + window.open(downUrl) + } + + refreshDataCatalog() { + this.refreshingDataCatalog = true + + this.sasService + .request('admin/refreshcatalog', null) + .then((res: any) => { + this.response = this.parseResponse(res) + this.responseModal = true + }) + .catch((err: any) => { + this.response = this.parseResponse(err) + this.responseModal = true + }) + .finally(() => { + this.refreshingDataCatalog = false + }) + } + + refreshDataLineage() { + this.refreshingDataLineage = true + + this.sasService + .request('admin/refreshtablelineage', null) + .then((res: any) => { + this.response = this.parseResponse(res) + this.responseModal = true + }) + .catch((err: any) => { + this.response = this.parseResponse(err) + this.responseModal = true + }) + .finally(() => { + this.refreshingDataLineage = false + }) + } + + private parseResponse(res: any) { + return typeof res === 'object' ? JSON.stringify(res) : res + } +} diff --git a/client/src/app/user/user.component.html b/client/src/app/user/user.component.html new file mode 100644 index 0000000..9a01a7b --- /dev/null +++ b/client/src/app/user/user.component.html @@ -0,0 +1,209 @@ + + + +
+ + + +
+
+ + +

+ + {{ user.NAME }} +

+
+
+
+
+ +
+
+ Loading... +
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + + + + + + + +
+
+ +
+
+
+
+

EMAILS ({{ userEmailsCount || '0' }})

+
No Emails Present
+
+ + + + + + + + + + + + + +
EMAILTYPE
{{ email.EMAIL }}{{ email.TYPE }}
+
+
+
+
+

GROUPS ({{ userGroupsCount || '0' }})

+
No Groups Present
+
+ + + + + + + + + +
+ {{ group.GROUPNAME }} + + {{ group.GROUPNAME }} +
+
+
+
+
+

ROLES ({{ userRolesCount || '0' }})

+
No Roles Present
+
+ + + + + + +
+ {{ role.ROLENAME }} +
+
+
+
+
+

LOGINS ({{ userLoginsCount || '0' }})

+
No Logins Present
+
+ + + + + + + + + + + + + +
DOMAINUSER ID
{{ login.DOMAIN }}{{ login.USERID }}
+
+
+
+
+
+
+
+
diff --git a/client/src/app/user/user.component.scss b/client/src/app/user/user.component.scss new file mode 100644 index 0000000..9adb276 --- /dev/null +++ b/client/src/app/user/user.component.scss @@ -0,0 +1,57 @@ +.sidebar-height{ + height: 100%; +} +.user-info-text{ + display: inline; + font-size: 20px; +} +.user-info{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.user-info td{ + text-align: center; +} +.user-data{ + background-color: #f9f9f9; + border: 1px solid #a7a7a7; + border-radius: 3px; + box-shadow: 0px 2px 5px #dad7d7; +} +.user-data{ + min-height: auto; + h3, h5{ + text-align: center; + } +} + +.user-table{ + background-color: #f9f9f9; + width: 100%; +} +.user-table thead{ + background-color: #dadada; +} +.user-table tbody{ + tr:hover{ + background-color: #e6e6e6; + cursor: pointer; + } +} +.width-50{ + width: 50%; +} +.width-33{ + width: 33%; +} +.table-container{ + overflow-y: scroll; + max-height: 500px; +} +@media screen and (max-width: 768px){ + .user-data{ + min-height: unset !important; + } +} \ No newline at end of file diff --git a/client/src/app/user/user.component.ts b/client/src/app/user/user.component.ts new file mode 100644 index 0000000..bc7ee21 --- /dev/null +++ b/client/src/app/user/user.component.ts @@ -0,0 +1,285 @@ +import { Component, OnInit } from '@angular/core' +import { globals } from '../_globals' +import { HelperService } from '../services/helper.service' +import { Router, ActivatedRoute } from '@angular/router' +import { Location } from '@angular/common' +import { SasService } from '../services/sas.service' +import { SASjsConfig } from '@sasjs/adapter' +import { ServerType } from '@sasjs/utils/types/serverType' + +@Component({ + selector: 'app-user', + templateUrl: './user.component.html', + styleUrls: ['./user.component.scss'], + host: { + class: 'content-container' + } +}) +export class UserComponent implements OnInit { + public users: Array | undefined + public loading: boolean = false + public userSearch: string = '' + public userData: Array | undefined + public userInfo: any | undefined + public userEmails: Array | undefined + public userEmailsCount: number | undefined + public userGroups: Array | undefined + public userGroupsCount: number | undefined + public userRoles: Array | undefined + public userRolesCount: number | undefined + public userLogins: Array | undefined + public userLoginsCount: number | undefined + public paramPresent: boolean = false + public paramName: string = '' + public sasjsConfig: SASjsConfig = new SASjsConfig() + public isViya: boolean = false + public serverType: string = '' + + ServerType = ServerType + + constructor( + private helperService: HelperService, + private sasService: SasService, + public route: ActivatedRoute, + private location: Location, + public router: Router + ) { + this.serverType = this.sasService.getServerType() + + this.sasjsConfig = this.sasService.getSasjsConfig() + if (this.sasjsConfig.serverType === 'SASVIYA') { + this.isViya = true + } + } + + ngOnInit() { + globals.viewer.currentSelection = 'view/usernav/users' + if (this.route.snapshot.params['uri'] !== undefined) { + this.paramPresent = true + this.paramName = this.route.snapshot.params['uri'] + } + if (globals.usernav.userList && !this.paramPresent) { + this.users = globals.usernav.userList + this.userSearch = globals.usernav.userSearch + } else { + if (globals.usernav.userList === undefined) { + this.loading = true + if (this.isViya) { + fetch(this.sasjsConfig.serverUrl + '/identities/users?limit=2000', { + headers: { + Accept: 'application/json' + } + }) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + let users = jsonRes.items.map((user: any) => { + return { + NAME: user.name, + URI: user.id, + PROVIDER: user.providerId + } + }) + this.loading = false + this.users = users + globals.usernav.userList = users + }) + } else { + this.sasService + .request('usernav/usermembers', null) + .then((res: any) => { + this.loading = false + this.users = res.users + globals.usernav.userList = res.users + }) + } + } else { + this.users = globals.usernav.userList + this.userSearch = globals.usernav.userSearch + } + if (this.paramPresent) { + this.loading = true + + if (this.isViya) { + let uri = this.route.snapshot.params['uri'] + fetch( + this.sasjsConfig.serverUrl + + '/identities/users/' + + uri + + '/memberships?limit=2000', + { + headers: { + Accept: 'application/json' + } + } + ) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + this.userData = jsonRes + this.loading = false + let groups = jsonRes.items.map((group: any) => { + return { + GROUPNAME: group.name, + URI: group.id + } + }) + this.userGroups = groups + this.userGroupsCount = groups.length + + if (this.users) { + this.userInfo = this.users.find((userAr) => userAr.URI === uri) + } + }) + } else { + const uri = this.route.snapshot.params['uri'] + let data = { iwant: [{ uri }] } + + this.sasService + .request('usernav/usergroupsbymember', data) + .then((res: any) => { + this.loading = false + + switch (this.serverType) { + case ServerType.Sas9: { + this.userInfo = res.info[0] + this.userEmails = res.emails + this.userEmailsCount = res.emails.length + this.userRoles = res.roles + this.userRolesCount = res.roles.length + this.userLogins = res.logins + this.userLoginsCount = res.logins.length + + break + } + case ServerType.Sasjs: { + if (this.users) { + this.userInfo = this.users.find( + (userAr) => userAr.URI === uri + ) + } else { + const group = res.groups[0] + + this.userInfo = { + URI: group.ID, + NAME: group.NAME, + DISPLAYNAME: group.NAME + } + } + + break + } + } + + this.userData = res + this.userGroups = res.groups + this.userGroupsCount = res.groups.length + }) + } + } + } + } + + public userListOnFilter() { + this.helperService.libraryOnFilter(this.users, this.userSearch, 'NAME') + globals.usernav.userSearch = this.userSearch + } + + public userOnClick(user: any) { + this.loading = true + let url = this.router.url + if (this.paramPresent) { + this.location.replaceState( + url.slice(0, url.lastIndexOf('/')) + '/' + encodeURI(user.URI) + ) + } else { + this.location.replaceState(url + '/' + encodeURI(user.URI)) + } + if (this.isViya) { + fetch( + this.sasjsConfig.serverUrl + + '/identities/users/' + + user.URI + + '/memberships?limit=2000', + { + headers: { + Accept: 'application/json' + } + } + ) + .then((res: any) => { + return res.text() + }) + .then((res: any) => { + let jsonRes = JSON.parse(res) + + this.userData = jsonRes + this.loading = false + + let groups = jsonRes.items.map((group: any) => { + return { + GROUPNAME: group.name, + URI: group.id + } + }) + + this.userGroups = groups + this.userGroupsCount = groups.length + + if (this.users) { + this.userInfo = this.users.find((userAr) => userAr.URI === user.URI) + } + }) + } else { + let data = { iwant: [{ uri: user.URI }] } + this.sasService + .request('usernav/usergroupsbymember', data) + .then((res: any) => { + this.loading = false + + switch (this.serverType) { + case ServerType.Sas9: { + this.userInfo = res.info[0] + this.userEmails = res.emails + this.userEmailsCount = res.emails.length + this.userRoles = res.roles + this.userRolesCount = res.roles.length + this.userLogins = res.logins + this.userLoginsCount = res.logins.length + + break + } + case ServerType.Sasjs: { + if (this.users) { + this.userInfo = this.users.find( + (userAr) => userAr.URI === user.URI + ) + } else { + const group = res.groups[0] + + this.userInfo = { + URI: group.ID, + NAME: group.NAME, + DISPLAYNAME: group.NAME + } + } + + break + } + } + + this.userData = res + this.userGroups = res.groups + this.userGroupsCount = res.groups.length + }) + } + } + + public getRoleURI(role: any) { + return role.split('OMSOBJ:IdentityGroup')[1].slice(1) + } +} diff --git a/client/src/app/viewer/viewer-routing.module.ts b/client/src/app/viewer/viewer-routing.module.ts new file mode 100644 index 0000000..7e8fff7 --- /dev/null +++ b/client/src/app/viewer/viewer-routing.module.ts @@ -0,0 +1,61 @@ +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { GroupComponent } from '../group/group.component' +import { LineageComponent } from '../lineage/lineage.component' +import { MetadataComponent } from '../metadata/metadata.component' +import { RoleComponent } from '../role/role.component' +import { UsernavRouteComponent } from '../routes/usernav-route/usernav-route.component' +import { ViewRouteComponent } from '../routes/view-route/view-route.component' +import { UserComponent } from '../user/user.component' +import { ViyaApiExplorerComponent } from '../viya-api-explorer/viya-api-explorer.component' +import { ViewerComponent } from './viewer.component' + +const routes: Routes = [ + { + path: '', + component: ViewRouteComponent, + children: [ + { path: '', pathMatch: 'full', redirectTo: 'data' }, + { path: 'data', component: ViewerComponent }, + { path: 'data', component: ViewerComponent }, + { path: 'data/:libMem/:filterId', component: ViewerComponent }, + { path: 'data/:libMem', component: ViewerComponent }, + { path: 'lineage', component: LineageComponent }, + { path: 'lineage/:tableid/:direction', component: LineageComponent }, + { + path: 'lineage/column/:coluri/:direction', + component: LineageComponent + }, + { + path: 'lineage/column/:coluri/:direction/:reload', + component: LineageComponent + }, + { path: 'viya-api-explorer', component: ViyaApiExplorerComponent }, + { path: 'metadata', component: MetadataComponent }, + { path: 'metadata/object/:objectID', component: MetadataComponent }, + { + path: 'metadata/object/:objectID/:objectName', + component: MetadataComponent + }, + { + path: 'usernav', + component: UsernavRouteComponent, + children: [ + { path: '', pathMatch: 'full', redirectTo: 'groups' }, + { path: 'users', component: UserComponent }, + { path: 'users/:uri', component: UserComponent }, + { path: 'groups', component: GroupComponent }, + { path: 'groups/:uri', component: GroupComponent }, + { path: 'roles', component: RoleComponent }, + { path: 'roles/:uri', component: RoleComponent } + ] + } + ] + } +] + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ViewerRoutingModule {} diff --git a/client/src/app/viewer/viewer.component.html b/client/src/app/viewer/viewer.component.html new file mode 100644 index 0000000..a7db9eb --- /dev/null +++ b/client/src/app/viewer/viewer.component.html @@ -0,0 +1,656 @@ + +
+ +
+ + + +
+ + + + +
+
+ + + +

+ + {{ library.LIBRARYNAME }} +

+ + +
+ + + + +
+
+ + + + + + + To unlock all tables, contact support@datacontroller.io + + + + +
+
+
+ +
+ Loading... +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Loading... +
+

Loading table viewer

+
+
+ +
+
+
+
+
+ + + + Loading... + +
+ + + + + + + +
+
+ +
+ + + + +

+ {{ tableTitle?.replace('-FC', '') }} + + + ({{ numberOfRows | thousandSeparator: ',' }} + {{ numberOfRows! === 1 ? 'row' : 'rows' }}, {{ filterCols.length + }}{{ filterCols.length === 1 ? ' col' : ' cols' }}) + + + +

+
+ +
+ + + + + + + + + + + +
+ +
+ FILTER : {{ queryText }} +
+
+ +
+ +

Please select a library

+
+ + +
+
+ +
+

+ {{ lib }} +

+ +
+ +
+
+ +
+ +
+ +
+ +

Please select a table

+
+ +
+

+ No library info found. Click + + button to refresh. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ENGINE: + {{ libinfo[0] ? libinfo[0].ENGINE : '' }} +
LIBID: + {{ libinfo[0] ? libinfo[0].LIBID : '' }} +
LIBNAME: + {{ libinfo[0] ? libinfo[0].LIBNAME : '' }} +
LIBSIZE: + {{ libinfo[0] ? (libinfo[0].LIBSIZE | convertSize) : '' }} +
OWNERS: + {{ libinfo[0] ? libinfo[0].OWNERS : '' }} +
PATHS: + {{ libinfo[0] ? libinfo[0].PATHS : '' }} +
PERMS: + {{ libinfo[0] ? libinfo[0].PERMS : '' }} +
SCHEMAS: + {{ libinfo[0] ? libinfo[0].SCHEMAS : '' }} +
TABLE_CNT: + {{ libinfo[0] ? libinfo[0].TABLE_CNT : '' }} +
+
+
+
+ +
+ +

+ No data found with given conditions +

+ +

+ No data found due to sas request error +

+
+ +
+ + +
+ +
+

+ To display more than {{ licenceState.value.viewer_rows_allowed }} rows, + contact +

+
+
+
+ + + + diff --git a/client/src/app/viewer/viewer.component.scss b/client/src/app/viewer/viewer.component.scss new file mode 100644 index 0000000..8956908 --- /dev/null +++ b/client/src/app/viewer/viewer.component.scss @@ -0,0 +1,175 @@ +.card { + margin-top: 0; + + flex: 1; + display: flex; + flex-direction: column; +} + +clr-tree-node button { + white-space: nowrap; +} + +.toggle-switch input[type=checkbox]:checked+label:before { + border-color: #314351; + background-color: #314351!important; + transition: .15s ease-in; + transition-property: border-color,background-color; +} + +.header-row { + .title-col { + display: flex; + align-items: center; + } + .options-col { + display: flex; + justify-content: flex-end; + } +} + +.sw { + margin: 1rem 0rem 0.5rem 1rem; +} + +.infoBar { + margin-top:10px; + background: #495967; + color: white; + text-align:center; + padding: 3px; + font-size: 16px; +} + +.filterSide { + margin-top: 26px; + margin-bottom: 19px; +} + +.options-dropdown { + ::ng-deep { + clr-icon { + margin-right: 5px; + } + } +} + +.viewerTitle { + text-align:center; + margin-bottom: 15px; +} + +.dropdown-menu { + width: 180px; + margin-top: -18px; + padding: 0; +} + +.dropdown-menu .btn { + width: 100%; + text-transform: none; +} + +.cardFlex { + display:flex; + justify-content: center +} + +.noData { + display:flex; + justify-content:center; + flex-direction:column; + align-items: center; + flex: 1; +} + + +.filterBtn { + display: flex; + justify-content: flex-end; +} + +.editBtn { + display: flex; + justify-content: flex-start; +} + +.btnView{ + margin: 0px!important; +} + +.content-area { + padding: 0.5rem !important; + + display: flex; + flex-direction: column; +} + +.download-select { + ::ng-deep { + .clr-select-wrapper { + max-height: unset !important; + } + } +} + +.refresh-table { + cursor: pointer; + margin-left: 5px; +} + +.libinfo { + padding: 10px 20px; + overflow: auto; +} + +hot-table { + ::ng-deep { + .primaryKeyHeaderStyle { + background: #306b006e; + } + } +} + +.no-table-selected-info { + background: none; + display: flex; + align-items: center; + flex-direction: column; +} + +.web-query { + max-height: 35vh; + + .web-query-text { + min-height: 100px; + max-height: 100px; + } +} + +// FIXME +// Let's leave it here for a reference if there +// is an issue with viewboxes/filter modal overlaying +// we will remove it if no issues found +// .filter-modal { +// z-index: 1210; +// } + +@media screen and (max-width: 768px) { + .filterBtn { + display: flex; + justify-content: center; + } + + .editBtn { + display: flex; + justify-content: center; + } +} + +@media (min-width: 576px) { + .row { + margin-right: 0rem; + margin-left: 0rem; + } +} \ No newline at end of file diff --git a/client/src/app/viewer/viewer.component.ts b/client/src/app/viewer/viewer.component.ts new file mode 100644 index 0000000..1387a6f --- /dev/null +++ b/client/src/app/viewer/viewer.component.ts @@ -0,0 +1,1078 @@ +import { + Component, + AfterContentInit, + ChangeDetectorRef, + AfterViewInit, + ViewChildren, + QueryList +} from '@angular/core' +import { SasStoreService } from '../services/sas-store.service' +import { Subscription } from 'rxjs' + +import { Params, Router } from '@angular/router' +import { ActivatedRoute } from '@angular/router' +import { globals } from '../_globals' + +import { EventService } from '../services/event.service' +import { HelperService } from '../services/helper.service' +import { HotTableRegisterer } from '@handsontable/angular' +import { SasService } from '../services/sas.service' +import { SASjsConfig } from '@sasjs/adapter' +import { AppService } from '../services/app.service' +import { QueryComponent } from '../query/query.component' + +import { FilterGroup, FilterQuery } from '../models/FilterQuery' +import { HotTableInterface } from '../models/HotTable.interface' +import { LoggerService } from '../services/logger.service' +import Handsontable from 'handsontable' +import { $DataFormats, DSMeta } from '../models/sas/editors-getdata.model' +import { mergeColsRules } from '../shared/dc-validator/utils/mergeColsRules' +import { PublicViewtablesServiceResponse } from '../models/sas/public-viewtables.model' +import { PublicViewlibsServiceResponse } from '../models/sas/public-viewlibs.model' +import { PublicRefreshlibinfoServiceResponse } from '../models/sas/public-refreshlibinfo.model' +import { DataFormat } from '../models/sas/common/DateFormat' +import { Libinfo } from '../models/sas/common/Libinfo' +import { LicenceService } from '../services/licence.service' +import { Location } from '@angular/common' + +@Component({ + selector: 'app-viewer', + templateUrl: './viewer.component.html', + styleUrls: ['./viewer.component.scss'], + host: { + class: 'content-container' + } +}) +export class ViewerComponent implements AfterContentInit, AfterViewInit { + @ViewChildren('queryFilter') + queryFilterCompList: QueryList = new QueryList() + + public libraries!: Array + public librariesPaging: boolean = false + public librariesSearch: string = '' + public libraryTablesRef: string = '' + public lib: any + public librariesTreeExpanded: boolean = false + public tables: any + public tableTitle: any + public libinfo: Libinfo[] | null = null + public table: any + public tableuri: string | null = null + public filter: boolean = false + public filterCols: any = [] + public nullVariables: boolean = false + public abortActive: boolean = false + public queryFilter: any + public urlFilterPk: number | null = null + public whereString!: string + public clauses: any + public libds!: string + public libTab!: string + public queryText: string = '' + public webQueryText: string = '' + public submitLoading!: boolean + public queryErr: boolean = false + public queryErrMessage!: string + public libDataset: any + public tableFlag: boolean = true + public librariesLoading: boolean = false + public loadingTableView: boolean = false + public switchFlag: boolean = false + public noData: boolean = false + public noDataReqErr: boolean = false + public tableDisable: boolean = false + public actionDisable: boolean = false + public openDownload: boolean = false + public webQuery: boolean = false + public webQueryTab: boolean = false + public downloadFormat: string = 'CSV' + public sasjsConfig: SASjsConfig = new SASjsConfig() + public searchLoading: boolean = false + public searchNumeric: boolean = false + private hotTableRegisterer: HotTableRegisterer + public numberOfRows: number | null = null + public headerPks: string[] = [] + public $dataFormats: $DataFormats | null = null + public datasetInfo: boolean = false + public dsmeta: DSMeta[] = [] + + public licenceState = this.licenceService.licenceState + public Infinity = Infinity + + public hotTable: HotTableInterface = { + data: [], + colHeaders: [], + columns: [], + height: '100%', + maxRows: this.licenceState.value.viewer_rows_allowed || Infinity, + settings: {}, + afterGetColHeader: undefined, + licenseKey: undefined, + contextMenu: ['copy_with_column_headers', 'copy_column_headers_only'], + copyPaste: { + copyColumnHeaders: true, + copyColumnHeadersOnly: true + }, + dropdownMenu: { + items: { + make_read_only: { + name: 'make_read_only' + }, + alignment: { + name: 'alignment' + }, + sp1: { + name: '---------' + }, + info: { + name: 'test info', + renderer: ( + hot: Handsontable.Core, + wrapper: HTMLElement, + row: number, + col: number, + prop: string | number, + itemValue: string + ) => { + const elem = document.createElement('span') + let colInfo: DataFormat | undefined + let textInfo = 'No info found' + + if (this.hotInstance) { + const hotSelected: [number, number, number, number][] = + this.hotInstance.getSelected() || [] + const selectedCol: number = hotSelected ? hotSelected[0][1] : -1 + const colName = this.hotInstance?.colToProp(selectedCol) + colInfo = this.$dataFormats?.vars[colName] + + if (colInfo) + textInfo = `LABEL: ${colInfo?.label}
TYPE: ${colInfo?.type}
LENGTH: ${colInfo?.length}
FORMAT: ${colInfo?.format}` + } + + elem.innerHTML = textInfo + + return elem + } + } + } + } + } + + private _query!: Subscription + + private hotInstance: Handsontable | null = null + public hotInstanceClickListener: boolean = false + + public viewboxOpen: boolean = false + + constructor( + private licenceService: LicenceService, + private sasStoreService: SasStoreService, + private sasService: SasService, + private router: Router, + private route: ActivatedRoute, + private eventService: EventService, + private loggerService: LoggerService, + private helperService: HelperService, + private location: Location, + private cdf: ChangeDetectorRef + ) { + this.hotTableRegisterer = new HotTableRegisterer() + this.sasjsConfig = this.sasService.getSasjsConfig() + } + + ngOnInit() { + if ( + globals.viewer.currentSelection !== '' && + Object.keys(this.route.snapshot.params).length === 0 + ) { + this.router.navigate([globals.viewer.currentSelection], { + queryParamsHandling: 'preserve' + }) + } + if (this.route.snapshot.params['libMem'] !== undefined) { + globals.viewer.currentSelection = 'view/data' + } + + this.licenceService.hot_license_key.subscribe( + (hot_license_key: string | undefined) => { + this.hotTable.licenseKey = hot_license_key + } + ) + } + + public newViewbox() { + this.viewboxOpen = true + } + + public resetFilter() { + if (this.queryFilterCompList.first) { + this.queryFilterCompList.first.resetFilter() + } + } + + public async searchTable(inputElement: any) { + this.searchLoading = true + + let searchValue = inputElement.value + + let libDataset = this.lib + '.' + this.table + let filter_pk = parseInt(this.route.snapshot.params['filterId']) || 0 + await this.sasStoreService + .viewDataSearch(searchValue, this.searchNumeric, libDataset, filter_pk) + .then((res: any) => { + if (!res.sasparams && !res.viewData) { + this.searchLoading = false + return + } + + this.hotTable.data = res.viewdata + this.$dataFormats = res.$viewdata + this.dsmeta = res.dsmeta + this.numberOfRows = res.sasparams[0].NOBS + this.queryText = res.sasparams[0].FILTER_TEXT + this.headerPks = res.sasparams[0].PK_FIELDS.split(' ') + + if (this.hotTable.data.length === 0) { + this.noData = true + } else { + this.noData = false + this.tableFlag = false + + this.setupHot() + } + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + + this.searchLoading = false + } + + public reloadTableData() { + this.viewData(this.urlFilterPk || 0) + } + + /** + * By default, SAS will send cached library information. + * This function calls SAS to update the backend database. + * It will also show the latest info on the page. + */ + public async reloadLibInfo() { + this.libinfo = null + + this.sasStoreService.refreshLibInfo(this.lib).then( + async (res: PublicRefreshlibinfoServiceResponse) => { + this.libinfo = res.libinfo + globals.viewer.libinfo = this.libinfo + + const library = this.libraries.find((x) => x.LIBRARYREF === this.lib) + + if (library) library.libinfo = this.libinfo + }, + (err: any) => { + this.loggerService.error(err) + + if (this.libinfo === null) this.libinfo = [] + } + ) + } + + public filterFn(input: string) { + let libraries = this.libraries + this.libraries = libraries.filter( + (item) => + item.LIBRARYNAME.toLowerCase().indexOf(input.toLocaleLowerCase()) !== -1 + ) + } + + public downloadData() { + let storage = this.sasjsConfig.serverUrl + let metaData = this.sasjsConfig.appLoc + const path = this.sasService.getExecutionPath() + let type = '&type=' + this.downloadFormat + let table = '&table=' + this.tableTitle + let contextname = + this.sasjsConfig.serverType === 'SASVIYA' + ? `&_contextname=${this.sasjsConfig.contextName}` + : '' + let filter_pk: number + + if (typeof this.route.snapshot.params['filterId'] === 'undefined') { + filter_pk = 0 + } else { + filter_pk = parseInt(this.route.snapshot.params['filterId']) + } + + let filter = '&filter=' + filter_pk + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/public/getrawdata' + + type + + table + + contextname + + filter + + window.open(downUrl) + this.openDownload = false + } + + public downloadDDL() { + let libref = this.lib + let ds = this.table + let flavour = this.downloadFormat.replace('_DDL', '') + let storage = this.sasjsConfig.serverUrl + let metaData = this.sasjsConfig.appLoc + const path = this.sasService.getExecutionPath() + let contextname = + this.sasjsConfig.serverType === 'SASVIYA' + ? `&_contextname=${this.sasjsConfig.contextName}` + : '' + + let params = `&ds=${ds}&libref=${libref}&flavour=${flavour}${contextname}` + + let downUrl = + storage + + path + + '/?_program=' + + metaData + + '/services/public/getddl' + + params + + window.open(downUrl) + this.openDownload = false + } + + public onCliCommandFocus(evt: any): void { + evt.preventDefault() + evt.target.select() + } + + public editTable() { + this.router.navigateByUrl('/editor/' + this.libTab) + } + + public tableEditExists() { + let editTables: any = {} + editTables = globals.editor.libsAndTables + let currentTable = this.libTab.split('.')[1] + let currentLibrary = this.libTab.split('.')[0] + + // If this line is undefined, that means startupservice failed or similar. + if (!editTables[currentLibrary]) return false + + return editTables[currentLibrary].includes(currentTable) + } + + public goToLineage() { + let routeUri = this.tableuri!.split('\\')[1] + let lineageUrl = `/view/lineage/${routeUri}/REVERSE` + this.router.navigateByUrl(lineageUrl) + } + + public showWebQuery() { + this.webQuery = true + let filter_pk: number + if (typeof this.route.snapshot.params['filterId'] === 'undefined') { + filter_pk = 0 + } else { + filter_pk = parseInt(this.route.snapshot.params['filterId']) + } + + let port = window.location.port.length > 0 ? ':' + window.location.port : '' + + const sasPath = this.sasService.getExecutionPath() + + let filter = '&filter=' + filter_pk + + let downUrl = `${window.location.protocol}//${ + window.location.hostname + }${port}/${sasPath}/?_program=${ + this.sasjsConfig.appLoc + }/services/public/getrawdata&type=WEB${ + this.webQueryTab ? 'TAB' : 'CSV' + }&table=${this.tableTitle}${filter}` + + this.webQueryText = downUrl.replace(/ /gim, '%20') + } + + public copyToClip() { + let selBox = document.createElement('textarea') + selBox.style.position = 'fixed' + selBox.style.left = '0' + selBox.style.top = '0' + selBox.style.opacity = '0' + selBox.value = this.webQueryText + document.body.appendChild(selBox) + selBox.focus() + selBox.select() + document.execCommand('copy') + document.body.removeChild(selBox) + } + + public goToViewer() { + this.router.navigateByUrl('/view/data') + } + + public showTableSelect() { + this.tableFlag = !this.tableFlag + } + + public checkExpand(event: any) {} + + public collapseLibraryItems(libraries: any, libraryToSkip: any) { + libraries.forEach((library: any) => { + if (library.LIBRARYREF !== libraryToSkip.LIBRARYREF) { + library['expanded'] = false + } + }) + } + + public loadMoreLibraries() { + if (!this.librariesPaging) { + this.librariesPaging = true + + this.helperService.displayLibraries(this.libraries, true) + + this.librariesPaging = false + } + } + + public treeNodeClicked(event: any, library: any) { + if (event.target.title === 'Collapse') { + this.collapseLibraryItems(this.libraries, library) + } + } + + public libraryExpandedChange(expanded: any, library: any) { + if (expanded) { + this.collapseLibraryItems(this.libraries, library) + } + } + + public async libraryOnClick(lib: string, library: any, expandOnly?: boolean) { + if (!library['tables']) { + await this.selectTable(lib, false, library) + } else { + if (!!expandOnly) { + library['expanded'] = true + } else { + library['expanded'] = !library['expanded'] + } + } + + if (library['expanded']) { + this.cdf.detectChanges() + let libTreeSearchInput: HTMLElement | null = document.querySelector( + `#search_${library.LIBRARYREF}` + ) + + this.loggerService.log('[libTreeSearchInput]', libTreeSearchInput) + if (libTreeSearchInput) libTreeSearchInput.focus() + + if (library && library.libinfo) this.libinfo = library.libinfo + + if (this.lib && this.table && !expandOnly) { + this.router + .navigate(['/view/data'], { + skipLocationChange: true, + queryParamsHandling: 'preserve' + }) + .then(() => { + this.router.navigate(['/view/data/' + this.lib], { + queryParamsHandling: 'preserve' + }) + }) + } else if (this.lib && !this.table) { + this.location.replaceState('/view/data/' + this.lib) + } + } + + this.collapseLibraryItems(this.libraries, library) + } + + public onTableClick(libTable: any, library: any) { + this.lib = library.LIBRARYREF + this.table = libTable + this.selectLibTable(libTable) + this.viewData(0) + } + + public async selectTable(lib: string, initial?: boolean, library?: any) { + library['loadingTables'] = true + + this.table = false + this.tableDisable = true + if (lib !== 'Please select library') { + if (globals.viewer.tablesSet && initial) { + this.abortActive = false + this.tableDisable = false + this.tables = globals.viewer.tables + this.libinfo = globals.viewer.libinfo + } else { + this.libinfo = null + + await this.sasStoreService + .viewTables(lib) + .then((res: PublicViewtablesServiceResponse) => { + this.abortActive = false + this.tableDisable = false + + let tables = res.mptables.map(function (item: any) { + return item.MEMNAME + }) + + this.libinfo = res.libinfo || [] + this.tables = tables + + if (library) { + library['tables'] = tables + library['libinfo'] = this.libinfo + } + + globals.viewer.libraries = this.libraries + globals.viewer.library = this.lib + globals.viewer.tables = this.tables + globals.viewer.libinfo = this.libinfo + globals.viewer.tablesSet = true + }) + .catch((err: any) => { + this.loggerService.error(err) + + this.abortActive = true + this.noData = true + this.tableTitle = '' + this.tableDisable = true + }) + } + } else { + this.tableDisable = true + } + // this.getTableState(); + + globals.viewer.library = this.lib + if (!initial) { + this.clearGlobalsFilter() + } + + library['loadingTables'] = false + library['expanded'] + ? (library['expanded'] = false) + : (library['expanded'] = true) + } + + public selectLibTable(ev: string, initial?: boolean) { + if (ev !== 'Please select table') { + this.actionDisable = false + this.libTab = this.lib + '.' + this.table + } else { + this.actionDisable = true + } + globals.viewer.table = ev + if (!initial) { + this.clearGlobalsFilter() + } + + this.loggerService.log(this.libTab) + } + + private clearGlobalsFilter() { + globals.viewer.filter.libds = '' + globals.viewer.filter.whereClause = '' + globals.viewer.filter.groupLogic = '' + globals.viewer.filter.clauses = [] + globals.viewer.filter.cols = [] + globals.viewer.filter.vals = [] + } + + public libTabActive(libraryRef: string, table: string) { + let currentLibTab = libraryRef + '.' + table + + if (!this.libTab) { + return false + } + + return currentLibTab === this.libTab + } + + public treeOnFilter(array: any, arrToFilter: string) { + this.helperService.treeOnFilter(array, arrToFilter) + } + + public libraryOnFilter() { + this.helperService.libraryOnFilter( + this.libraries, + this.librariesSearch, + 'LIBRARYNAME' + ) + + globals.viewer.librariesSearch = this.librariesSearch + } + + public libraryResetFilter() { + this.helperService.resetArrayFilter(this.libraries) + } + + public async viewData(filter_pk: number) { + this.loadingTableView = true + + let libDataset: any + if (typeof this.libDataset === 'undefined') { + libDataset = this.lib + '.' + this.table + } else if ( + typeof this.lib === 'undefined' && + typeof this.table === 'undefined' + ) { + let ds = [] + ds = this.libDataset.split('.') + + if (globals.viewer.startupSet) { + this.libraries = globals.viewer.libraries + } else { + await this.sasStoreService + .viewLibs() + .then((res: any) => { + this.libraries = res.saslibs + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + } + + this.lib = ds[0] + + if (globals.viewer.startupSet) { + this.tables = globals.viewer.tables + } else { + let library = this.libraries.find( + (lib) => lib.LIBRARYREF.toLowerCase() === this.lib.toLowerCase() + ) + + await this.sasStoreService + .viewTables(this.lib) + .then((response: any) => { + this.tables = response.mptables.map(function (item: any) { + return item.MEMNAME + }) + + library.tables = this.tables + globals.viewer.libraries = this.libraries + globals.viewer.tables = this.tables + globals.viewer.startupSet = true + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + } + + this.table = ds[1] + + this.tableFlag = false + + libDataset = this.libDataset + this.libTab = libDataset + } else { + if (globals.viewer.startupSet) { + this.libraries = globals.viewer.libraries + } else { + await this.sasStoreService + .viewLibs() + .then((res: any) => { + this.libraries = res.saslibs + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + } + + if (typeof this.table !== 'undefined') { + if (globals.viewer.startupSet) { + this.tables = globals.viewer.tables + } else { + await this.sasStoreService + .viewTables(this.lib) + .then((response: PublicViewtablesServiceResponse) => { + this.tables = response.mptables.map(function (item: any) { + return item.MEMNAME + }) + }) + .catch((err: any) => { + this.loggerService.error(err) + + this.router.navigate(['/view/data'], { + queryParamsHandling: 'preserve' + }) + }) + } + + this.tableFlag = false + + libDataset = this.lib + '.' + this.table + this.tableTitle = libDataset + this.libTab = libDataset + } + } + + if (this.router.url.split('/').length > 3 && libDataset) { + await this.sasStoreService + .viewData(libDataset, filter_pk) + .then((res: any) => { + if ( + res.query.length > 0 && + globals.rootParam === 'view' && + globals.viewer.filter.clauses.length === 0 + ) { + globals.viewer.filter.query = this.helperService.deepClone( + res.query + ) + globals.viewer.filter.libds = this.route.snapshot.params['libMem'] + this.sasStoreService.initializeGlobalFilterClause( + 'viewer', + res.cols + ) + } + this.abortActive = false + this.filterCols = res.cols + + // This will merge $formats types with `Cols` object. + mergeColsRules(this.filterCols, [], res.$viewdata) + + this.numberOfRows = res.sasparams[0].NOBS + this.headerPks = res.sasparams[0].PK_FIELDS.split(' ') + + if (this.sasjsConfig.serverType === 'SAS9') { + let tableuri = res.sasparams[0].TABLEURI + + if (tableuri) { + if (tableuri.length > 0) { + this.tableuri = tableuri + } + } + } + + this.hotTable.data = res.viewdata + this.$dataFormats = res.$viewdata + this.dsmeta = res.dsmeta + this.queryText = res.sasparams[0].FILTER_TEXT + let columns: any[] = [] + let colArr = [] + + for (let key in res.viewdata[0]) { + if (key) { + colArr.push(key) + } + } + + for (let index = 0; index < colArr.length; index++) { + columns.push({ data: colArr[index] }) + } + + let cells = function () { + let cellProperties = { readOnly: true } + return cellProperties + } + + this.hotTable.colHeaders = colArr + this.hotTable.columns = columns + this.hotTable.cells = cells + + this.tableFlag = false + let ds = [] + ds = libDataset.split('.') + this.lib = ds[0] + this.table = ds[1] + + if (this.hotTable.data.length === 0) { + this.noData = true + this.tableFlag = true + } else { + this.noData = false + this.tableFlag = false + } + + this.noDataReqErr = false + }) + .catch((err: any) => { + this.loggerService.error(err) + + this.abortActive = true + this.noDataReqErr = true + }) + } + + // If we move away from the viewer page, we don't renavigate to table view + if (this.router.url.includes('/data') && libDataset) { + if (filter_pk !== 0) { + this.router.navigate(['/view/data/' + libDataset + '/' + filter_pk], { + queryParamsHandling: 'preserve' + }) + } else { + this.router.navigate(['/view/data/' + libDataset], { + queryParamsHandling: 'preserve' + }) + } + } + + let currentTable = this.table + let libraryObject = this.libraries.find( + (lib) => lib.LIBRARYREF.toLowerCase() === this.lib.toLowerCase() + ) + + if (libraryObject) { + if (globals.viewer.libraries.length > 0) { + this.libraries = globals.viewer.libraries + this.librariesSearch = globals.viewer.librariesSearch + this.libraryOnClick(this.lib, libraryObject, true) + } else { + this.libraryOnClick(this.lib, libraryObject, true) + } + } else { + this.libinfo = [] + } + + this.table = currentTable ? currentTable : this.table + + if (this.libraries) { + this.helperService.displayLibraries(this.libraries) + } + + if (this.router.url.includes('/data')) { + this.eventService.closeSidebar() + } + + this.loadingTableView = false + + //If we try to setup hot when no data is returned it errors `isDestoryed`. + //That is intorduced by HOT update + if (!this.noData && !this.noDataReqErr && libDataset) this.setupHot() + + /** + * This is hacky fix for closing the nav drodpwon, when clicking on the handsontable area. + * Without it, hot table does not steal focus, so it doesn't close the nav. + */ + if (!this.hotInstanceClickListener) { + setTimeout(() => { + let hotInstanceEl = document.getElementById('hotInstance') + + if (hotInstanceEl) { + hotInstanceEl.addEventListener('mousedown', (event) => { + setTimeout(() => { + let menuDebugItem: any = + document.querySelector('.debug-switch-item') || undefined + if (menuDebugItem) menuDebugItem.click() + }, 100) + }) + this.hotInstanceClickListener = true + } + }, 2000) + } + } + + public maxWidthCheker(width: any, col: any) { + if (width > 200) return 200 + else return width + } + + public openQb() { + this.filter = true + this.cdf.detectChanges() + + let libDataset = this.lib + '.' + this.table + this.sasStoreService.setQueryVariables(libDataset, this.filterCols) + } + + public async sendClause() { + this.submitLoading = true + let nullVariableArr = [] + let emptyVariablesArr = [] + // to check number of empty clauses + if (typeof this.clauses === 'undefined') { + this.nullVariables = true + this.submitLoading = false + return + } else { + let query = this.clauses.queryObj + + if (query[0].elements.length < 1) { + // Clear cached filtering data + if (globals.rootParam === 'view') { + globals.viewer.filter.clauses = [] + globals.viewer.filter.query = [] + globals.viewer.filter.groupLogic = '' + } + + this.router.navigate(['/view/data/' + this.libds], { + queryParamsHandling: 'preserve' + }) + return + } + + for (let index = 0; index < query.length; index++) { + const el = query[index].elements + nullVariableArr = el.filter(function (item: any) { + return item.variable === null + }) + if (nullVariableArr.length) { + emptyVariablesArr.push(el) + } + } + } + + if (emptyVariablesArr.length) { + // not allow to submit if some of clauses are empty + this.nullVariables = true + this.submitLoading = false + return + } else { + const filterQuery: FilterQuery = { + groupLogic: this.clauses.groupLogic, + filterGroups: [] + } + this.clauses.queryObj.forEach((group: any) => { + const filterGroup: FilterGroup = { + filterClauses: [] + } + group.elements.forEach((clause: any) => { + filterGroup.filterClauses.push(this.helperService.deepClone(clause)) + }) + filterGroup.clauseLogic = group.clauseLogic + filterQuery.filterGroups.push(this.helperService.deepClone(filterGroup)) + }) + + const filterQueryClauseTable = + this.sasStoreService.createFilterQueryTable(filterQuery) + await this.sasStoreService + .saveQuery(this.libds, filterQueryClauseTable) + .then((res: any) => { + this.queryText = res.result[0].FILTER_TEXT + let id = res.result[0].FILTER_RK + this.router.navigate(['/view/data/' + this.libds + '/' + id], { + queryParamsHandling: 'preserve' + }) + + this.viewData(id) + + this.filter = false + }) + .catch((err: any) => { + this.loggerService.error(err) + }) + + this.submitLoading = false + } + } + + public removeQuery() { + this.sasStoreService.removeClause() + } + + private setupHot() { + setTimeout(() => { + if (!this.loadingTableView && this.libDataset) { + this.hotInstance = this.hotTableRegisterer.getInstance('hotInstance') + + if (this.hotInstance) { + this.hotInstance.updateSettings({ + height: this.hotTable.height, + modifyColWidth: function (width: any, col: any) { + if (width > 500) return 500 + else return width + }, + afterGetColHeader: (col: number, th: any) => { + const column = this.hotInstance?.colToProp(col) as string + + // header columns styling - primary keys + const isPKCol = column && this.headerPks.indexOf(column) > -1 + + if (isPKCol) th.classList.add('primaryKeyHeaderStyle') + } + }) + } + } + }, 1000) + } + + async loadWithParameters() { + this.switchFlag = true + this.tableTitle = this.route.snapshot.params['libMem'] || 0 + let id = this.route.snapshot.params['filterId'] || '0' + + this.urlFilterPk = parseInt(id) + + let libds = this.route.snapshot.params['libMem'] + this.libDataset = libds + + if (!libds.includes('.')) this.lib = libds + + await this.viewData(this.urlFilterPk) + + if (this.noData) { + setTimeout(() => { + this.tableFlag = true + }, 1200) + } else { + setTimeout(() => { + this.tableFlag = false + }, 1200) + } + } + + async loadWithoutParameters() { + this.switchFlag = false + this.librariesLoading = true + + if (globals.viewer.startupSet) { + setTimeout(() => { + this.libraries = globals.viewer.libraries + this.librariesSearch = globals.viewer.librariesSearch + this.lib = globals.viewer.library + this.librariesTreeExpanded = true + this.librariesLoading = false + + this.helperService.displayLibraries(this.libraries) + }, 100) + } else { + this.noDataReqErr = false + + await this.sasStoreService + .viewLibs() + .then((res: PublicViewlibsServiceResponse) => { + this.libraries = res.saslibs + globals.viewer.libraries = this.libraries + globals.viewer.startupSet = true + + this.librariesLoading = false + + this.helperService.displayLibraries(this.libraries) + }) + .catch((err: any) => { + this.loggerService.error(err) + + this.librariesLoading = false + this.noDataReqErr = true + }) + } + } + + ngAfterViewInit() {} + + async ngAfterContentInit() { + if (this.hotTable.data.length > 0) { + this.tableFlag = true + } + this._query = this.sasStoreService.query.subscribe((query: any) => { + this.whereString = query.string + this.clauses = query.obj + this.libds = query.libds + }) + + if (typeof this.route.snapshot.params['libMem'] !== 'undefined') { + this.loadWithParameters() + } else { + this.loadWithoutParameters() + } + } +} diff --git a/client/src/app/viewer/viewer.module.ts b/client/src/app/viewer/viewer.module.ts new file mode 100644 index 0000000..5a578c9 --- /dev/null +++ b/client/src/app/viewer/viewer.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { ViewerComponent } from './viewer.component' +import { ViewRouteComponent } from '../routes/view-route/view-route.component' +import { HotTableModule } from '@handsontable/angular' +import { ViewerRoutingModule } from './viewer-routing.module' +import { ClarityModule } from '@clr/angular' +import { FormsModule } from '@angular/forms' +import { ClipboardModule } from 'ngx-clipboard' +import { AppSharedModule } from '../app-shared.module' +import { PipesModule } from '../pipes/pipes.module' +import { SharedModule } from '../shared/shared.module' +import { ViewboxesModule } from '../shared/viewboxes/viewboxes.module' +import { QueryModule } from '../query/query.module' +import { DirectivesModule } from '../directives/directives.module' + +@NgModule({ + declarations: [ViewerComponent, ViewRouteComponent], + imports: [ + ViewboxesModule, + CommonModule, + ViewerRoutingModule, + ClipboardModule, + FormsModule, + ClarityModule, + HotTableModule.forRoot(), + AppSharedModule, + SharedModule, + PipesModule, + QueryModule, + DirectivesModule + ] +}) +export class ViewerModule {} diff --git a/client/src/app/viya-api-explorer/models/collection-details.model.ts b/client/src/app/viya-api-explorer/models/collection-details.model.ts new file mode 100644 index 0000000..a6cfa4f --- /dev/null +++ b/client/src/app/viya-api-explorer/models/collection-details.model.ts @@ -0,0 +1,11 @@ +import { Link } from './link.model' + +export interface CollectionDetails { + links: Link[] + name: string + accept: string + start: number + items: any[] + limit: number + version: number +} diff --git a/client/src/app/viya-api-explorer/models/collection.model.ts b/client/src/app/viya-api-explorer/models/collection.model.ts new file mode 100644 index 0000000..5c84a8d --- /dev/null +++ b/client/src/app/viya-api-explorer/models/collection.model.ts @@ -0,0 +1,11 @@ +import { Link } from './link.model' + +export interface Collection { + links: Link[] + version: number + name?: string + accept?: string + start?: number + items?: any[] + limit?: number +} diff --git a/client/src/app/viya-api-explorer/models/link.model.ts b/client/src/app/viya-api-explorer/models/link.model.ts new file mode 100644 index 0000000..70176bf --- /dev/null +++ b/client/src/app/viya-api-explorer/models/link.model.ts @@ -0,0 +1,13 @@ +export interface Link { + method: string + rel: string + href: string + uri: string + type: string + itemType: string + //Tree related properties + tables?: any[] + expanded: boolean + hidden?: boolean + loadingTables?: boolean +} diff --git a/client/src/app/viya-api-explorer/models/viya-apis.models.ts b/client/src/app/viya-api-explorer/models/viya-apis.models.ts new file mode 100644 index 0000000..fc52101 --- /dev/null +++ b/client/src/app/viya-api-explorer/models/viya-apis.models.ts @@ -0,0 +1 @@ +export type ViyaApis = { [key: string]: { [key: string]: string } } diff --git a/client/src/app/viya-api-explorer/viya-api-explorer.component.html b/client/src/app/viya-api-explorer/viya-api-explorer.component.html new file mode 100644 index 0000000..b809cab --- /dev/null +++ b/client/src/app/viya-api-explorer/viya-api-explorer.component.html @@ -0,0 +1,198 @@ + +
+ + + + +
+ +

+ Select collection to start +

+ +
+ +
+ + + +
+ + + +
+
+ + +

+ + {{ link.method }} {{ link.rel }} +

+
+
+
+ + + +
+ + + +
+
+ + +

+ + {{ item.name || item.id }} +

+
+
+
+
+ +
+
+
+
+ + + + + + + + +
+ +

+ API Explorer + +

+
+
+ + +
+ + GET +

+ +
+ +
+ + + + + + + + + +
+
+
+        
+          
+          
+            {{ endpointJson | prettyjson }}
+          
+        
+      
+
+
+
diff --git a/client/src/app/viya-api-explorer/viya-api-explorer.component.scss b/client/src/app/viya-api-explorer/viya-api-explorer.component.scss new file mode 100644 index 0000000..2e01220 --- /dev/null +++ b/client/src/app/viya-api-explorer/viya-api-explorer.component.scss @@ -0,0 +1,44 @@ +.api-collection-dropdown { + margin-left: 15px; + margin-right: 15px; + margin-bottom: 10px; +} + +.json-area { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + overflow: auto; + + ::ng-deep { + a { + text-decoration: none; + } + + > ngx-json-viewer { + height: 100%; + + > .ngx-json-viewer { + overflow: auto; + } + } + } +} + +.json-toggle { + position: absolute; + left: 10px; + margin: 0; +} + +.endpoint-breadcrums { + margin: 0; + margin-left: 10px; +} + +.query-params { + input { + width: 70px; + } +} \ No newline at end of file diff --git a/client/src/app/viya-api-explorer/viya-api-explorer.component.ts b/client/src/app/viya-api-explorer/viya-api-explorer.component.ts new file mode 100644 index 0000000..4d9c409 --- /dev/null +++ b/client/src/app/viya-api-explorer/viya-api-explorer.component.ts @@ -0,0 +1,207 @@ +import { Component, OnInit } from '@angular/core' +import { SASjsConfig } from '@sasjs/adapter' +import { EventService, HelperService, SasService } from '../services' +import { SasViyaService } from '../services/sas-viya.service' +import { globals } from '../_globals' +import { Collection } from './models/collection.model' +import { Link } from './models/link.model' +import { ViyaApis } from './models/viya-apis.models' + +@Component({ + selector: 'app-viya-api-explorer', + templateUrl: './viya-api-explorer.component.html', + styleUrls: ['./viya-api-explorer.component.scss'], + host: { + class: 'content-container' + } +}) +export class ViyaApiExplorerComponent implements OnInit { + collections: ViyaApis = {} + collection: string = '' + + endpointLinks: Link[] = [] + endpointItems: any[] = [] + endpointJson: any + endpoint: { + url: string + start: number | undefined + limit: number | undefined + } = { + url: '', + start: -1, + limit: -1 + } + + endpointLoading: boolean = false + collectionLoading: boolean = false + rawJson: boolean = false + + linksSearch: string = '' + itemsSearch: string = '' + + public sasjsConfig: SASjsConfig = new SASjsConfig() + + constructor( + private helperService: HelperService, + private sasViyaService: SasViyaService, + private sasService: SasService, + private eventService: EventService + ) {} + + ngOnInit(): void { + this.sasjsConfig = this.sasService.getSasjsConfig() + this.collections = this.sasViyaService.getAllCollections() + } + + linksListOnFilter() { + this.helperService.libraryOnFilter( + this.endpointLinks, + this.linksSearch, + 'rel' + ) + + globals.viyaApi.linkssSearch = this.linksSearch + } + + itemsListOnFilter() { + this.helperService.libraryOnFilter( + this.endpointItems, + this.itemsSearch, + 'name' + ) + + globals.viyaApi.itemsSearch = this.itemsSearch + } + + linkOnClick(link: Link) { + this.loadUrl(link.href) + } + + itemOnClick(item: any) { + this.loadUrl(item.links[0].href) + } + + treeNodeClicked(event: any, item: any, tree: any) { + if (event.target.title === 'Collapse') { + this.collapseTreeItems(tree, item) + } + } + + collapseTreeItems(tree: any, itemToSkip: any) { + tree.forEach((item: any) => { + if (JSON.stringify(item) !== JSON.stringify(itemToSkip)) { + item['expanded'] = false + } + }) + } + + updateSelectedCollection() { + globals.viyaApi.selectedCollection = this.collection + this.endpoint.url = this.collection + + this.collectionLoading = true + + this.sasViyaService.getByCollection(this.collection).subscribe( + (collection: Collection) => { + this.endpointLinks = collection.links + this.endpointItems = collection.items ? collection.items : [] + this.collectionLoading = false + + this.endpointJson = collection + + this.endpoint.start = collection.start + this.endpoint.limit = collection.limit + }, + (err: any) => { + this.collectionLoading = false + + let message = 'Error occurred while sending request' + + if (err.message) message = err.message + if (err.error) { + if (err.error.message) message = err.error.message + if (err.error.remediation) + message = `${message}\n${err.error.remediation}` + } + + this.eventService.showAbortModal(null, message, null, 'HTTP Error') + } + ) + } + + onJsonLinkClick(link: string) { + this.loadUrl(link) + } + + onJsonClick(event: any) { + event.preventDefault() + + if (event.srcElement.tagName === 'A') { + const url = event.srcElement.href.split(event.srcElement.host)[1] + + this.loadUrl(url) + } + } + + onBreadcumsClick(event: any) { + event.preventDefault() + + if (!event.srcElement.href) return + + const url = event.srcElement.href.split(event.srcElement.host)[1] + + this.loadUrl(url) + } + + copyJson() { + if (this.endpointJson) + navigator.clipboard.writeText(JSON.stringify(this.endpointJson, null, 2)) + } + + copyBreadcrums() { + if (this.endpoint && this.endpoint.url) + navigator.clipboard.writeText(this.endpoint.url) + } + + applyQueryParams() { + const start = this.endpoint.start + const limit = this.endpoint.limit + const params = `?${start !== undefined ? 'start=' + start : ''}${ + limit !== undefined ? '&limit=' + limit : '' + }` + + const url = `${this.endpoint.url.split('?')[0]}${params}` + this.loadUrl(url) + } + + loadUrl(url: string) { + this.endpointLoading = true + + this.sasViyaService.getByUrl(url).subscribe( + (collection: Collection) => { + this.endpointLinks = collection.links + this.endpointItems = collection.items ? collection.items : [] + this.endpointJson = collection + this.endpointLoading = false + + this.endpoint.url = url + this.endpoint.start = collection.start + this.endpoint.limit = collection.limit + }, + (err: any) => { + this.endpointLoading = false + + let message = 'Error occurred while sending request' + + if (err.message) message = err.message + if (err.error) { + if (err.error.message) message = err.error.message + if (err.error.remediation) + message = `${message}\n${err.error.remediation}` + } + + this.eventService.showAbortModal(null, message, null, 'HTTP Error') + } + ) + } +} diff --git a/client/src/assets/a_pompadour_font.zip b/client/src/assets/a_pompadour_font.zip new file mode 100644 index 0000000..f1f0269 Binary files /dev/null and b/client/src/assets/a_pompadour_font.zip differ diff --git a/client/src/assets/base64-images.txt b/client/src/assets/base64-images.txt new file mode 100644 index 0000000..2fcdb2d --- /dev/null +++ b/client/src/assets/base64-images.txt @@ -0,0 +1,5 @@ +datacontroller_logo = data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAA/j4meAAAAKpJREFUAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA0BNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAcSik/AfWUJajApYI1AAAAAElFTkSuQmCC + +datacontroller_favicon = data:image/png;base64,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 + +datacontroller_logo_svg = data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAyMDAwIDUyMC43IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMDAwIDUyMC43OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6I0UwRTBFMDt9Cgkuc3Qxe2ZpbGw6IzhFQzYzRjt9Cgkuc3Qye2ZvbnQtZmFtaWx5OidBUG9tcGFkb3VyQm9sZFNhbXBsZSc7fQoJLnN0M3tmb250LXNpemU6MjA1Ljc0NTRweDt9Cgkuc3Q0e2xldHRlci1zcGFjaW5nOjU7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzIxLjksMTk4LjJjMy4zLDAuNCw2LjUsMC43LDkuOCwxLjFjNy45LDEuMSwxNS42LDIuNiwyMi44LDYuM2MyLjEsMS4xLDQuMSwyLjMsNS42LDQuMgoJYzIuNCwyLjgsMi4zLDUuOC0wLjEsOC42Yy0yLjUsMi44LTUuNyw0LjQtOS4xLDUuN2MtNy45LDMuMS0xNi4yLDQuNS0yNC42LDUuMmMtMTMuNywxLjEtMjcuMiwwLjYtNDAuNi0yLjYKCWMtNC40LTEtOC43LTIuNC0xMi42LTQuNmMtMS41LTAuOC0yLjktMS44LTQuMi0zYy0zLjYtMy41LTMuNi03LjIsMC4xLTEwLjVjNC0zLjYsOC45LTUuMywxMy45LTYuN2M3LTIsMTQuMS0zLDIxLjMtMy41CgljMC42LDAsMS4zLDAuMiwxLjgtMC4zQzMxMS4yLDE5OC4yLDMxNi42LDE5OC4yLDMyMS45LDE5OC4yeiIvPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjY2LjIsMjgwLjNjNi40LDguMiwxNS41LDExLjIsMjQuOSwxMy4yYzE4LjYsNCwzNy4yLDMuNSw1NS4zLTIuOWM1LjYtMiwxMC44LTQuNywxNC41LTkuNwoJYzAuNi0wLjgsMC45LTAuNCwxLjIsMC4yYzAuNiwxLjMsMC45LDIuNiwwLjksNGMwLDQuOSwwLDkuOSwwLDE0LjhjMCwzLjItMS41LDUuNy0zLjcsNy45Yy00LjYsNC42LTEwLjQsNy4xLTE2LjUsOQoJYy0xMi4zLDMuOC0yNC45LDQuNi0zNy42LDMuN2MtOS41LTAuNy0xOC43LTIuNS0yNy40LTYuNGMtMy43LTEuNy03LjEtMy43LTkuOC02LjhjLTIuMS0yLjQtMy4yLTUuMS0zLjItOC4zYzAuMS00LjUsMC05LDAtMTMuNQoJQzI2NC44LDI4My43LDI2NS4xLDI4MiwyNjYuMiwyODAuM3oiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI2Ni4zLDI0OS40YzUuMyw3LjEsMTIuNywxMC4xLDIwLjYsMTIuMmMxOC45LDUsMzcuOCw0LjksNTYuNS0wLjdjNi4yLTEuOCwxMi00LjUsMTYuNS05LjQKCWMwLjYtMC42LDEtMiwxLjctMS44YzEsMC4zLDEsMS43LDEuMywyLjhjMC40LDEuNywwLjIsMy40LDAuMiw1LjFjMCwzLjQtMC4xLDYuNywwLDEwLjFjMC4yLDQuMi0xLjUsNy41LTQuNiwxMC4yCgljLTQuNyw0LjItMTAuNCw2LjctMTYuNSw4LjNjLTIwLjUsNS41LTQwLjksNS40LTYxLTEuNmMtNC45LTEuNy05LjQtNC4xLTEzLThjLTIuMi0yLjQtMy4zLTUuMi0zLjMtOC41YzAuMS00LjQsMC04LjksMC0xMy4zCglDMjY0LjgsMjUzLDI2NS4xLDI1MS4yLDI2Ni4zLDI0OS40eiIvPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjY2LjEsMjE5LjdjMS41LDQuNCw1LjEsNi40LDguOSw4LjJjNi44LDMuMiwxNC4xLDQuNywyMS40LDUuNmMxNC41LDEuOCwyOSwxLjYsNDMuMy0xLjQKCWM1LjgtMS4yLDExLjQtMi44LDE2LjUtNmMyLjktMS44LDQuNC0zLjUsNS40LTYuM2MxLDEuNCwxLjMsMi45LDEuMyw0LjRjMCw1LDAuMSw5LjksMCwxNC45Yy0wLjEsNC4yLTIuNSw3LjItNS42LDkuNwoJYy01LjgsNC42LTEyLjYsNy0xOS43LDguNmMtMTguOCw0LjEtMzcuNCwzLjgtNTUuNy0yLjRjLTQuOC0xLjYtOS40LTMuOS0xMy4xLTcuNWMtMi44LTIuNy00LjMtNS44LTQuMi05LjhjMC4xLTQuMywwLTguNiwwLTEyLjkKCUMyNjQuOCwyMjIuOSwyNjUuMSwyMjEuMywyNjYuMSwyMTkuN3oiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTM4MC45LDM1My45YzE2LjMsMC45LDI1LTE5LjEsMTMuMi0zMC40Yy0xMi40LTExLjktMzIuOC0wLjgtMjkuNiwxNmMtNzMuNyw0Ny0xNjguNS0yMy4zLTE0MS41LTEwOC43CglsLTE4LjItMTIuMkMxNjMuOSwzMjcuMywyODkuOCw0MTkuMiwzODAuOSwzNTMuOXogTTM3NS43LDMzMC40YzcuNi03LjksMTkuNywzLjEsMTIuNiwxMS40QzM4MC44LDM1MC41LDM2Ny42LDMzOC44LDM3NS43LDMzMC40eiIKCS8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yMzIuMiwxOTMuN2MxMS43LDExLjIsMzEsMiwyOS45LTE0YzczLjYtNDcuNCwxNjguOSwyMi44LDE0MS45LDEwOC41bDE4LjIsMTIuMgoJYzM5LjctMTA1LjYtODAuOC0yMDAuNy0xNzQtMTM2LjhDMjMwLjcsMTYwLDIxOS40LDE4MS40LDIzMi4yLDE5My43eiBNMjUwLjYsMTg2LjhjLTcuOCw4LjEtMjAuMS0zLjctMTIuMy0xMS44CglDMjQ2LjEsMTY2LjksMjU4LjQsMTc4LjcsMjUwLjYsMTg2Ljh6Ii8+Cjx0ZXh0IHRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIDEgNTAwLjIwMzIgMzMwLjg3NDMpIj48dHNwYW4geD0iMCIgeT0iMCIgY2xhc3M9InN0MCBzdDIgc3QzIHN0NCI+RGF0YTwvdHNwYW4+PHRzcGFuIHg9IjQ2My4xIiB5PSIwIiBjbGFzcz0ic3QxIHN0MiBzdDMgc3Q0Ij5Db250cm9sbGVyPC90c3Bhbj48L3RleHQ+Cjwvc3ZnPgo= \ No newline at end of file diff --git a/client/src/assets/datacontroller.svg b/client/src/assets/datacontroller.svg new file mode 100644 index 0000000..2143045 --- /dev/null +++ b/client/src/assets/datacontroller.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/client/src/assets/dc-logo.svg b/client/src/assets/dc-logo.svg new file mode 100644 index 0000000..79479cc --- /dev/null +++ b/client/src/assets/dc-logo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/client/src/assets/favicon.ico b/client/src/assets/favicon.ico new file mode 100644 index 0000000..b888dfb Binary files /dev/null and b/client/src/assets/favicon.ico differ diff --git a/client/src/environments/_eula.ts b/client/src/environments/_eula.ts new file mode 100644 index 0000000..9547382 --- /dev/null +++ b/client/src/environments/_eula.ts @@ -0,0 +1,31 @@ +//IMPORTANT: THIS FILE IS AUTO GENERATED BASED ON LICENCE.MD FILE! +export const EULA = ` +Licence Agreement for Data Controller for SAS® +==================== + +Copyright (c) Bowe IO Ltd + +Data Controller is a software distributed by 4GL Apps, a brand owned by Bowe IO Ltd, a UK Limited Company headquarted in 29 Oldfield Rd, Cumbria, registered by companies house under number 08777171, VAT number: 203914240 + +This software is protected by applicable copyright laws, including international treaties, and dual- +licensed – depending on whether your use for commercial purposes, meaning intended for or +resulting in commercial advantage or monetary compensation, or not. + +If your use is strictly personal or solely for evaluation purposes, meaning for the purposes of testing +the suitability, performance, and usefulness of this software outside the production environment, +you agree to be bound by the terms included in the "licence-non-commercial-datacontroller.md" file. + +Your use of this software for commercial purposes is subject to the terms included in an applicable +license agreement. + +In any case, you must not make any such use of this software as to develop software which may be +considered competitive with this software. + +UNLESS EXPRESSLY AGREED OTHERWISE, 4GL APPS PROVIDES THIS SOFTWARE ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, AND IN NO EVENT AND UNDER NO +LEGAL THEORY, SHALL 4GL APPS BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM +USE OR INABILITY TO USE THIS SOFTWARE. + + +` \ No newline at end of file diff --git a/client/src/environments/environment.prod.ts b/client/src/environments/environment.prod.ts new file mode 100644 index 0000000..e283758 --- /dev/null +++ b/client/src/environments/environment.prod.ts @@ -0,0 +1,4 @@ +export const environment = { + production: true, + commitId: 'to be updated' // process.env.CI_COMMIT_ID +} diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts new file mode 100644 index 0000000..218675c --- /dev/null +++ b/client/src/environments/environment.ts @@ -0,0 +1,9 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `angular-cli.json`. + +export const environment = { + production: false, + commitId: 'to be updated' // process.env.CI_COMMIT_ID +} diff --git a/client/src/eula.ts b/client/src/eula.ts new file mode 100644 index 0000000..7ebc757 --- /dev/null +++ b/client/src/eula.ts @@ -0,0 +1,30 @@ +/** + * Recreate _eula.ts based on LICENCE.md an put it in environments folder so it can be used in the angular components + */ + +const { readFileSync } = require('fs') +const { resolve, relative } = require('path') +const { writeFileSync } = require('fs-extra') + +const file = resolve(__dirname, '..', 'src', 'environments', '_eula.ts') + +const licenceFilePath = resolve(__dirname, '..', '..', 'LICENCE.md') + +try { + const licence = readFileSync(licenceFilePath).toString() + + writeFileSync( + file, + `//IMPORTANT: THIS FILE IS AUTO GENERATED BASED ON LICENCE.MD FILE!\nexport const EULA = \`\n${licence}\n\``, + { encoding: 'utf-8' } + ) + + console.log( + `Created _eula.ts based on LICENCE.MD in: ${relative( + resolve(__dirname, '..'), + file + )}` + ) +} catch (e) { + console.log(e) +} diff --git a/client/src/formatToParts.polyfill.js b/client/src/formatToParts.polyfill.js new file mode 100644 index 0000000..06dbec1 --- /dev/null +++ b/client/src/formatToParts.polyfill.js @@ -0,0 +1,526 @@ +'use strict' + +const localeData = require('./locale-data.json') + +Intl.DateTimeFormat.prototype.formatToParts = function (date) { + let options = this.resolvedOptions() + let formats = createDateTimeFormats(localeData.date.formats) + let opt = {} + for (var prop in dateTimeComponents) { + if (!hop.call(dateTimeComponents, prop)) continue + + var value = options[prop] + opt['[[' + prop + ']]'] = value + } + + let score = calculateScore(opt, formats) + return FormatToPartsDateTime(score, date) +} + +function FormatToPartsDateTime(internal, x) { + if (!isFinite(x)) + throw new RangeError('Invalid valid date passed to formatToParts') + + var locale = 'en-US', + pattern = internal.pattern, + nf = new Intl.NumberFormat([locale], { useGrouping: false }), + nf2 = new Intl.NumberFormat([locale], { + minimumIntegerDigits: 2, + useGrouping: false + }), + tm = ToLocalTime(x), + ca = 'gregory', + caLocaleData = localeData.date.calendars, + result = [] + + var componentsRe = /{([^}]+)}/g + var match + var currentIndex = 0 + while ((match = componentsRe.exec(pattern)) !== null) { + if (currentIndex < match.index) { + result.push({ + type: 'separator', + value: pattern.substr(currentIndex, match.index - currentIndex) + }) + } + var p = match[1] + var fv = null + + if (hop.call(internal, p)) { + var pm, + f = internal[p], + v = tm['[[' + p + ']]'] + + if (p === 'year' && v <= 0) v = 1 - v + else if (p === 'month') v++ + else if (p === 'hour' && internal['[[hour12]]'] === true) { + v = v % 12 + pm = v !== tm['[[' + p + ']]'] + if (v === 0 && internal['[[hourNo0]]'] === true) v = 12 + } + + if (f === 'numeric') fv = v + else if (f === '2-digit') { + fv = v + if (fv.length > 2) fv = fv.slice(-2) + } else if (f in dateWidths) { + switch (p) { + case 'month': + fv = resolveDateString( + caLocaleData, + ca, + 'months', + f, + tm['[[' + p + ']]'] + ) + break + case 'weekday': + try { + fv = resolveDateString( + caLocaleData, + ca, + 'days', + f, + tm['[[' + p + ']]'] + ) + } catch (e) { + throw new Error( + 'Could not find weekday data for locale ' + locale + ) + } + break + case 'timeZoneName': + fv = '' // TODO + break + default: + fv = tm['[[' + p + ']]'] + } + } + } else if (p === 'ampm') { + fv = resolveDateString(caLocaleData, ca, 'dayPeriods', pm ? 'pm' : 'am') + } + if (fv !== null) { + result.push({ + type: match[1], + value: fv + }) + currentIndex = match.index + match[0].length + } + } + if (currentIndex < pattern.length) { + result.push({ + type: 'separator', + value: pattern.substr(currentIndex) + }) + } + + return result +} + +// core.js +var hop = Object.prototype.hasOwnProperty +var arrIndexOf = Array.prototype.indexOf +var dateWidths = Object.create(null, { narrow: {}, short: {}, long: {} }) + +var dateTimeComponents = { + weekday: ['narrow', 'short', 'long'], + era: ['narrow', 'short', 'long'], + year: ['2-digit', 'numeric'], + month: ['2-digit', 'numeric', 'narrow', 'short', 'long'], + day: ['2-digit', 'numeric'], + hour: ['2-digit', 'numeric'], + minute: ['2-digit', 'numeric'], + second: ['2-digit', 'numeric'], + timeZoneName: ['short', 'long'] +} + +/** + * Calculates score for BestFitFormatMatcher and BasicFormatMatcher. + * Abstracted from BasicFormatMatcher section. + */ +function calculateScore(options, formats, bestFit) { + var // Additional penalty type when bestFit === true + diffDataTypePenalty = 8, + // 1. Let removalPenalty be 120. + removalPenalty = 120, + // 2. Let additionPenalty be 20. + additionPenalty = 20, + // 3. Let longLessPenalty be 8. + longLessPenalty = 8, + // 4. Let longMorePenalty be 6. + longMorePenalty = 6, + // 5. Let shortLessPenalty be 6. + shortLessPenalty = 6, + // 6. Let shortMorePenalty be 3. + shortMorePenalty = 3, + // 7. Let bestScore be -Infinity. + bestScore = -Infinity, + // 8. Let bestFormat be undefined. + bestFormat, + // 9. Let i be 0. + i = 0, + // 10. Let len be the result of calling the [[Get]] internal method of formats with argument "length". + len = formats.length + + // 11. Repeat while i < len: + while (i < len) { + var // a. Let format be the result of calling the [[Get]] internal method of formats with argument ToString(i). + format = formats[i], + // b. Let score be 0. + score = 0 + + // c. For each property shown in Table 3: + for (var property in dateTimeComponents) { + if (!hop.call(dateTimeComponents, property)) continue + + var // i. Let optionsProp be options.[[]]. + optionsProp = options['[[' + property + ']]'], + // ii. Let formatPropDesc be the result of calling the [[GetOwnProperty]] internal method of format + // with argument property. + // iii. If formatPropDesc is not undefined, then + // 1. Let formatProp be the result of calling the [[Get]] internal method of format with argument property. + formatProp = hop.call(format, property) ? format[property] : undefined + + // iv. If optionsProp is undefined and formatProp is not undefined, then decrease score by + // additionPenalty. + if (optionsProp === undefined && formatProp !== undefined) + score -= additionPenalty + // v. Else if optionsProp is not undefined and formatProp is undefined, then decrease score by + // removalPenalty. + else if (optionsProp !== undefined && formatProp === undefined) + score -= removalPenalty + // vi. Else + else { + var // 1. Let values be the array ["2-digit", "numeric", "narrow", "short", + // "long"]. + values = ['2-digit', 'numeric', 'narrow', 'short', 'long'], + // 2. Let optionsPropIndex be the index of optionsProp within values. + optionsPropIndex = arrIndexOf.call(values, optionsProp), + // 3. Let formatPropIndex be the index of formatProp within values. + formatPropIndex = arrIndexOf.call(values, formatProp), + // 4. Let delta be max(min(formatPropIndex - optionsPropIndex, 2), -2). + delta = Math.max(Math.min(formatPropIndex - optionsPropIndex, 2), -2) + + // When the bestFit argument is true, subtract additional penalty where data types are not the same + if ( + bestFit && + (((optionsProp === 'numeric' || optionsProp === '2-digit') && + formatProp !== 'numeric' && + formatProp !== '2-digit') || + (optionsProp !== 'numeric' && + optionsProp !== '2-digit' && + (formatProp === '2-digit' || formatProp === 'numeric'))) + ) + score -= diffDataTypePenalty + + // 5. If delta = 2, decrease score by longMorePenalty. + if (delta === 2) score -= longMorePenalty + // 6. Else if delta = 1, decrease score by shortMorePenalty. + else if (delta === 1) score -= shortMorePenalty + // 7. Else if delta = -1, decrease score by shortLessPenalty. + else if (delta === -1) score -= shortLessPenalty + // 8. Else if delta = -2, decrease score by longLessPenalty. + else if (delta === -2) score -= longLessPenalty + } + } + + // d. If score > bestScore, then + if (score > bestScore) { + // i. Let bestScore be score. + bestScore = score + + // ii. Let bestFormat be format. + bestFormat = format + } + + // e. Increase i by 1. + i++ + } + + // 12. Return bestFormat. + return bestFormat +} + +function ToLocalTime(date, calendar, timeZone) { + // 1. Apply calendrical calculations on date for the given calendar and time zone to + // produce weekday, era, year, month, day, hour, minute, second, and inDST values. + // The calculations should use best available information about the specified + // calendar and time zone. If the calendar is "gregory", then the calculations must + // match the algorithms specified in ES5, 15.9.1, except that calculations are not + // bound by the restrictions on the use of best available information on time zones + // for local time zone adjustment and daylight saving time adjustment imposed by + // ES5, 15.9.1.7 and 15.9.1.8. + // ###TODO### + var d = new Date(date), + m = 'get' + (timeZone || '') + + // 2. Return a Record with fields [[weekday]], [[era]], [[year]], [[month]], [[day]], + // [[hour]], [[minute]], [[second]], and [[inDST]], each with the corresponding + // calculated value. + return { + '[[weekday]]': d[m + 'Day'](), + '[[era]]': +(d[m + 'FullYear']() >= 0), + '[[year]]': d[m + 'FullYear'](), + '[[month]]': d[m + 'Month'](), + '[[day]]': d[m + 'Date'](), + '[[hour]]': d[m + 'Hours'](), + '[[minute]]': d[m + 'Minutes'](), + '[[second]]': d[m + 'Seconds'](), + '[[inDST]]': false // ###TODO### + } +} + +function resolveDateString(data, ca, component, width, key) { + // From http://www.unicode.org/reports/tr35/tr35.html#Multiple_Inheritance: + // 'In clearly specified instances, resources may inherit from within the same locale. + // For example, ... the Buddhist calendar inherits from the Gregorian calendar.' + var obj = + data[ca] && data[ca][component] + ? data[ca][component] + : data.gregory[component], + // "sideways" inheritance resolves strings when a key doesn't exist + alts = { + narrow: ['short', 'long'], + short: ['long', 'narrow'], + long: ['short', 'narrow'] + }, + // + resolved = hop.call(obj, width) + ? obj[width] + : hop.call(obj, alts[width][0]) + ? obj[alts[width][0]] + : obj[alts[width][1]] + + // `key` wouldn't be specified for components 'dayPeriods' + return key != null ? resolved[key] : resolved +} + +// CLDR + +// Match these datetime components in a CLDR pattern, except those in single quotes +var expDTComponents = + /(?:[Eec]{1,6}|G{1,5}|(?:[yYu]+|U{1,5})|[ML]{1,5}|d{1,2}|a|[hkHK]{1,2}|m{1,2}|s{1,2}|z{1,4})(?=([^']*'[^']*')*[^']*$)/g + +// Skip over patterns with these datetime components +var unwantedDTCs = /[QxXVOvZASjgFDwWIQqH]/ + +// Maps the number of characters in a CLDR pattern to the specification +var dtcLengthMap = { + month: ['numeric', '2-digit', 'short', 'long', 'narrow'], + weekday: ['short', 'short', 'short', 'long', 'narrow'], + era: ['short', 'short', 'short', 'long', 'narrow'] +} + +var dtKeys = ['weekday', 'era', 'year', 'month', 'day'] +var tmKeys = ['hour', 'minute', 'second', 'timeZoneName'] + +function isDateFormatOnly(obj) { + for (var i = 0; i < tmKeys.length; i += 1) { + if (obj.hasOwnProperty(tmKeys[i])) { + return false + } + } + return true +} + +function isTimeFormatOnly(obj) { + for (var i = 0; i < dtKeys.length; i += 1) { + if (obj.hasOwnProperty(dtKeys[i])) { + return false + } + } + return true +} + +/** + * Converts the CLDR availableFormats into the objects and patterns required by + * the ECMAScript Internationalization API specification. + */ +function createDateTimeFormat(format) { + if (unwantedDTCs.test(format)) return undefined + + var formatObj = {} + + // Replace the pattern string with the one required by the specification, whilst + // at the same time evaluating it for the subsets and formats + formatObj.pattern = format.replace(expDTComponents, function ($0) { + // See which symbol we're dealing with + switch ($0.charAt(0)) { + case 'E': + case 'e': + case 'c': + formatObj.weekday = dtcLengthMap.weekday[$0.length - 1] + return '{weekday}' + + // Not supported yet + case 'G': + formatObj.era = dtcLengthMap.era[$0.length - 1] + return '{era}' + + case 'y': + case 'Y': + case 'u': + case 'U': + formatObj.year = $0.length === 2 ? '2-digit' : 'numeric' + return '{year}' + + case 'M': + case 'L': + formatObj.month = dtcLengthMap.month[$0.length - 1] + return '{month}' + + case 'd': + formatObj.day = $0.length === 2 ? '2-digit' : 'numeric' + return '{day}' + + case 'a': + return '{ampm}' + + case 'h': + case 'H': + case 'k': + case 'K': + formatObj.hour = $0.length === 2 ? '2-digit' : 'numeric' + return '{hour}' + + case 'm': + formatObj.minute = $0.length === 2 ? '2-digit' : 'numeric' + return '{minute}' + + case 's': + formatObj.second = $0.length === 2 ? '2-digit' : 'numeric' + return '{second}' + + case 'z': + formatObj.timeZoneName = $0.length < 4 ? 'short' : 'long' + return '{timeZoneName}' + } + }) + + // From http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns: + // 'In patterns, two single quotes represents a literal single quote, either + // inside or outside single quotes. Text within single quotes is not + // interpreted in any way (except for two adjacent single quotes).' + formatObj.pattern = formatObj.pattern.replace( + /'([^']*)'/g, + function ($0, literal) { + return literal ? literal : "'" + } + ) + + if (formatObj.pattern.indexOf('{ampm}') > -1) { + formatObj.hour12 = true + formatObj.pattern12 = formatObj.pattern + formatObj.pattern = formatObj.pattern + .replace('{ampm}', '') + .replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '') + } + + return formatObj +} + +/** + * Processes DateTime formats from CLDR to an easier-to-parse format. + * the result of this operation should be cached the first time a particular + * calendar is analyzed. + * + * The specification requires we support at least the following subsets of + * date/time components: + * + * - 'weekday', 'year', 'month', 'day', 'hour', 'minute', 'second' + * - 'weekday', 'year', 'month', 'day' + * - 'year', 'month', 'day' + * - 'year', 'month' + * - 'month', 'day' + * - 'hour', 'minute', 'second' + * - 'hour', 'minute' + * + * We need to cherry pick at least these subsets from the CLDR data and convert + * them into the pattern objects used in the ECMA-402 API. + */ +function createDateTimeFormats(formats) { + var availableFormats = formats.availableFormats + var timeFormats = formats.timeFormats + var dateFormats = formats.dateFormats + var order = formats.medium + var result = [] + var key, format, computed, i, j + var timeRelatedFormats = [] + var dateRelatedFormats = [] + + function expandFormat(key, pattern) { + // Expand component lengths if necessary, as allowed in the LDML spec + // Get the lengths of 'M' and 'E' substrings in the date pattern + // as arrays that can be joined to create a new substring + var M = new Array((key.match(/M/g) || []).length + 1) + var E = new Array((key.match(/E/g) || []).length + 1) + + // note from caridy: I'm not sure we really need this, seems to be + // useless since it relies on the keys from CLDR + // instead of the actual format pattern, but I'm not sure. + if (M.length > 2) pattern = pattern.replace(/(M|L)+/, M.join('$1')) + + if (E.length > 2) pattern = pattern.replace(/([Eec])+/, E.join('$1')) + + return pattern + } + + // Map available (custom) formats into a pattern for createDateTimeFormats + for (key in availableFormats) { + if (availableFormats.hasOwnProperty(key)) { + format = expandFormat(key, availableFormats[key]) + computed = createDateTimeFormat(format) + if (computed) { + result.push(computed) + // in some cases, the format is only displaying date specific props + // or time specific props, in which case we need to also produce the + // combined formats. + if (isDateFormatOnly(computed)) { + dateRelatedFormats.push(format) + } else if (isTimeFormatOnly(computed)) { + timeRelatedFormats.push(format) + } + } + } + } + + // combine custom time and custom date formats when they are orthogonals to complete the + // formats supported by browsers by relying on the value of "formats.medium" which defines + // how to join custom formats into a single pattern. + for (i = 0; i < timeRelatedFormats.length; i += 1) { + for (j = 0; j < dateRelatedFormats.length; j += 1) { + format = order + .replace('{0}', timeRelatedFormats[i]) + .replace('{1}', dateRelatedFormats[j]) + .replace(/^[,\s]+|[,\s]+$/gi, '') + computed = createDateTimeFormat(format) + if (computed) { + result.push(computed) + } + } + } + + // Map time formats into a pattern for createDateTimeFormats + for (key in timeFormats) { + if (timeFormats.hasOwnProperty(key)) { + format = expandFormat(key, timeFormats[key]) + computed = createDateTimeFormat(format) + if (computed) { + result.push(computed) + } + } + } + + // Map date formats into a pattern for createDateTimeFormats + for (key in dateFormats) { + if (dateFormats.hasOwnProperty(key)) { + format = expandFormat(key, dateFormats[key]) + computed = createDateTimeFormat(format) + if (computed) { + result.push(computed) + } + } + } + + return result +} diff --git a/client/src/images/caret.svg b/client/src/images/caret.svg new file mode 100644 index 0000000..a7360a9 --- /dev/null +++ b/client/src/images/caret.svg @@ -0,0 +1,7 @@ + + + + + Caret + + diff --git a/client/src/images/datacontroller.svg b/client/src/images/datacontroller.svg new file mode 100644 index 0000000..2143045 --- /dev/null +++ b/client/src/images/datacontroller.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/client/src/images/dc-logo.svg b/client/src/images/dc-logo.svg new file mode 100644 index 0000000..79479cc --- /dev/null +++ b/client/src/images/dc-logo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/client/src/images/favicon.ico b/client/src/images/favicon.ico new file mode 100644 index 0000000..b888dfb Binary files /dev/null and b/client/src/images/favicon.ico differ diff --git a/client/src/images/spinner.svg b/client/src/images/spinner.svg new file mode 100644 index 0000000..142164a --- /dev/null +++ b/client/src/images/spinner.svg @@ -0,0 +1,23 @@ + + + + + Preloader_72x2 + + + + diff --git a/client/src/index.html b/client/src/index.html new file mode 100644 index 0000000..80cd4f2 --- /dev/null +++ b/client/src/index.html @@ -0,0 +1,63 @@ + + + + + Data Controller + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/locale-data.json b/client/src/locale-data.json new file mode 100644 index 0000000..c0fcde2 --- /dev/null +++ b/client/src/locale-data.json @@ -0,0 +1,1803 @@ +{ + "locale": "en", + "date": { + "ca": [ + "gregory", + "buddhist", + "chinese", + "coptic", + "dangi", + "ethioaa", + "ethiopic", + "generic", + "hebrew", + "indian", + "islamic", + "islamicc", + "japanese", + "persian", + "roc" + ], + "hourNo0": true, + "hour12": true, + "formats": { + "short": "{1}, {0}", + "medium": "{1}, {0}", + "full": "{1} 'at' {0}", + "long": "{1} 'at' {0}", + "availableFormats": { + "d": "d", + "E": "ccc", + "Ed": "d E", + "Ehm": "E h:mm a", + "EHm": "E HH:mm", + "Ehms": "E h:mm:ss a", + "EHms": "E HH:mm:ss", + "Gy": "y G", + "GyMMM": "MMM y G", + "GyMMMd": "MMM d, y G", + "GyMMMEd": "E, MMM d, y G", + "h": "h a", + "H": "HH", + "hm": "h:mm a", + "Hm": "HH:mm", + "hms": "h:mm:ss a", + "Hms": "HH:mm:ss", + "hmsv": "h:mm:ss a v", + "Hmsv": "HH:mm:ss v", + "hmv": "h:mm a v", + "Hmv": "HH:mm v", + "M": "L", + "Md": "M/d", + "MEd": "E, M/d", + "MMM": "LLL", + "MMMd": "MMM d", + "MMMEd": "E, MMM d", + "MMMMd": "MMMM d", + "ms": "mm:ss", + "y": "y", + "yM": "M/y", + "yMd": "M/d/y", + "yMEd": "E, M/d/y", + "yMMM": "MMM y", + "yMMMd": "MMM d, y", + "yMMMEd": "E, MMM d, y", + "yMMMM": "MMMM y", + "yQQQ": "QQQ y", + "yQQQQ": "QQQQ y" + }, + "dateFormats": { + "yMMMMEEEEd": "EEEE, MMMM d, y", + "yMMMMd": "MMMM d, y", + "yMMMd": "MMM d, y", + "yMd": "M/d/yy" + }, + "timeFormats": { + "hmmsszzzz": "h:mm:ss a zzzz", + "hmsz": "h:mm:ss a z", + "hms": "h:mm:ss a", + "hm": "h:mm a" + } + }, + "calendars": { + "buddhist": { + "months": { + "narrow": [ + "J", + "F", + "M", + "A", + "M", + "J", + "J", + "A", + "S", + "O", + "N", + "D" + ], + "short": [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ], + "long": [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["BE"], "short": ["BE"], "long": ["BE"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "chinese": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Mo1", + "Mo2", + "Mo3", + "Mo4", + "Mo5", + "Mo6", + "Mo7", + "Mo8", + "Mo9", + "Mo10", + "Mo11", + "Mo12" + ], + "long": [ + "Month1", + "Month2", + "Month3", + "Month4", + "Month5", + "Month6", + "Month7", + "Month8", + "Month9", + "Month10", + "Month11", + "Month12" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "coptic": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13" + ], + "short": [ + "Tout", + "Baba", + "Hator", + "Kiahk", + "Toba", + "Amshir", + "Baramhat", + "Baramouda", + "Bashans", + "Paona", + "Epep", + "Mesra", + "Nasie" + ], + "long": [ + "Tout", + "Baba", + "Hator", + "Kiahk", + "Toba", + "Amshir", + "Baramhat", + "Baramouda", + "Bashans", + "Paona", + "Epep", + "Mesra", + "Nasie" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": ["ERA0", "ERA1"], + "short": ["ERA0", "ERA1"], + "long": ["ERA0", "ERA1"] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "dangi": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Mo1", + "Mo2", + "Mo3", + "Mo4", + "Mo5", + "Mo6", + "Mo7", + "Mo8", + "Mo9", + "Mo10", + "Mo11", + "Mo12" + ], + "long": [ + "Month1", + "Month2", + "Month3", + "Month4", + "Month5", + "Month6", + "Month7", + "Month8", + "Month9", + "Month10", + "Month11", + "Month12" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "ethiopic": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13" + ], + "short": [ + "Meskerem", + "Tekemt", + "Hedar", + "Tahsas", + "Ter", + "Yekatit", + "Megabit", + "Miazia", + "Genbot", + "Sene", + "Hamle", + "Nehasse", + "Pagumen" + ], + "long": [ + "Meskerem", + "Tekemt", + "Hedar", + "Tahsas", + "Ter", + "Yekatit", + "Megabit", + "Miazia", + "Genbot", + "Sene", + "Hamle", + "Nehasse", + "Pagumen" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": ["ERA0", "ERA1"], + "short": ["ERA0", "ERA1"], + "long": ["ERA0", "ERA1"] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "ethioaa": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13" + ], + "short": [ + "Meskerem", + "Tekemt", + "Hedar", + "Tahsas", + "Ter", + "Yekatit", + "Megabit", + "Miazia", + "Genbot", + "Sene", + "Hamle", + "Nehasse", + "Pagumen" + ], + "long": [ + "Meskerem", + "Tekemt", + "Hedar", + "Tahsas", + "Ter", + "Yekatit", + "Megabit", + "Miazia", + "Genbot", + "Sene", + "Hamle", + "Nehasse", + "Pagumen" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["ERA0"], "short": ["ERA0"], "long": ["ERA0"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "generic": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "M01", + "M02", + "M03", + "M04", + "M05", + "M06", + "M07", + "M08", + "M09", + "M10", + "M11", + "M12" + ], + "long": [ + "M01", + "M02", + "M03", + "M04", + "M05", + "M06", + "M07", + "M08", + "M09", + "M10", + "M11", + "M12" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": ["ERA0", "ERA1"], + "short": ["ERA0", "ERA1"], + "long": ["ERA0", "ERA1"] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "gregory": { + "months": { + "narrow": [ + "J", + "F", + "M", + "A", + "M", + "J", + "J", + "A", + "S", + "O", + "N", + "D" + ], + "short": [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ], + "long": [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": ["B", "A", "BCE", "CE"], + "short": ["BC", "AD", "BCE", "CE"], + "long": [ + "Before Christ", + "Anno Domini", + "Before Common Era", + "Common Era" + ] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "hebrew": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "7" + ], + "short": [ + "Tishri", + "Heshvan", + "Kislev", + "Tevet", + "Shevat", + "Adar I", + "Adar", + "Nisan", + "Iyar", + "Sivan", + "Tamuz", + "Av", + "Elul", + "Adar II" + ], + "long": [ + "Tishri", + "Heshvan", + "Kislev", + "Tevet", + "Shevat", + "Adar I", + "Adar", + "Nisan", + "Iyar", + "Sivan", + "Tamuz", + "Av", + "Elul", + "Adar II" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["AM"], "short": ["AM"], "long": ["AM"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "indian": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Chaitra", + "Vaisakha", + "Jyaistha", + "Asadha", + "Sravana", + "Bhadra", + "Asvina", + "Kartika", + "Agrahayana", + "Pausa", + "Magha", + "Phalguna" + ], + "long": [ + "Chaitra", + "Vaisakha", + "Jyaistha", + "Asadha", + "Sravana", + "Bhadra", + "Asvina", + "Kartika", + "Agrahayana", + "Pausa", + "Magha", + "Phalguna" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["Saka"], "short": ["Saka"], "long": ["Saka"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "islamic": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Muh.", + "Saf.", + "Rab. I", + "Rab. II", + "Jum. I", + "Jum. II", + "Raj.", + "Sha.", + "Ram.", + "Shaw.", + "Dhuʻl-Q.", + "Dhuʻl-H." + ], + "long": [ + "Muharram", + "Safar", + "Rabiʻ I", + "Rabiʻ II", + "Jumada I", + "Jumada II", + "Rajab", + "Shaʻban", + "Ramadan", + "Shawwal", + "Dhuʻl-Qiʻdah", + "Dhuʻl-Hijjah" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["AH"], "short": ["AH"], "long": ["AH"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "islamicc": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Muh.", + "Saf.", + "Rab. I", + "Rab. II", + "Jum. I", + "Jum. II", + "Raj.", + "Sha.", + "Ram.", + "Shaw.", + "Dhuʻl-Q.", + "Dhuʻl-H." + ], + "long": [ + "Muharram", + "Safar", + "Rabiʻ I", + "Rabiʻ II", + "Jumada I", + "Jumada II", + "Rajab", + "Shaʻban", + "Ramadan", + "Shawwal", + "Dhuʻl-Qiʻdah", + "Dhuʻl-Hijjah" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["AH"], "short": ["AH"], "long": ["AH"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "japanese": { + "months": { + "narrow": [ + "J", + "F", + "M", + "A", + "M", + "J", + "J", + "A", + "S", + "O", + "N", + "D" + ], + "short": [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ], + "long": [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": [ + "Taika (645–650)", + "Hakuchi (650–671)", + "Hakuhō (672–686)", + "Shuchō (686–701)", + "Taihō (701–704)", + "Keiun (704–708)", + "Wadō (708–715)", + "Reiki (715–717)", + "Yōrō (717–724)", + "Jinki (724–729)", + "Tenpyō (729–749)", + "Tenpyō-kampō (749-749)", + "Tenpyō-shōhō (749-757)", + "Tenpyō-hōji (757-765)", + "Tenpyō-jingo (765-767)", + "Jingo-keiun (767-770)", + "Hōki (770–780)", + "Ten-ō (781-782)", + "Enryaku (782–806)", + "Daidō (806–810)", + "Kōnin (810–824)", + "Tenchō (824–834)", + "Jōwa (834–848)", + "Kajō (848–851)", + "Ninju (851–854)", + "Saikō (854–857)", + "Ten-an (857-859)", + "Jōgan (859–877)", + "Gangyō (877–885)", + "Ninna (885–889)", + "Kanpyō (889–898)", + "Shōtai (898–901)", + "Engi (901–923)", + "Enchō (923–931)", + "Jōhei (931–938)", + "Tengyō (938–947)", + "Tenryaku (947–957)", + "Tentoku (957–961)", + "Ōwa (961–964)", + "Kōhō (964–968)", + "Anna (968–970)", + "Tenroku (970–973)", + "Ten’en (973–976)", + "Jōgen (976–978)", + "Tengen (978–983)", + "Eikan (983–985)", + "Kanna (985–987)", + "Eien (987–989)", + "Eiso (989–990)", + "Shōryaku (990–995)", + "Chōtoku (995–999)", + "Chōhō (999–1004)", + "Kankō (1004–1012)", + "Chōwa (1012–1017)", + "Kannin (1017–1021)", + "Jian (1021–1024)", + "Manju (1024–1028)", + "Chōgen (1028–1037)", + "Chōryaku (1037–1040)", + "Chōkyū (1040–1044)", + "Kantoku (1044–1046)", + "Eishō (1046–1053)", + "Tengi (1053–1058)", + "Kōhei (1058–1065)", + "Jiryaku (1065–1069)", + "Enkyū (1069–1074)", + "Shōho (1074–1077)", + "Shōryaku (1077–1081)", + "Eihō (1081–1084)", + "Ōtoku (1084–1087)", + "Kanji (1087–1094)", + "Kahō (1094–1096)", + "Eichō (1096–1097)", + "Jōtoku (1097–1099)", + "Kōwa (1099–1104)", + "Chōji (1104–1106)", + "Kashō (1106–1108)", + "Tennin (1108–1110)", + "Ten-ei (1110-1113)", + "Eikyū (1113–1118)", + "Gen’ei (1118–1120)", + "Hōan (1120–1124)", + "Tenji (1124–1126)", + "Daiji (1126–1131)", + "Tenshō (1131–1132)", + "Chōshō (1132–1135)", + "Hōen (1135–1141)", + "Eiji (1141–1142)", + "Kōji (1142–1144)", + "Ten’yō (1144–1145)", + "Kyūan (1145–1151)", + "Ninpei (1151–1154)", + "Kyūju (1154–1156)", + "Hōgen (1156–1159)", + "Heiji (1159–1160)", + "Eiryaku (1160–1161)", + "Ōho (1161–1163)", + "Chōkan (1163–1165)", + "Eiman (1165–1166)", + "Nin’an (1166–1169)", + "Kaō (1169–1171)", + "Shōan (1171–1175)", + "Angen (1175–1177)", + "Jishō (1177–1181)", + "Yōwa (1181–1182)", + "Juei (1182–1184)", + "Genryaku (1184–1185)", + "Bunji (1185–1190)", + "Kenkyū (1190–1199)", + "Shōji (1199–1201)", + "Kennin (1201–1204)", + "Genkyū (1204–1206)", + "Ken’ei (1206–1207)", + "Jōgen (1207–1211)", + "Kenryaku (1211–1213)", + "Kenpō (1213–1219)", + "Jōkyū (1219–1222)", + "Jōō (1222–1224)", + "Gennin (1224–1225)", + "Karoku (1225–1227)", + "Antei (1227–1229)", + "Kanki (1229–1232)", + "Jōei (1232–1233)", + "Tenpuku (1233–1234)", + "Bunryaku (1234–1235)", + "Katei (1235–1238)", + "Ryakunin (1238–1239)", + "En’ō (1239–1240)", + "Ninji (1240–1243)", + "Kangen (1243–1247)", + "Hōji (1247–1249)", + "Kenchō (1249–1256)", + "Kōgen (1256–1257)", + "Shōka (1257–1259)", + "Shōgen (1259–1260)", + "Bun’ō (1260–1261)", + "Kōchō (1261–1264)", + "Bun’ei (1264–1275)", + "Kenji (1275–1278)", + "Kōan (1278–1288)", + "Shōō (1288–1293)", + "Einin (1293–1299)", + "Shōan (1299–1302)", + "Kengen (1302–1303)", + "Kagen (1303–1306)", + "Tokuji (1306–1308)", + "Enkyō (1308–1311)", + "Ōchō (1311–1312)", + "Shōwa (1312–1317)", + "Bunpō (1317–1319)", + "Genō (1319–1321)", + "Genkō (1321–1324)", + "Shōchū (1324–1326)", + "Karyaku (1326–1329)", + "Gentoku (1329–1331)", + "Genkō (1331–1334)", + "Kenmu (1334–1336)", + "Engen (1336–1340)", + "Kōkoku (1340–1346)", + "Shōhei (1346–1370)", + "Kentoku (1370–1372)", + "Bunchū (1372–1375)", + "Tenju (1375–1379)", + "Kōryaku (1379–1381)", + "Kōwa (1381–1384)", + "Genchū (1384–1392)", + "Meitoku (1384–1387)", + "Kakei (1387–1389)", + "Kōō (1389–1390)", + "Meitoku (1390–1394)", + "Ōei (1394–1428)", + "Shōchō (1428–1429)", + "Eikyō (1429–1441)", + "Kakitsu (1441–1444)", + "Bun’an (1444–1449)", + "Hōtoku (1449–1452)", + "Kyōtoku (1452–1455)", + "Kōshō (1455–1457)", + "Chōroku (1457–1460)", + "Kanshō (1460–1466)", + "Bunshō (1466–1467)", + "Ōnin (1467–1469)", + "Bunmei (1469–1487)", + "Chōkyō (1487–1489)", + "Entoku (1489–1492)", + "Meiō (1492–1501)", + "Bunki (1501–1504)", + "Eishō (1504–1521)", + "Taiei (1521–1528)", + "Kyōroku (1528–1532)", + "Tenbun (1532–1555)", + "Kōji (1555–1558)", + "Eiroku (1558–1570)", + "Genki (1570–1573)", + "Tenshō (1573–1592)", + "Bunroku (1592–1596)", + "Keichō (1596–1615)", + "Genna (1615–1624)", + "Kan’ei (1624–1644)", + "Shōho (1644–1648)", + "Keian (1648–1652)", + "Jōō (1652–1655)", + "Meireki (1655–1658)", + "Manji (1658–1661)", + "Kanbun (1661–1673)", + "Enpō (1673–1681)", + "Tenna (1681–1684)", + "Jōkyō (1684–1688)", + "Genroku (1688–1704)", + "Hōei (1704–1711)", + "Shōtoku (1711–1716)", + "Kyōhō (1716–1736)", + "Genbun (1736–1741)", + "Kanpō (1741–1744)", + "Enkyō (1744–1748)", + "Kan’en (1748–1751)", + "Hōreki (1751–1764)", + "Meiwa (1764–1772)", + "An’ei (1772–1781)", + "Tenmei (1781–1789)", + "Kansei (1789–1801)", + "Kyōwa (1801–1804)", + "Bunka (1804–1818)", + "Bunsei (1818–1830)", + "Tenpō (1830–1844)", + "Kōka (1844–1848)", + "Kaei (1848–1854)", + "Ansei (1854–1860)", + "Man’en (1860–1861)", + "Bunkyū (1861–1864)", + "Genji (1864–1865)", + "Keiō (1865–1868)", + "M", + "T", + "S", + "H" + ], + "short": [ + "Taika (645–650)", + "Hakuchi (650–671)", + "Hakuhō (672–686)", + "Shuchō (686–701)", + "Taihō (701–704)", + "Keiun (704–708)", + "Wadō (708–715)", + "Reiki (715–717)", + "Yōrō (717–724)", + "Jinki (724–729)", + "Tenpyō (729–749)", + "Tenpyō-kampō (749-749)", + "Tenpyō-shōhō (749-757)", + "Tenpyō-hōji (757-765)", + "Tenpyō-jingo (765-767)", + "Jingo-keiun (767-770)", + "Hōki (770–780)", + "Ten-ō (781-782)", + "Enryaku (782–806)", + "Daidō (806–810)", + "Kōnin (810–824)", + "Tenchō (824–834)", + "Jōwa (834–848)", + "Kajō (848–851)", + "Ninju (851–854)", + "Saikō (854–857)", + "Ten-an (857-859)", + "Jōgan (859–877)", + "Gangyō (877–885)", + "Ninna (885–889)", + "Kanpyō (889–898)", + "Shōtai (898–901)", + "Engi (901–923)", + "Enchō (923–931)", + "Jōhei (931–938)", + "Tengyō (938–947)", + "Tenryaku (947–957)", + "Tentoku (957–961)", + "Ōwa (961–964)", + "Kōhō (964–968)", + "Anna (968–970)", + "Tenroku (970–973)", + "Ten’en (973–976)", + "Jōgen (976–978)", + "Tengen (978–983)", + "Eikan (983–985)", + "Kanna (985–987)", + "Eien (987–989)", + "Eiso (989–990)", + "Shōryaku (990–995)", + "Chōtoku (995–999)", + "Chōhō (999–1004)", + "Kankō (1004–1012)", + "Chōwa (1012–1017)", + "Kannin (1017–1021)", + "Jian (1021–1024)", + "Manju (1024–1028)", + "Chōgen (1028–1037)", + "Chōryaku (1037–1040)", + "Chōkyū (1040–1044)", + "Kantoku (1044–1046)", + "Eishō (1046–1053)", + "Tengi (1053–1058)", + "Kōhei (1058–1065)", + "Jiryaku (1065–1069)", + "Enkyū (1069–1074)", + "Shōho (1074–1077)", + "Shōryaku (1077–1081)", + "Eihō (1081–1084)", + "Ōtoku (1084–1087)", + "Kanji (1087–1094)", + "Kahō (1094–1096)", + "Eichō (1096–1097)", + "Jōtoku (1097–1099)", + "Kōwa (1099–1104)", + "Chōji (1104–1106)", + "Kashō (1106–1108)", + "Tennin (1108–1110)", + "Ten-ei (1110-1113)", + "Eikyū (1113–1118)", + "Gen’ei (1118–1120)", + "Hōan (1120–1124)", + "Tenji (1124–1126)", + "Daiji (1126–1131)", + "Tenshō (1131–1132)", + "Chōshō (1132–1135)", + "Hōen (1135–1141)", + "Eiji (1141–1142)", + "Kōji (1142–1144)", + "Ten’yō (1144–1145)", + "Kyūan (1145–1151)", + "Ninpei (1151–1154)", + "Kyūju (1154–1156)", + "Hōgen (1156–1159)", + "Heiji (1159–1160)", + "Eiryaku (1160–1161)", + "Ōho (1161–1163)", + "Chōkan (1163–1165)", + "Eiman (1165–1166)", + "Nin’an (1166–1169)", + "Kaō (1169–1171)", + "Shōan (1171–1175)", + "Angen (1175–1177)", + "Jishō (1177–1181)", + "Yōwa (1181–1182)", + "Juei (1182–1184)", + "Genryaku (1184–1185)", + "Bunji (1185–1190)", + "Kenkyū (1190–1199)", + "Shōji (1199–1201)", + "Kennin (1201–1204)", + "Genkyū (1204–1206)", + "Ken’ei (1206–1207)", + "Jōgen (1207–1211)", + "Kenryaku (1211–1213)", + "Kenpō (1213–1219)", + "Jōkyū (1219–1222)", + "Jōō (1222–1224)", + "Gennin (1224–1225)", + "Karoku (1225–1227)", + "Antei (1227–1229)", + "Kanki (1229–1232)", + "Jōei (1232–1233)", + "Tenpuku (1233–1234)", + "Bunryaku (1234–1235)", + "Katei (1235–1238)", + "Ryakunin (1238–1239)", + "En’ō (1239–1240)", + "Ninji (1240–1243)", + "Kangen (1243–1247)", + "Hōji (1247–1249)", + "Kenchō (1249–1256)", + "Kōgen (1256–1257)", + "Shōka (1257–1259)", + "Shōgen (1259–1260)", + "Bun’ō (1260–1261)", + "Kōchō (1261–1264)", + "Bun’ei (1264–1275)", + "Kenji (1275–1278)", + "Kōan (1278–1288)", + "Shōō (1288–1293)", + "Einin (1293–1299)", + "Shōan (1299–1302)", + "Kengen (1302–1303)", + "Kagen (1303–1306)", + "Tokuji (1306–1308)", + "Enkyō (1308–1311)", + "Ōchō (1311–1312)", + "Shōwa (1312–1317)", + "Bunpō (1317–1319)", + "Genō (1319–1321)", + "Genkō (1321–1324)", + "Shōchū (1324–1326)", + "Karyaku (1326–1329)", + "Gentoku (1329–1331)", + "Genkō (1331–1334)", + "Kenmu (1334–1336)", + "Engen (1336–1340)", + "Kōkoku (1340–1346)", + "Shōhei (1346–1370)", + "Kentoku (1370–1372)", + "Bunchū (1372–1375)", + "Tenju (1375–1379)", + "Kōryaku (1379–1381)", + "Kōwa (1381–1384)", + "Genchū (1384–1392)", + "Meitoku (1384–1387)", + "Kakei (1387–1389)", + "Kōō (1389–1390)", + "Meitoku (1390–1394)", + "Ōei (1394–1428)", + "Shōchō (1428–1429)", + "Eikyō (1429–1441)", + "Kakitsu (1441–1444)", + "Bun’an (1444–1449)", + "Hōtoku (1449–1452)", + "Kyōtoku (1452–1455)", + "Kōshō (1455–1457)", + "Chōroku (1457–1460)", + "Kanshō (1460–1466)", + "Bunshō (1466–1467)", + "Ōnin (1467–1469)", + "Bunmei (1469–1487)", + "Chōkyō (1487–1489)", + "Entoku (1489–1492)", + "Meiō (1492–1501)", + "Bunki (1501–1504)", + "Eishō (1504–1521)", + "Taiei (1521–1528)", + "Kyōroku (1528–1532)", + "Tenbun (1532–1555)", + "Kōji (1555–1558)", + "Eiroku (1558–1570)", + "Genki (1570–1573)", + "Tenshō (1573–1592)", + "Bunroku (1592–1596)", + "Keichō (1596–1615)", + "Genna (1615–1624)", + "Kan’ei (1624–1644)", + "Shōho (1644–1648)", + "Keian (1648–1652)", + "Jōō (1652–1655)", + "Meireki (1655–1658)", + "Manji (1658–1661)", + "Kanbun (1661–1673)", + "Enpō (1673–1681)", + "Tenna (1681–1684)", + "Jōkyō (1684–1688)", + "Genroku (1688–1704)", + "Hōei (1704–1711)", + "Shōtoku (1711–1716)", + "Kyōhō (1716–1736)", + "Genbun (1736–1741)", + "Kanpō (1741–1744)", + "Enkyō (1744–1748)", + "Kan’en (1748–1751)", + "Hōreki (1751–1764)", + "Meiwa (1764–1772)", + "An’ei (1772–1781)", + "Tenmei (1781–1789)", + "Kansei (1789–1801)", + "Kyōwa (1801–1804)", + "Bunka (1804–1818)", + "Bunsei (1818–1830)", + "Tenpō (1830–1844)", + "Kōka (1844–1848)", + "Kaei (1848–1854)", + "Ansei (1854–1860)", + "Man’en (1860–1861)", + "Bunkyū (1861–1864)", + "Genji (1864–1865)", + "Keiō (1865–1868)", + "Meiji", + "Taishō", + "Shōwa", + "Heisei" + ], + "long": [ + "Taika (645–650)", + "Hakuchi (650–671)", + "Hakuhō (672–686)", + "Shuchō (686–701)", + "Taihō (701–704)", + "Keiun (704–708)", + "Wadō (708–715)", + "Reiki (715–717)", + "Yōrō (717–724)", + "Jinki (724–729)", + "Tenpyō (729–749)", + "Tenpyō-kampō (749-749)", + "Tenpyō-shōhō (749-757)", + "Tenpyō-hōji (757-765)", + "Tenpyō-jingo (765-767)", + "Jingo-keiun (767-770)", + "Hōki (770–780)", + "Ten-ō (781-782)", + "Enryaku (782–806)", + "Daidō (806–810)", + "Kōnin (810–824)", + "Tenchō (824–834)", + "Jōwa (834–848)", + "Kajō (848–851)", + "Ninju (851–854)", + "Saikō (854–857)", + "Ten-an (857-859)", + "Jōgan (859–877)", + "Gangyō (877–885)", + "Ninna (885–889)", + "Kanpyō (889–898)", + "Shōtai (898–901)", + "Engi (901–923)", + "Enchō (923–931)", + "Jōhei (931–938)", + "Tengyō (938–947)", + "Tenryaku (947–957)", + "Tentoku (957–961)", + "Ōwa (961–964)", + "Kōhō (964–968)", + "Anna (968–970)", + "Tenroku (970–973)", + "Ten’en (973–976)", + "Jōgen (976–978)", + "Tengen (978–983)", + "Eikan (983–985)", + "Kanna (985–987)", + "Eien (987–989)", + "Eiso (989–990)", + "Shōryaku (990–995)", + "Chōtoku (995–999)", + "Chōhō (999–1004)", + "Kankō (1004–1012)", + "Chōwa (1012–1017)", + "Kannin (1017–1021)", + "Jian (1021–1024)", + "Manju (1024–1028)", + "Chōgen (1028–1037)", + "Chōryaku (1037–1040)", + "Chōkyū (1040–1044)", + "Kantoku (1044–1046)", + "Eishō (1046–1053)", + "Tengi (1053–1058)", + "Kōhei (1058–1065)", + "Jiryaku (1065–1069)", + "Enkyū (1069–1074)", + "Shōho (1074–1077)", + "Shōryaku (1077–1081)", + "Eihō (1081–1084)", + "Ōtoku (1084–1087)", + "Kanji (1087–1094)", + "Kahō (1094–1096)", + "Eichō (1096–1097)", + "Jōtoku (1097–1099)", + "Kōwa (1099–1104)", + "Chōji (1104–1106)", + "Kashō (1106–1108)", + "Tennin (1108–1110)", + "Ten-ei (1110-1113)", + "Eikyū (1113–1118)", + "Gen’ei (1118–1120)", + "Hōan (1120–1124)", + "Tenji (1124–1126)", + "Daiji (1126–1131)", + "Tenshō (1131–1132)", + "Chōshō (1132–1135)", + "Hōen (1135–1141)", + "Eiji (1141–1142)", + "Kōji (1142–1144)", + "Ten’yō (1144–1145)", + "Kyūan (1145–1151)", + "Ninpei (1151–1154)", + "Kyūju (1154–1156)", + "Hōgen (1156–1159)", + "Heiji (1159–1160)", + "Eiryaku (1160–1161)", + "Ōho (1161–1163)", + "Chōkan (1163–1165)", + "Eiman (1165–1166)", + "Nin’an (1166–1169)", + "Kaō (1169–1171)", + "Shōan (1171–1175)", + "Angen (1175–1177)", + "Jishō (1177–1181)", + "Yōwa (1181–1182)", + "Juei (1182–1184)", + "Genryaku (1184–1185)", + "Bunji (1185–1190)", + "Kenkyū (1190–1199)", + "Shōji (1199–1201)", + "Kennin (1201–1204)", + "Genkyū (1204–1206)", + "Ken’ei (1206–1207)", + "Jōgen (1207–1211)", + "Kenryaku (1211–1213)", + "Kenpō (1213–1219)", + "Jōkyū (1219–1222)", + "Jōō (1222–1224)", + "Gennin (1224–1225)", + "Karoku (1225–1227)", + "Antei (1227–1229)", + "Kanki (1229–1232)", + "Jōei (1232–1233)", + "Tenpuku (1233–1234)", + "Bunryaku (1234–1235)", + "Katei (1235–1238)", + "Ryakunin (1238–1239)", + "En’ō (1239–1240)", + "Ninji (1240–1243)", + "Kangen (1243–1247)", + "Hōji (1247–1249)", + "Kenchō (1249–1256)", + "Kōgen (1256–1257)", + "Shōka (1257–1259)", + "Shōgen (1259–1260)", + "Bun’ō (1260–1261)", + "Kōchō (1261–1264)", + "Bun’ei (1264–1275)", + "Kenji (1275–1278)", + "Kōan (1278–1288)", + "Shōō (1288–1293)", + "Einin (1293–1299)", + "Shōan (1299–1302)", + "Kengen (1302–1303)", + "Kagen (1303–1306)", + "Tokuji (1306–1308)", + "Enkyō (1308–1311)", + "Ōchō (1311–1312)", + "Shōwa (1312–1317)", + "Bunpō (1317–1319)", + "Genō (1319–1321)", + "Genkō (1321–1324)", + "Shōchū (1324–1326)", + "Karyaku (1326–1329)", + "Gentoku (1329–1331)", + "Genkō (1331–1334)", + "Kenmu (1334–1336)", + "Engen (1336–1340)", + "Kōkoku (1340–1346)", + "Shōhei (1346–1370)", + "Kentoku (1370–1372)", + "Bunchū (1372–1375)", + "Tenju (1375–1379)", + "Kōryaku (1379–1381)", + "Kōwa (1381–1384)", + "Genchū (1384–1392)", + "Meitoku (1384–1387)", + "Kakei (1387–1389)", + "Kōō (1389–1390)", + "Meitoku (1390–1394)", + "Ōei (1394–1428)", + "Shōchō (1428–1429)", + "Eikyō (1429–1441)", + "Kakitsu (1441–1444)", + "Bun’an (1444–1449)", + "Hōtoku (1449–1452)", + "Kyōtoku (1452–1455)", + "Kōshō (1455–1457)", + "Chōroku (1457–1460)", + "Kanshō (1460–1466)", + "Bunshō (1466–1467)", + "Ōnin (1467–1469)", + "Bunmei (1469–1487)", + "Chōkyō (1487–1489)", + "Entoku (1489–1492)", + "Meiō (1492–1501)", + "Bunki (1501–1504)", + "Eishō (1504–1521)", + "Taiei (1521–1528)", + "Kyōroku (1528–1532)", + "Tenbun (1532–1555)", + "Kōji (1555–1558)", + "Eiroku (1558–1570)", + "Genki (1570–1573)", + "Tenshō (1573–1592)", + "Bunroku (1592–1596)", + "Keichō (1596–1615)", + "Genna (1615–1624)", + "Kan’ei (1624–1644)", + "Shōho (1644–1648)", + "Keian (1648–1652)", + "Jōō (1652–1655)", + "Meireki (1655–1658)", + "Manji (1658–1661)", + "Kanbun (1661–1673)", + "Enpō (1673–1681)", + "Tenna (1681–1684)", + "Jōkyō (1684–1688)", + "Genroku (1688–1704)", + "Hōei (1704–1711)", + "Shōtoku (1711–1716)", + "Kyōhō (1716–1736)", + "Genbun (1736–1741)", + "Kanpō (1741–1744)", + "Enkyō (1744–1748)", + "Kan’en (1748–1751)", + "Hōreki (1751–1764)", + "Meiwa (1764–1772)", + "An’ei (1772–1781)", + "Tenmei (1781–1789)", + "Kansei (1789–1801)", + "Kyōwa (1801–1804)", + "Bunka (1804–1818)", + "Bunsei (1818–1830)", + "Tenpō (1830–1844)", + "Kōka (1844–1848)", + "Kaei (1848–1854)", + "Ansei (1854–1860)", + "Man’en (1860–1861)", + "Bunkyū (1861–1864)", + "Genji (1864–1865)", + "Keiō (1865–1868)", + "Meiji", + "Taishō", + "Shōwa", + "Heisei" + ] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "persian": { + "months": { + "narrow": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ], + "short": [ + "Farvardin", + "Ordibehesht", + "Khordad", + "Tir", + "Mordad", + "Shahrivar", + "Mehr", + "Aban", + "Azar", + "Dey", + "Bahman", + "Esfand" + ], + "long": [ + "Farvardin", + "Ordibehesht", + "Khordad", + "Tir", + "Mordad", + "Shahrivar", + "Mehr", + "Aban", + "Azar", + "Dey", + "Bahman", + "Esfand" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { "narrow": ["AP"], "short": ["AP"], "long": ["AP"] }, + "dayPeriods": { "am": "AM", "pm": "PM" } + }, + "roc": { + "months": { + "narrow": [ + "J", + "F", + "M", + "A", + "M", + "J", + "J", + "A", + "S", + "O", + "N", + "D" + ], + "short": [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ], + "long": [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ] + }, + "days": { + "narrow": ["S", "M", "T", "W", "T", "F", "S"], + "short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + "long": [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ] + }, + "eras": { + "narrow": ["Before R.O.C.", "Minguo"], + "short": ["Before R.O.C.", "Minguo"], + "long": ["Before R.O.C.", "Minguo"] + }, + "dayPeriods": { "am": "AM", "pm": "PM" } + } + } + }, + "number": { + "nu": ["latn"], + "patterns": { + "decimal": { + "positivePattern": "{number}", + "negativePattern": "{minusSign}{number}" + }, + "currency": { + "positivePattern": "{currency}{number}", + "negativePattern": "{minusSign}{currency}{number}" + }, + "percent": { + "positivePattern": "{number}{percentSign}", + "negativePattern": "{minusSign}{number}{percentSign}" + } + }, + "symbols": { + "latn": { + "decimal": ".", + "group": ",", + "nan": "NaN", + "plusSign": "+", + "minusSign": "-", + "percentSign": "%", + "infinity": "∞" + } + }, + "currencies": { + "AUD": "A$", + "BRL": "R$", + "CAD": "CA$", + "CNY": "CN¥", + "EUR": "€", + "GBP": "£", + "HKD": "HK$", + "ILS": "₪", + "INR": "₹", + "JPY": "¥", + "KRW": "₩", + "MXN": "MX$", + "NZD": "NZ$", + "TWD": "NT$", + "USD": "$", + "VND": "₫", + "XAF": "FCFA", + "XCD": "EC$", + "XOF": "CFA", + "XPF": "CFPF" + } + } +} diff --git a/client/src/main.ts b/client/src/main.ts new file mode 100644 index 0000000..a7ceaff --- /dev/null +++ b/client/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' + +import { AppModule } from './app/' + +platformBrowserDynamic().bootstrapModule(AppModule) diff --git a/client/src/polyfills.ts b/client/src/polyfills.ts new file mode 100644 index 0000000..f963162 --- /dev/null +++ b/client/src/polyfills.ts @@ -0,0 +1,79 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +import 'core-js/es6/symbol' +import 'core-js/es6/object' +import 'core-js/es6/function' +import 'core-js/es6/parse-int' +import 'core-js/es6/parse-float' +import 'core-js/es6/number' +import 'core-js/es6/math' +import 'core-js/es6/string' +import 'core-js/es6/date' +import 'core-js/es6/array' +import 'core-js/es6/regexp' +import 'core-js/es6/map' +import 'core-js/es6/set' +import 'core-js/es6/reflect' + +import 'core-js/es7/reflect' + +import 'handsontable' + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js' // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +import './formatToParts.polyfill.js' +import buffer from 'buffer' +;(window as any).global = window +;(window as any).global.Buffer = (window as any).global.Buffer || buffer.Buffer +;(window as any).process = { + version: '' +} diff --git a/client/src/styles.scss b/client/src/styles.scss new file mode 100644 index 0000000..1a208ea --- /dev/null +++ b/client/src/styles.scss @@ -0,0 +1,1079 @@ +/* You can add global styles to this file, and also import other style files */ +@import '~handsontable/dist/handsontable.full.css'; + +@import "~@clr/ui/clr-ui.min.css"; +@import "~@clr/icons/clr-icons.min.css"; + +@font-face{ + font-family: text-security-disc; + src: url("https://raw.githubusercontent.com/noppa/text-security/master/dist/text-security-disc.woff"); +} + +body, html { + font-weight: 400!important; + + padding: 0; + margin: 0; + + &.should-login { + clr-modal { + display: none !important; + } + } +} + +button { + &:focus { + outline: none; + } +} + +// Custom loading spinner +.slider{ + position: absolute; + width: 320px; + margin-left: 75px; + margin-top: 70px; + height: 5px; + overflow-x: hidden; +} + +.line{ + position:absolute; + opacity: 0.4; + background:#73D544; + width:150%; + height:5px; +} + +.subline{ + position:absolute; + background:#73D544; + height:5px; +} +.inc{ + animation: increase 2s infinite; +} +.dec{ + animation: decrease 2s 0.5s infinite; +} + +@keyframes increase { + from { left: -5%; width: 5%; } + to { left: 130%; width: 100%;} +} +@keyframes decrease { + from { left: -80%; width: 80%; } + to { left: 110%; width: 10%;} +} +// Custo loading spinner end + +// Should be here until we figure out why it was there in the first place +// .modal { +// z-index: 2020; +// } + +.app-loading { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background: #314351; + flex-direction: column; + z-index: 2000; + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; +} + +.select-none { + user-select: none; +} + +.h-auto { + height: auto; +} + +.h-unset-i { + height: unset !important; +} + +.min-h-50vh { + min-height: 50vh; +} + +.h-24vh { + height: 25vh; +} + +.h-25vh { + height: 25vh; +} + +.h-70vh { + height: 70vh; +} + +.h-80vh { + height: 80vh; +} + +.h-100 { + height: 100%; +} + +.w-50vw { + width: 50vw; +} + +.w-100 { + width: 100%; +} + +.w-40 { + width: 40%; +} + +.min-w-0 { + min-width: 0px; +} + +.mx-5 { + margin: 0 5px; +} + +.my-5 { + margin: 5px 0; +} + +.my-15 { + margin: 15px 0; +} + +.my-10-mx-auto { + margin: 10px auto; +} + +.m-0 { + margin: 0 !important; +} + +.m-10 { + margin: 10px; +} + +.mt-0 { + margin-top: 0; +} + +.mt-0-i { + margin-top: 0 !important; +} + +.mt-3-negative { + margin-top: -3px; +} + +.mt-5 { + margin-top: 5px; +} + +.mt-5-i { + margin-top: 5px !important; +} + +.mt-2 { + margin-top: 2px; +} + +.mt-2-i { + margin-top: 2px !important; +} + +.mt-10 { + margin-top: 10px; +} + +.mt-20 { + margin-top: 20px; +} + +.mt-15 { + margin-top: 15px; +} + +.mt-17 { + margin-top: 17px; +} + +.mt-20 { + margin-top: 20px; +} + +.ml-0 { + margin-left: 0; +} + +.ml-3 { + margin-left: 3px; +} + +.ml-5 { + margin-left: 5px; +} + +.ml-10 { + margin-left: 10px; +} + +.ml-15 { + margin-left: 15px; +} + +.ml-20 { + margin-left: 20px; +} + +.ml-20-i { + margin-left: 20px !important; +} + +.mr-0 { + margin-right: 0; +} + +.mr-5 { + margin-right: 5px; +} + +.mr-10 { + margin-right: 10px; +} + +.mr-12 { + margin-right: 12px; +} + +.mr-20 { + margin-right: 20px; +} + +.mb-0 { + margin-bottom: 0; +} + +.mb-0i { + margin-bottom: 0 !important; +} + +.mb-5 { + margin-bottom: 5px; +} + +.mb-10 { + margin-bottom: 10px; +} + +.mb-20 { + margin-bottom: 20px; +} + +.mb-30 { + margin-bottom: 30px; +} + +.p-0 { + padding: 0; +} + +.p-10 { + padding: 10px; +} + +.pb-0 { + padding-bottom: 0; +} + +.pb-10 { + padding-bottom: 10px; +} + +.py-5 { + padding: 5px 0px; +} + +.py-10 { + padding: 10px 0px; +} + +.background-transparent { + background: transparent; +} + +.background-transparent-i { + background: transparent !important; +} + +.color-gray { + color: #5a5a5a; +} + +.color-dark-gray { + color: #495967 +} + +.color-darker-gray{ + color: #314351 +} + +.color-white { + color: white; +} + +.color-white-i { + color: white !important +} + +.color-green { + color: #4b9e4b; +} + +.color-dc-green { + color: #81b440 +} + +.color-red { + color: #e45454 +} + +.color-orange { + color: #E67E22; +} + +.color-blue { + color: #3f8cc3; +} + +.color-yellow { + color: #f1c40f +} + +.cursor-pointer { + cursor: pointer; +} + +.cursor-defualt { + cursor: default; +} + +.cursor-default-i { + cursor: default !important; +} + +.background-transparent { + background-color: transparent; +} + +.pointer-events-none { + pointer-events: none; +} + +.text-center { + text-align: center; +} + +.font-size-15 { + font-size: 15px; +} + +.font-size-18 { + font-size: 18px; +} + +.font-bold { + font-weight: bold; +} + +.font-bold-i { + font-weight: bold !important; +} + +.font-weight-300 { + font-weight: 300; +} + +.font-weight-700 { + font-weight: 700; +} + +.word-break { + word-break: break-word; +} + +.word-break-all { + word-break: break-all; +} + +.position-relative { + position: relative; +} + +.position-absolute { + position: absolute; +} + +.d-none { + display: none; +} + +.d-block { + display: block; +} + +.d-inline-block { + display: inline-block; +} + +.d-flex { + display: flex; +} + +.d-contents { + display: contents; +} + +.flex-unset { + flex: unset; +} + +.align-self-end { + align-self: flex-end; +} + +.align-self-start { + align-self: flex-start; +} + +.align-items-center { + align-items: center; +} + +.justify-content-center { + justify-content: center; +} + +.justify-content-center-i { + justify-content: center !important; +} + +.justify-content-start { + justify-content: flex-start; +} + +.justify-content-end { + justify-content: flex-end; +} + +.justify-content-between { + justify-content: space-between; +} + +.justify-content-around { + justify-content: space-around; +} + +.flex-column { + flex-direction: column; +} + +.clr-gap-5 { + gap: 5px; +} + +.clr-gap-0 { + gap: 0; +} + +.overflow-auto { + overflow: auto; +} + +.z-index-highest { + z-index: 10000000 +} + +.vertical-align-middle { + vertical-align: middle; +} + +.icon-dc-fill { + fill: #81b440; +} + +.datagrid-custom-footer { + .datagrid-outer-wrapper { + width: 100%; + } +} + +.progresStatic { + margin-top:-6px!important; + position: absolute!important; + z-index: 10000!important; +} + +.progress, .progress-static { + background-color: #f5f6fe; + border-radius: 0; + font-size: inherit; + height: 6px; + margin: 0; + max-height: .583333rem; + min-height: .166667rem; + overflow: hidden; + display: block; + width: calc(100% - 63px); +} + +.progress.loop:after { + -webkit-animation: clr-progress-looper 1.5s ease-in-out infinite; + animation: clr-progress-looper 1.5s ease-in-out infinite; + content: " "; + top: .166667rem; + bottom: 0; + left: 0; + position: absolute; + display: block; + background-color: #60b515; + width: 75%; +} + +// Fix for clarity bug, should be addressed when clarity is updated +.badge-warning { + color: white !important; +} + +.content-container .content-area .card-header h3 { + margin-top: 10px; +} + +.modal-header .close clr-icon { + display: none; +} +.show-close .modal-header .close clr-icon { + display: inline-block; + position: relative; + top: -18px; + right: -10px; +} + +.alert-app-level.alert-danger { + background: #D94B2E; + color: #fff; + border: none; +} + +.card-header { + font-weight: 300; +} + +.select select:focus { + border-bottom: 1px solid #495967; + background: linear-gradient(180deg,transparent 95%,#495a67 0) no-repeat; +} + +.clr-treenode-children { + margin-left: 0.2rem !important; +} + +.table-active { + background: #d8e3e9 !important; + color: black !important; +} + +.table-active:focus { + background: #d8e3e9; +} + +clr-select-container .clr-control-container, clr-select-container .clr-control-container .clr-select-wrapper, clr-select-container select { + width: 100%; +} + +tbody { + font-weight: 400; +} + +h3, h4 { + color: #585858; + font-weight: 400; + letter-spacing: normal; + line-height: 1rem; + margin-top: 1rem; + margin-bottom: 0; + /* text-transform: uppercase; */ +} + +h1, h2 { + color: #585858; + font-weight: 400; + /* font-family: Metropolis,Avenir Next,Helvetica Neue,Arial,sans-serif; */ + letter-spacing: normal; + line-height: 2rem; + margin-top: 1rem; + margin-bottom: 0; + /* text-transform: uppercase; */ +} + +clr-icon.is-info { + fill: #80b441; +} + +.datagrid-host, .datagrid-overlay-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-box!important; + -webkit-box-direction: normal; +} + +.btn.btn-danger, .btn.btn-warning { + border-color: #ef4f2e; + background-color: #D94B2E; + color: #fff; +} + +.d-none { + display: none !important; +} + +.d-block { + display: block !important; +} + +.clr-flex-1 { + flex: 1; +} + +.clr-flex-column { + flex-direction: column; +} + +.clr-flex-row { + flex-direction: row; +} + +.border-0 { + border: 0; +} + +.box-shadow-none { + box-shadow: none; +} + +.box-shadow-none-i { + box-shadow: none !important; +} + +.handsontable .htAutocompleteArrow { + color: #828282; +} + +.handsontable.listbox { + padding: 5px 0px 5px 5px; + box-shadow: 0px 4px 20px 0px #00000070; +} + +.handsontable td.htInvalid { + background: #e62700ad!important; + border: 1px solid red !important; + color: #ffffff!important; +} +.margin-top-20{ + margin-top: 20px; +} +.hidden { + display: none !important; +} +.unvisible { + visibility: hidden; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-sm-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } + .clr-flex-sm-column { + flex-direction: column; + } + .clr-flex-sm-row { + flex-direction: row; + } + .clr-gap-sm-5 { + gap: 5px; + } + .clr-gap-sm-0 { + gap: 0; + } +} + +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-md-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } + .clr-flex-md-column { + flex-direction: column; + } + .clr-flex-md-row { + flex-direction: row; + } + .clr-gap-md-5 { + gap: 5px; + } + .clr-gap-md-0 { + gap: 0; + } +} + +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-lg-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } + .clr-flex-lg-column { + flex-direction: column; + } + .clr-flex-lg-row { + flex-direction: row; + } + .clr-gap-lg-5 { + gap: 5px; + } + .clr-gap-lg-0 { + gap: 0; + } +} + +.datagrid-body { + padding-bottom: 2rem!important; +} + +.abortMsg { + white-space: pre-wrap; + font-family: monospace; +} + + +#graph svg { + height: 100%; + width: 100%; +} + +.no-table-selected { + display:flex; + justify-content:center; + flex-direction:column; + align-items: center; + position: absolute; + background: white; + z-index: 10; + width: 100%; + height: 100%; + top: 0; +} + +.copyRight { + background:#495967!important; + color: #fff; + display:flex !important; + justify-content:center; + align-items: center; + padding: 5px 0px 4px 0px; + z-index: 100; +} + + +.nav-tree > clr-tree-node.clr-expanded { + display: inline-block !important; +} + +clr-tree-node { + overflow-y: visible; + + &:focus { + outline: none !important; + } + + .clr-treenode-caret { + width: auto !important; + height: auto !important; + } + + .clr-treenode-spinner-container { + padding: 0px 8px 0px 8px; + width: auto; + height: auto; + display: flex; + align-items: center; + } + + .clr-tree-node-content-container { + &:focus { + outline: none !important; + } + } +} + +.clr-treenode-content { + p { + white-space: nowrap; + } +} + +.search-node { + margin-bottom: 5px; +} + +.tree-search-wrapper { + position: relative; + display: flex; + align-items: center; + + clr-input-container { + margin: 0; + } + + clr-icon { + position: absolute; + right: 0; + bottom: 0; + margin: 0; + margin-top: 5px; + background: white; + cursor: pointer; + } +} + +.clr-tree-node { + overflow: visible !important; +} + +.content-container { + width: 100%; +} + +//Firefox Fixes +@-moz-document url-prefix() { + .wtHolder { + width: 100% !important; + } +} + +// IE Fixes +input::-ms-clear { + display: none; +} + +@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + clr-tree-node.clr-expanded { + padding-bottom: 20px; + min-height: auto; + } + + .clr-tree-node { + min-height: 24px; + } + + .clr-treenode-children { + overflow: hidden !important; + } + + .clr-treenode-content .clr-icon, .clr-treenode-content clr-icon { + min-width: 16px; + min-height: 16px; + } + + .tree-search-wrapper clr-icon { + bottom: 2px; + } + + .content-container { + height: 100%; + } + + .content-area { + & > .card { + margin-bottom: 20px; + } + } + + .record-edit-modal textarea { + min-height: 42px; + } +} + +.border-bottom-divider { + border-bottom: 1px solid #d3d3d3; +} + +.loadingSpinner { + height:70vh; + flex: 1; + display:flex; + justify-content: center; + flex-direction:column; + align-items:center; +} + +.disable-password-manager { + -webkit-text-security: disc; + -moz-text-security: disc; + text-security: disc; + font-family: text-security-disc; +} + +.relative { + position: relative; +} + +hr.light { + border: 0; + border-bottom: 1px solid #dedede; +} + +//Rules to fix CSP issues with clarity elements (they use base64 which is blocked) +.spinner { + background: url('./images/spinner.svg') !important; +} + +.clr-select-wrapper::after { + background: url('./images/caret.svg') !important; +} + +.table-search-wrapper { + background-color: #fff; + + .input-wrapper { + position: relative; + min-width: 170px; + + clr-icon, .spinner { + position: absolute; + right: 19px; + top: 0px; + } + + clr-icon { + cursor: pointer; + background: white; + } + } + + clr-input-container { + margin-top: -5px; + margin-right: 0; + + label { + display: none; + } + } + + clr-checkbox-container { + margin-top: 0; + } + + input { + border-bottom: none; + border: 1px solid #999; + } + + /* Chrome, Safari, Edge, Opera */ + input::-webkit-outer-spin-button, + input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + input[type=number] { + -moz-appearance: textfield; + } +} + +.dc-locked-control { + opacity: 0.4; + cursor: not-allowed !important; +} + +.link-it { + cursor: pointer; + text-decoration: underline; +} \ No newline at end of file diff --git a/client/src/types/crypto-js/index.d.ts b/client/src/types/crypto-js/index.d.ts new file mode 100644 index 0000000..1a3b564 --- /dev/null +++ b/client/src/types/crypto-js/index.d.ts @@ -0,0 +1,2 @@ +declare module 'crypto-js' +declare module 'crypto-js/md5' diff --git a/client/src/types/save-svg-as-png/index.d.ts b/client/src/types/save-svg-as-png/index.d.ts new file mode 100644 index 0000000..cc09c41 --- /dev/null +++ b/client/src/types/save-svg-as-png/index.d.ts @@ -0,0 +1 @@ +declare module 'save-svg-as-png' diff --git a/client/src/typings.d.ts b/client/src/typings.d.ts new file mode 100644 index 0000000..e69de29 diff --git a/client/src/version.ts b/client/src/version.ts new file mode 100644 index 0000000..8982688 --- /dev/null +++ b/client/src/version.ts @@ -0,0 +1,43 @@ +const { readFileSync } = require('fs') +const { gitDescribeSync } = require('git-describe') +const { resolve, relative } = require('path') +const { writeFileSync } = require('fs-extra') +const momentObj = require('moment') + +const gitInfo = gitDescribeSync({ + dirtyMark: false, + dirtySemver: false +}) + +//Reading the installed adapter version +const adapterPackagePath = resolve( + __dirname, + '..', + 'node_modules', + '@sasjs', + 'adapter', + 'package.json' +) +const adapterPackageFile = readFileSync(adapterPackagePath) +const adapterPackageFileJson = JSON.parse(adapterPackageFile) + +gitInfo.timestamp = momentObj().format('x') +gitInfo.adapterVersion = adapterPackageFileJson.version + +const file = resolve(__dirname, '..', 'src', 'environments', 'version.ts') +writeFileSync( + file, + `// IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT OR CHECKIN! +/* tslint:disable */ +export const VERSION = ${JSON.stringify(gitInfo, null, 4)}; +/* tslint:enable */ +`, + { encoding: 'utf-8' } +) + +console.log( + `Wrote version info ${gitInfo.raw} to ${relative( + resolve(__dirname, '..'), + file + )}` +) diff --git a/client/tsconfig.app.json b/client/tsconfig.app.json new file mode 100644 index 0000000..acf688d --- /dev/null +++ b/client/tsconfig.app.json @@ -0,0 +1,21 @@ +/* + This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience. + It is not intended to be used to perform a compilation. + + To learn more about this file see: https://angular.io/config/solution-tsconfig. +*/ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./app", + "types": [] + }, + "files": [ + "src/polyfills.ts", + "src/main.ts", + "src/app/app.d.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} \ No newline at end of file diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 0000000..b10d456 --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,50 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "", + "outDir": "dist", + "downlevelIteration": true, + "declaration": false, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "lib": [ + "ES2022", + "dom" + ], + "module": "ES2022", + "importHelpers": true, + "moduleResolution": "node", + "sourceMap": true, + "resolveJsonModule": true, + "target": "ES2022", + "paths": { + "crypto": [ + "./node_modules/crypto-browserify" + ], + "stream": [ + "./node_modules/stream-browserify" + ], + "assert": [ + "./node_modules/assert" + ], + "http": [ + "./node_modules/stream-http" + ], + "https": [ + "./node_modules/https-browserify" + ], + "os": [ + "./node_modules/os-browserify" + ] + }, + "useDefineForClassFields": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + } +} diff --git a/client/tsconfig.spec.json b/client/tsconfig.spec.json new file mode 100644 index 0000000..b841681 --- /dev/null +++ b/client/tsconfig.spec.json @@ -0,0 +1,17 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/client/typedoc.json b/client/typedoc.json new file mode 100644 index 0000000..be1879f --- /dev/null +++ b/client/typedoc.json @@ -0,0 +1,12 @@ +{ + "out": "../dc-devdocs", + "tsconfig": "./tsconfig.app.json", + "entryPointStrategy": "expand", + "entryPoints": [ + "./src" + ], + "exclude": "**/*+(index|.spec|.e2e).ts", + "externalPattern": "**/node_modules/**", + "excludeExternals": true, + "excludePrivate": true + } \ No newline at end of file diff --git a/licence-non-commercial-datacontroller.md b/licence-non-commercial-datacontroller.md new file mode 100644 index 0000000..089457d --- /dev/null +++ b/licence-non-commercial-datacontroller.md @@ -0,0 +1,52 @@ + +# Data Controller +_FREE FOR NON-COMMERCIAL LICENSE_ + +_VERSION 1.0 OF July 11th, 2022_ + +## 1. Copyright notice +Copyright (c) Bowe IO Ltd, a UK Limited Company headquarted in 29 Oldfield Rd, Cumbria, registered by companies house under number 08777171, VAT number: 203914240 + +## 2. License terms and conditions +### 2.1. Grant of license. +Subject to the terms and conditions of this license, the licensor as indicated in the copyright notice above (“Licensor”) hereby grants you a perpetual, irrevocable except in the event of any breach of this license, worldwide, non-exclusive, no-charge, royalty-free, and limited license to: + +(i) use Data Controller software (“Software”) and prepare original works of authorship based on or derived from the Software (“Derivative Works”); and + +(ii) reproduce and distribute copies of the Software and Derivative Works (collectively, +“Deliverables”). + +### 2.2. Restrictions. +Neither this license nor the Deliverables may be so used as to result in: + +(i) your direct or indirect commercial advantage or monetary gains (“Commercial Purposes”) except only if such use is for the sole purpose of testing the suitability, performance, and usefulness of the Deliverables for your business needs; or + +(ii) commercial, non-commercial, for profit or not for profit licensing, transfer or distribution of a Derivative Work that is competitive with the Software, contains the same or substantially similar functionality as the Software, or could likely result in third parties utilizing the Derivative Work in lieu of or in place of the Software (“Competitive Purposes”); or + +(iii) both Commercial Purposes and Competitive Purposes. + +### 2.3. Redistribution. +You may reproduce and distribute copies of the Deliverables in any medium, with or without modifications, and in source or object form, if you meet the following conditions: + +(i) you must give any other recipients of the Deliverables a copy of this license; and + +(ii) you must cause any modified files to carry prominent notices stating that you changed the files; +and + +(iii) you must retain, in the source form of any Derivative Works that you distribute, all copyright, trademark, and attribution notices from the source form of the Software, excluding those notices that do not pertain to any part of the Derivative Works; and + +(iv) if the Software includes a “notice” text file as part of its distribution, then any Derivative Works that you distribute must include a readable copy of the attribution notices contained within such notice file, excluding those notices that do not pertain to any part of the Derivative Works. The contents of the notice file are for informational purposes only and do not modify this license. + +## 3. Miscellaneous +### 3.1. License key. +To use the Deliverables, you shall apply a license key defined in the relevant Software documentation as from time to time amended. + +### 3.2. Trademarks. +This license does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Deliverables and reproducing the content of the notice file. + +## 4. Disclaimer and limitation +### 4.1. Disclaimer of warranty. +UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, LICENSOR PROVIDES THE SOFTWARE ON AN “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING THE DELIVERABLES AND ASSUME ANY RISKS ASSOCIATED WITH YOUR EXERCISE OF PERMISSIONS UNDER THIS LICENSE. + +### 4.2. Limitation of liability. +IN NO EVENT AND UNDER NO LEGAL THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, UNLESS REQUIRED BY APPLICABLE LAW (SUCH AS DELIBERATE AND GROSSLY NEGLIGENT ACTS) OR AGREED TO IN WRITING, SHALL LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING AS A RESULT OF THIS LICENSE OR OUT OF THE USE OR INABILITY TO USE THE DELIVERABLES (INCLUDING BUT NOT LIMITED TO DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a2457c7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,16453 @@ +{ + "name": "dcfrontend", + "version": "6.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "dcfrontend", + "version": "6.0.0", + "hasInstallScript": true, + "devDependencies": { + "@saithodev/semantic-release-gitea": "^2.1.0", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^10.0.1", + "@semantic-release/git": "^10.0.1", + "@semantic-release/release-notes-generator": "^11.0.4", + "commit-and-tag-version": "^11.2.2", + "prettier": "3.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", + "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", + "dev": true, + "peer": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-7.1.2.tgz", + "integrity": "sha512-Jx8KuKqEAVRsK6fMzZKv3h6UH9/NRDHsDRtUAROqqmZlCptM///Uef7A1ViZ/cbDplekz7VbDWdFLAZ/mpuDww==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/tsconfig": "^2.0.0", + "@octokit/types": "^9.3.2" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=4" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-5.0.5.tgz", + "integrity": "sha512-sB1RWMhSrre02Atv95K6bhESlJ/sPdZkK/wE/w1IdSCe0yM6FxSjksLa6T7aAvxvxlLKzQEC4KIiqpqyov1Tbg==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-retry/node_modules/@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/plugin-retry/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-6.1.0.tgz", + "integrity": "sha512-JqMbTiPC0sUSTsLQsdq3JVx1mx8UtTo5mwR80YqPXE93+XhevvSyOR1rO2Z+NbO/r0TK4hqFJSSi/9oIZBxZTg==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^4.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/tsconfig": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-2.0.0.tgz", + "integrity": "sha512-tWnrai3quGt8+gRN2edzo9fmraWekeryXPeXDomMw2oFSpu/lH3VSWGn/q4V+rwjTRMeeXk/ci623/01Zet4VQ==", + "dev": true, + "peer": true + }, + "node_modules/@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "dev": true, + "peer": true, + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@saithodev/semantic-release-gitea": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-gitea/-/semantic-release-gitea-2.1.0.tgz", + "integrity": "sha512-jvr5U6/ZVADgwJ7yosymrwFF4AO+bhYMaiFNLoo/RUOJQNalrwziOmCtWH3YC/ouEd1TiPXDhfBOuXSgXvgANg==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "form-data": "^3.0.0", + "fs-extra": "^8.0.0", + "globby": "^10.0.0", + "got": "^10.0.1", + "lodash": "^4.17.21", + "querystring": "^0.2.0", + "url-join": "^4.0.0" + }, + "engines": { + "node": "^10 || ^11 || ^12 || >=14" + } + }, + "node_modules/@saithodev/semantic-release-gitea/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/@saithodev/semantic-release-gitea/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/@saithodev/semantic-release-gitea/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@saithodev/semantic-release-gitea/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@saithodev/semantic-release-gitea/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@saithodev/semantic-release-gitea/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/@saithodev/semantic-release-gitea/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" + } + }, + "node_modules/@semantic-release/commit-analyzer": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-10.0.1.tgz", + "integrity": "sha512-9ejHzTAijYs9z246sY/dKBatmOPcd0GQ7lH4MgLCkv1q4GCiDZRkjHJkaQZXZVaK7mJybS+sH3Ng6G8i3pYMGQ==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "debug": "^4.0.0", + "import-from": "^4.0.0", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" + } + }, + "node_modules/@semantic-release/git/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@semantic-release/git/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/@semantic-release/git/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/git/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/@semantic-release/git/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/git/node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@semantic-release/github": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.0.3.tgz", + "integrity": "sha512-X6gq4USKVlCxPwIIyXb99jU7gwVWlnsKOevs+OyABRdoqc+OIRITbFmrrYU3eE1vGMGk+Qu/GAoLUQQQwC3YOA==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^7.0.0", + "@octokit/plugin-retry": "^5.0.0", + "@octokit/plugin-throttling": "^6.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^4.0.1", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^13.1.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^3.0.0", + "p-filter": "^3.0.0", + "url-join": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/github/node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/github/node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/github/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-10.0.4.tgz", + "integrity": "sha512-6R3timIQ7VoL2QWRkc9DG8v74RQtRp7UOe/2KbNaqwJ815qOibAv65bH3RtTEhs4axEaHoZf7HDgFs5opaZ9Jw==", + "dev": true, + "peer": true, + "dependencies": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^4.0.1", + "execa": "^7.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^9.5.0", + "rc": "^1.2.8", + "read-pkg": "^8.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/npm/node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-11.0.4.tgz", + "integrity": "sha512-j0Znnwq9IdWTCGzqSlkLv4MpALTsVDZxcVESzJCNN8pK2BYQlYaKsdZ1Ea/+7RlppI3vjhEi33ZKmjSGY1FLKw==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^6.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from": "^4.0.0", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^10.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg-up": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", + "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true, + "peer": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true, + "peer": true + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "peer": true + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "peer": 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/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dev": true, + "dependencies": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "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-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "peer": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "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/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-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "peer": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "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/commit-and-tag-version": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/commit-and-tag-version/-/commit-and-tag-version-11.2.2.tgz", + "integrity": "sha512-pqtTvRZFSqsGevhdcCvZVhzoSC56OeWZxhVzVDOWu97FfMJR4xUmpirRZcGqmTsDWCTxnm+UVl9/slN7OGO82A==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.25", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "6.1.0", + "conventional-recommended-bump": "7.0.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "git-semver-tags": "^5.0.0", + "semver": "^7.1.1", + "yargs": "^17.0.0" + }, + "bin": { + "commit-and-tag-version": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-changelog/node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-recommended-bump": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", + "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", + "dev": true, + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^3.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "git-raw-commits": "^3.0.0", + "git-semver-tags": "^5.0.0", + "meow": "^8.1.2" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/conventional-recommended-bump/node_modules/conventional-changelog-preset-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", + "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/git-raw-commits": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", + "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/git-semver-tags": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.0.tgz", + "integrity": "sha512-fZ+tmZ1O5aXW/T5nLzZLbxWAHdQTLLXalOECMNAmhoEQSfqZjtaeMjpsXH4C5qVhrICTkVQeQFujB1lKzIHljA==", + "dev": true, + "dependencies": { + "meow": "^8.1.2", + "semver": "^6.3.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/commit-and-tag-version/node_modules/git-semver-tags/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/commit-and-tag-version/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/commit-and-tag-version/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "node_modules/conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/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/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cosmiconfig/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dev": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "peer": true + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/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/dotgitignore/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/dotgitignore/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/dotgitignore/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/dotgitignore/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": 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/duplexer2/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, + "peer": true + }, + "node_modules/duplexer2/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, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, + "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/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/env-ci": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-9.1.1.tgz", + "integrity": "sha512-Im2yEWeF4b2RAMAaWvGioXk6m0UNaIjD8hj28j2ij5ldnIFrDQT0+pzDvpbRkcjurhXhf/AsBKv8P2rtmGi9Aw==", + "dev": true, + "peer": true, + "dependencies": { + "execa": "^7.0.0", + "java-properties": "^1.0.2" + }, + "engines": { + "node": "^16.14 || >=18" + } + }, + "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/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.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, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-glob": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "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/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/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "peer": true, + "dependencies": { + "semver-regex": "^4.0.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "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/from2/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/from2/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/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/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/get-pkg-repo/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/get-pkg-repo/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/get-pkg-repo/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/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", + "dev": true, + "peer": true, + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + } + }, + "node_modules/git-log-parser/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": 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/git-log-parser/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, + "peer": true + }, + "node_modules/git-log-parser/node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "dev": true, + "peer": true, + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/git-log-parser/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, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/git-log-parser/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, + "peer": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "dev": true, + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-semver-tags/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/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "peer": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got/node_modules/type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dev": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", + "dev": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "dev": true, + "engines": { + "node": ">=12.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "dev": true, + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": ">=10.13" + } + }, + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "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": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "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": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "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/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "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/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true, + "peer": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true, + "peer": true + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "peer": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "peer": true + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true, + "peer": true + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.1.tgz", + "integrity": "sha512-bTmmGdEINWmOMDjnPWDxGPQ4qkDLeYorpYbEtFOXzOruTwUE671q4Guiuchn4N8h/v6NGd7916kXsm3Iz4iUSg==", + "dev": true, + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-terminal": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.2.0.tgz", + "integrity": "sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.2.0", + "cli-table3": "^0.6.3", + "node-emoji": "^1.11.0", + "supports-hyperlinks": "^2.3.0" + }, + "engines": { + "node": ">=14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "marked": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/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/meow/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/meow/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/meow/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/meow/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/meow/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/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/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/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/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/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "peer": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true, + "peer": true + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dev": true, + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-9.8.0.tgz", + "integrity": "sha512-AXeiBAdfM5K2jvBwA7EGLKeYyt0VnhmJRnlq4k2+M0Ao9v7yKJBqF8xFPzQL8kAybzwlfpTPCZwM4uTIszb3xA==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/run-script", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "sigstore", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "peer": true, + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^6.3.0", + "@npmcli/config": "^6.2.1", + "@npmcli/map-workspaces": "^3.0.4", + "@npmcli/package-json": "^4.0.0", + "@npmcli/run-script": "^6.0.2", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^17.1.3", + "chalk": "^5.2.0", + "ci-info": "^3.8.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.3", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.2", + "glob": "^10.2.7", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^6.1.1", + "ini": "^4.1.1", + "init-package-json": "^5.0.0", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^3.0.0", + "libnpmaccess": "^7.0.2", + "libnpmdiff": "^5.0.19", + "libnpmexec": "^6.0.2", + "libnpmfund": "^4.0.19", + "libnpmhook": "^9.0.3", + "libnpmorg": "^5.0.4", + "libnpmpack": "^5.0.19", + "libnpmpublish": "^7.5.0", + "libnpmsearch": "^6.0.2", + "libnpmteam": "^5.0.3", + "libnpmversion": "^4.0.2", + "make-fetch-happen": "^11.1.1", + "minimatch": "^9.0.0", + "minipass": "^5.0.0", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^9.4.0", + "nopt": "^7.2.0", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.1.1", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-profile": "^7.0.1", + "npm-registry-fetch": "^14.0.5", + "npm-user-validate": "^2.0.0", + "npmlog": "^7.0.1", + "p-map": "^4.0.0", + "pacote": "^15.2.0", + "parse-conflict-json": "^3.0.1", + "proc-log": "^3.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^2.1.0", + "semver": "^7.5.2", + "sigstore": "^1.7.0", + "ssri": "^10.0.4", + "supports-color": "^9.3.1", + "tar": "^6.1.15", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.0", + "which": "^3.0.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "6.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.0", + "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^5.0.0", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^4.0.0", + "@npmcli/query": "^3.0.0", + "@npmcli/run-script": "^6.0.0", + "bin-links": "^4.0.1", + "cacache": "^17.0.4", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^6.1.1", + "json-parse-even-better-errors": "^3.0.0", + "json-stringify-nice": "^1.1.4", + "minimatch": "^9.0.0", + "nopt": "^7.0.0", + "npm-install-checks": "^6.0.0", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-registry-fetch": "^14.0.3", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "parse-conflict-json": "^3.0.0", + "proc-log": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.2", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.1", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^3.8.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "ansi-styles": "^4.3.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cacache": "^17.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^15.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/git": "^4.1.0", + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.1", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tootallnate/once": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abort-controller": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/npm/node_modules/agentkeepalive": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^4.1.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/bin-links": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/buffer": { + "version": "6.0.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/npm/node_modules/builtins": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "17.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "3.8.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "ip-regex": "^4.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cli-table3": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/npm/node_modules/columnify": { + "version": "1.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/depd": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/event-target-shim": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/events": { + "version": "3.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/gauge": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.2.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/has": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "6.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "6.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/ini": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-package-arg": "^10.0.0", + "promzard": "^1.0.0", + "read": "^2.0.0", + "read-package-json": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/ip": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "cidr-regex": "^3.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/is-core-module": { + "version": "2.12.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "5.0.19", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/disparity-colors": "^3.0.0", + "@npmcli/installed-package-contents": "^2.0.2", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^9.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8", + "tar": "^6.1.13" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "ci-info": "^3.7.1", + "npm-package-arg": "^10.1.0", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "proc-log": "^3.0.0", + "read": "^2.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "4.0.19", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/arborist": "^6.3.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "9.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "5.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "5.0.19", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "7.5.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "ci-info": "^3.6.1", + "normalize-package-data": "^5.0.0", + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3", + "proc-log": "^3.0.0", + "semver": "^7.3.7", + "sigstore": "^1.4.0", + "ssri": "^10.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "5.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/git": "^4.0.1", + "@npmcli/run-script": "^6.0.0", + "json-parse-even-better-errors": "^3.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "11.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minipass": "^5.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "9.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/node-gyp/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "6.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "10.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "8.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "14.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npmlog": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "15.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.9.2", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.0.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/process": { + "version": "0.11.10", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "read": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "peer": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "mute-stream": "~1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json": { + "version": "6.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/readable-stream": { + "version": "4.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.5.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "1.7.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.1", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0", + "peer": true + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.13", + "dev": true, + "inBundle": true, + "license": "CC0-1.0", + "peer": true + }, + "node_modules/npm/node_modules/ssri": { + "version": "10.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.1.15", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "1.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "peer": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "peer": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "peer": true, + "dependencies": { + "p-map": "^5.1.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "peer": true, + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map/node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map/node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "peer": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "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/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "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": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "dev": true, + "peer": true, + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "peer": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "peer": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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, + "peer": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "peer": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "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/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "peer": true + }, + "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/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "peer": 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/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/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/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/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/read-pkg/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/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/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "peer": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "peer": true, + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semantic-release": { + "version": "21.0.7", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-21.0.7.tgz", + "integrity": "sha512-peRDSXN+hF8EFSKzze90ff/EnAmgITHQ/a3SZpRV3479ny0BIZWEJ33uX6/GlOSKdaSxo9hVRDyv2/u2MuF+Bw==", + "dev": true, + "peer": true, + "dependencies": { + "@semantic-release/commit-analyzer": "^10.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^10.0.2", + "@semantic-release/release-notes-generator": "^11.0.0", + "aggregate-error": "^4.0.1", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^9.0.0", + "execa": "^7.0.0", + "figures": "^5.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^6.0.0", + "lodash-es": "^4.17.21", + "marked": "^5.0.0", + "marked-terminal": "^5.1.1", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^10.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/semantic-release/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/semantic-release/node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "peer": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/semantic-release/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/semantic-release/node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/semantic-release/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "peer": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/semantic-release/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "peer": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "peer": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/semantic-release/node_modules/read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/read-pkg-up": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", + "dev": true, + "peer": true, + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "peer": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true, + "peer": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "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.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "peer": true, + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-combiner2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": 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/stream-combiner2/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, + "peer": true + }, + "node_modules/stream-combiner2/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, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/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, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "peer": true, + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "peer": true + }, + "node_modules/traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "peer": true, + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true, + "peer": true + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "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/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "peer": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/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/wrap-ansi/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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "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": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true + }, + "@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "peer": true + }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "dev": true, + "peer": true + }, + "@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dev": true, + "peer": true, + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "peer": true, + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", + "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", + "dev": true, + "peer": true + }, + "@octokit/plugin-paginate-rest": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-7.1.2.tgz", + "integrity": "sha512-Jx8KuKqEAVRsK6fMzZKv3h6UH9/NRDHsDRtUAROqqmZlCptM///Uef7A1ViZ/cbDplekz7VbDWdFLAZ/mpuDww==", + "dev": true, + "peer": true, + "requires": { + "@octokit/tsconfig": "^2.0.0", + "@octokit/types": "^9.3.2" + } + }, + "@octokit/plugin-retry": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-5.0.5.tgz", + "integrity": "sha512-sB1RWMhSrre02Atv95K6bhESlJ/sPdZkK/wE/w1IdSCe0yM6FxSjksLa6T7aAvxvxlLKzQEC4KIiqpqyov1Tbg==", + "dev": true, + "peer": true, + "requires": { + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "bottleneck": "^2.15.3" + }, + "dependencies": { + "@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dev": true, + "peer": true, + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + }, + "@octokit/plugin-throttling": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-6.1.0.tgz", + "integrity": "sha512-JqMbTiPC0sUSTsLQsdq3JVx1mx8UtTo5mwR80YqPXE93+XhevvSyOR1rO2Z+NbO/r0TK4hqFJSSi/9oIZBxZTg==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + } + }, + "@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "peer": true, + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/tsconfig": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-2.0.0.tgz", + "integrity": "sha512-tWnrai3quGt8+gRN2edzo9fmraWekeryXPeXDomMw2oFSpu/lH3VSWGn/q4V+rwjTRMeeXk/ci623/01Zet4VQ==", + "dev": true, + "peer": true + }, + "@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "peer": true, + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "peer": true + }, + "@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "4.2.10" + } + }, + "@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "dev": true, + "peer": true, + "requires": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + } + }, + "@saithodev/semantic-release-gitea": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-gitea/-/semantic-release-gitea-2.1.0.tgz", + "integrity": "sha512-jvr5U6/ZVADgwJ7yosymrwFF4AO+bhYMaiFNLoo/RUOJQNalrwziOmCtWH3YC/ouEd1TiPXDhfBOuXSgXvgANg==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "form-data": "^3.0.0", + "fs-extra": "^8.0.0", + "globby": "^10.0.0", + "got": "^10.0.1", + "lodash": "^4.17.21", + "querystring": "^0.2.0", + "url-join": "^4.0.0" + }, + "dependencies": { + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "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, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "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 + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + } + } + }, + "@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "dev": true, + "requires": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" + } + }, + "@semantic-release/commit-analyzer": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-10.0.1.tgz", + "integrity": "sha512-9ejHzTAijYs9z246sY/dKBatmOPcd0GQ7lH4MgLCkv1q4GCiDZRkjHJkaQZXZVaK7mJybS+sH3Ng6G8i3pYMGQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "debug": "^4.0.0", + "import-from": "^4.0.0", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "dependencies": { + "conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + } + }, + "conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + } + } + }, + "@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true + }, + "@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "dev": true, + "requires": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "dependencies": { + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "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 + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + } + } + }, + "@semantic-release/github": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.0.3.tgz", + "integrity": "sha512-X6gq4USKVlCxPwIIyXb99jU7gwVWlnsKOevs+OyABRdoqc+OIRITbFmrrYU3eE1vGMGk+Qu/GAoLUQQQwC3YOA==", + "dev": true, + "peer": true, + "requires": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^7.0.0", + "@octokit/plugin-retry": "^5.0.0", + "@octokit/plugin-throttling": "^6.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^4.0.1", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^13.1.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^3.0.0", + "p-filter": "^3.0.0", + "url-join": "^5.0.0" + }, + "dependencies": { + "@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true + }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "5.0.0" + } + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true + } + } + }, + "@semantic-release/npm": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-10.0.4.tgz", + "integrity": "sha512-6R3timIQ7VoL2QWRkc9DG8v74RQtRp7UOe/2KbNaqwJ815qOibAv65bH3RtTEhs4axEaHoZf7HDgFs5opaZ9Jw==", + "dev": true, + "peer": true, + "requires": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^4.0.1", + "execa": "^7.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^9.5.0", + "rc": "^1.2.8", + "read-pkg": "^8.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "dependencies": { + "@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true + }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "5.0.0" + } + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true + }, + "hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true + }, + "json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "peer": true + }, + "lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "peer": true + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "peer": true + }, + "normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "peer": true, + "requires": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + } + }, + "read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "peer": true, + "requires": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + } + }, + "type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true + } + } + }, + "@semantic-release/release-notes-generator": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-11.0.4.tgz", + "integrity": "sha512-j0Znnwq9IdWTCGzqSlkLv4MpALTsVDZxcVESzJCNN8pK2BYQlYaKsdZ1Ea/+7RlppI3vjhEi33ZKmjSGY1FLKw==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^6.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from": "^4.0.0", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^10.0.0" + }, + "dependencies": { + "conventional-changelog-angular": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", + "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "dev": true, + "requires": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + } + }, + "conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + } + }, + "conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true + }, + "hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true + }, + "lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + }, + "normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "requires": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + } + }, + "read-pkg-up": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", + "dev": true, + "requires": { + "find-up": "^6.3.0", + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" + } + }, + "type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, + "@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/node": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", + "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true + }, + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "peer": true, + "requires": { + "debug": "^4.3.4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^3.0.0" + }, + "dependencies": { + "type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "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, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true, + "peer": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true, + "peer": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "peer": true + }, + "bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "peer": true + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dev": true, + "requires": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + } + }, + "cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "peer": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "peer": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "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, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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 + }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "peer": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + }, + "dependencies": { + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + } + } + }, + "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, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "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, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commit-and-tag-version": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/commit-and-tag-version/-/commit-and-tag-version-11.2.2.tgz", + "integrity": "sha512-pqtTvRZFSqsGevhdcCvZVhzoSC56OeWZxhVzVDOWu97FfMJR4xUmpirRZcGqmTsDWCTxnm+UVl9/slN7OGO82A==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.25", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "6.1.0", + "conventional-recommended-bump": "7.0.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "git-semver-tags": "^5.0.0", + "semver": "^7.1.1", + "yargs": "^17.0.0" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + }, + "dependencies": { + "conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + } + } + }, + "conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + } + }, + "conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + }, + "conventional-recommended-bump": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", + "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^3.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "git-raw-commits": "^3.0.0", + "git-semver-tags": "^5.0.0", + "meow": "^8.1.2" + }, + "dependencies": { + "conventional-changelog-preset-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", + "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", + "dev": true + } + } + }, + "git-raw-commits": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", + "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "meow": "^8.1.2", + "split2": "^3.2.2" + } + }, + "git-semver-tags": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.0.tgz", + "integrity": "sha512-fZ+tmZ1O5aXW/T5nLzZLbxWAHdQTLLXalOECMNAmhoEQSfqZjtaeMjpsXH4C5qVhrICTkVQeQFujB1lKzIHljA==", + "dev": true, + "requires": { + "meow": "^8.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "peer": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + } + }, + "conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^1.0.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true + } + } + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true + } + } + }, + "decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dev": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "peer": true + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "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, + "requires": { + "locate-path": "^3.0.0" + } + }, + "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, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "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, + "requires": { + "p-try": "^2.0.0" + } + }, + "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, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + } + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "peer": true, + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "requires": { + "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" + } + }, + "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, + "peer": 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, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "once": "^1.4.0" + } + }, + "env-ci": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-9.1.1.tgz", + "integrity": "sha512-Im2yEWeF4b2RAMAaWvGioXk6m0UNaIjD8hj28j2ij5ldnIFrDQT0+pzDvpbRkcjurhXhf/AsBKv8P2rtmGi9Aw==", + "dev": true, + "peer": true, + "requires": { + "execa": "^7.0.0", + "java-properties": "^1.0.2" + } + }, + "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, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "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, + "peer": true + }, + "execa": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "fast-glob": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "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, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "peer": true, + "requires": { + "semver-regex": "^4.0.5" + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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 + }, + "get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "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, + "requires": { + "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" + } + }, + "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 + }, + "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" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", + "dev": true, + "peer": true, + "requires": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "requires": { + "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" + } + }, + "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, + "peer": true + }, + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "dev": true, + "peer": true, + "requires": { + "through2": "~2.0.0" + } + }, + "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, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "peer": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "dev": true, + "requires": { + "ini": "^1.3.2" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "peer": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dev": true, + "requires": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "dev": true, + "peer": true + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dev": true, + "peer": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", + "dev": true, + "peer": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "peer": true + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "peer": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true + } + } + }, + "import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", + "dev": true + }, + "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 + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "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 + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "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 + }, + "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 + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "peer": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "peer": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "peer": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "peer": true, + "requires": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + } + }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true, + "peer": true + }, + "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 + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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 + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "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" + } + }, + "keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "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 + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + } + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true, + "peer": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true, + "peer": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "peer": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "peer": true + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true, + "peer": true + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "marked": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.1.tgz", + "integrity": "sha512-bTmmGdEINWmOMDjnPWDxGPQ4qkDLeYorpYbEtFOXzOruTwUE671q4Guiuchn4N8h/v6NGd7916kXsm3Iz4iUSg==", + "dev": true, + "peer": true + }, + "marked-terminal": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.2.0.tgz", + "integrity": "sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==", + "dev": true, + "peer": true, + "requires": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.2.0", + "cli-table3": "^0.6.3", + "node-emoji": "^1.11.0", + "supports-hyperlinks": "^2.3.0" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "peer": true + } + } + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "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, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "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, + "requires": { + "p-locate": "^4.1.0" + } + }, + "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, + "requires": { + "p-try": "^2.0.0" + } + }, + "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, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "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, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "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 + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "peer": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "peer": true + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "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 + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true, + "peer": true + }, + "node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "requires": { + "lodash": "^4.17.21" + } + }, + "node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dev": true, + "peer": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true, + "peer": true + }, + "npm": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-9.8.0.tgz", + "integrity": "sha512-AXeiBAdfM5K2jvBwA7EGLKeYyt0VnhmJRnlq4k2+M0Ao9v7yKJBqF8xFPzQL8kAybzwlfpTPCZwM4uTIszb3xA==", + "dev": true, + "peer": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^6.3.0", + "@npmcli/config": "^6.2.1", + "@npmcli/map-workspaces": "^3.0.4", + "@npmcli/package-json": "^4.0.0", + "@npmcli/run-script": "^6.0.2", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^17.1.3", + "chalk": "^5.2.0", + "ci-info": "^3.8.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.3", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.2", + "glob": "^10.2.7", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^6.1.1", + "ini": "^4.1.1", + "init-package-json": "^5.0.0", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^3.0.0", + "libnpmaccess": "^7.0.2", + "libnpmdiff": "^5.0.19", + "libnpmexec": "^6.0.2", + "libnpmfund": "^4.0.19", + "libnpmhook": "^9.0.3", + "libnpmorg": "^5.0.4", + "libnpmpack": "^5.0.19", + "libnpmpublish": "^7.5.0", + "libnpmsearch": "^6.0.2", + "libnpmteam": "^5.0.3", + "libnpmversion": "^4.0.2", + "make-fetch-happen": "^11.1.1", + "minimatch": "^9.0.0", + "minipass": "^5.0.0", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^9.4.0", + "nopt": "^7.2.0", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.1.1", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-profile": "^7.0.1", + "npm-registry-fetch": "^14.0.5", + "npm-user-validate": "^2.0.0", + "npmlog": "^7.0.1", + "p-map": "^4.0.0", + "pacote": "^15.2.0", + "parse-conflict-json": "^3.0.1", + "proc-log": "^3.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^2.1.0", + "semver": "^7.5.2", + "sigstore": "^1.7.0", + "ssri": "^10.0.4", + "supports-color": "^9.3.1", + "tar": "^6.1.15", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.0", + "which": "^3.0.1", + "write-file-atomic": "^5.0.1" + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "bundled": true, + "dev": true, + "optional": true, + "peer": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "emoji-regex": { + "version": "9.2.2", + "bundled": true, + "dev": true, + "peer": true + }, + "string-width": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@npmcli/arborist": { + "version": "6.3.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.0", + "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^5.0.0", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^4.0.0", + "@npmcli/query": "^3.0.0", + "@npmcli/run-script": "^6.0.0", + "bin-links": "^4.0.1", + "cacache": "^17.0.4", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^6.1.1", + "json-parse-even-better-errors": "^3.0.0", + "json-stringify-nice": "^1.1.4", + "minimatch": "^9.0.0", + "nopt": "^7.0.0", + "npm-install-checks": "^6.0.0", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-registry-fetch": "^14.0.3", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "parse-conflict-json": "^3.0.0", + "proc-log": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.2", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.1", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + } + }, + "@npmcli/config": { + "version": "6.2.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^3.8.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + } + }, + "@npmcli/disparity-colors": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.3.0" + } + }, + "@npmcli/fs": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + } + }, + "@npmcli/installed-package-contents": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + } + }, + "@npmcli/map-workspaces": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + } + }, + "@npmcli/metavuln-calculator": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "cacache": "^17.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^15.0.0", + "semver": "^7.3.5" + } + }, + "@npmcli/name-from-folder": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@npmcli/node-gyp": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@npmcli/package-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/git": "^4.1.0", + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.1", + "proc-log": "^3.0.0" + } + }, + "@npmcli/promise-spawn": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "which": "^3.0.0" + } + }, + "@npmcli/query": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "@npmcli/run-script": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "bundled": true, + "dev": true, + "optional": true, + "peer": true + }, + "@sigstore/protobuf-specs": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@sigstore/tuf": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@sigstore/protobuf-specs": "^0.1.0", + "tuf-js": "^1.1.7" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@tufjs/canonical-json": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "@tufjs/models": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + } + }, + "abbrev": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "abort-controller": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "agent-base": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "are-we-there-yet": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^4.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "base64-js": { + "version": "1.5.1", + "bundled": true, + "dev": true, + "peer": true + }, + "bin-links": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "brace-expansion": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "buffer": { + "version": "6.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "builtins": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "semver": "^7.0.0" + } + }, + "cacache": { + "version": "17.1.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + } + }, + "chalk": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "chownr": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "ci-info": { + "version": "3.8.0", + "bundled": true, + "dev": true, + "peer": true + }, + "cidr-regex": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ip-regex": "^4.1.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "cli-columns": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, + "cli-table3": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "peer": true + }, + "cmd-shim": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "peer": true + }, + "color-support": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "peer": true + }, + "columnify": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + } + }, + "common-ancestor-path": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "peer": true + }, + "cross-spawn": { + "version": "7.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssesc": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "debug": { + "version": "4.3.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "peer": true + } + } + }, + "defaults": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "clone": "^1.0.2" + } + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "depd": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "diff": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "peer": true + }, + "eastasianwidth": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "emoji-regex": { + "version": "8.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "encoding": { + "version": "0.1.13", + "bundled": true, + "dev": true, + "optional": true, + "peer": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "env-paths": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "peer": true + }, + "err-code": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "peer": true + }, + "event-target-shim": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "events": { + "version": "3.3.0", + "bundled": true, + "dev": true, + "peer": true + }, + "exponential-backoff": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "bundled": true, + "dev": true, + "peer": true + }, + "foreground-child": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fs-minipass": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^5.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "gauge": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "glob": { + "version": "10.2.7", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.7.0" + } + }, + "graceful-fs": { + "version": "4.2.11", + "bundled": true, + "dev": true, + "peer": true + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "hosted-git-info": { + "version": "6.1.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "optional": true, + "peer": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "peer": true + }, + "ignore-walk": { + "version": "6.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minimatch": "^9.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "peer": true + }, + "indent-string": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "peer": true + }, + "ini": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "init-package-json": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-package-arg": "^10.0.0", + "promzard": "^1.0.0", + "read": "^2.0.0", + "read-package-json": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + } + }, + "ip": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "ip-regex": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "peer": true + }, + "is-cidr": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "cidr-regex": "^3.1.1" + } + }, + "is-core-module": { + "version": "2.12.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "is-lambda": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "jackspeak": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "json-parse-even-better-errors": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "peer": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "peer": true + }, + "just-diff": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "just-diff-apply": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "peer": true + }, + "libnpmaccess": { + "version": "7.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3" + } + }, + "libnpmdiff": { + "version": "5.0.19", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/disparity-colors": "^3.0.0", + "@npmcli/installed-package-contents": "^2.0.2", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^9.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8", + "tar": "^6.1.13" + } + }, + "libnpmexec": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "ci-info": "^3.7.1", + "npm-package-arg": "^10.1.0", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "proc-log": "^3.0.0", + "read": "^2.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + } + }, + "libnpmfund": { + "version": "4.0.19", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/arborist": "^6.3.0" + } + }, + "libnpmhook": { + "version": "9.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + } + }, + "libnpmorg": { + "version": "5.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + } + }, + "libnpmpack": { + "version": "5.0.19", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8" + } + }, + "libnpmpublish": { + "version": "7.5.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ci-info": "^3.6.1", + "normalize-package-data": "^5.0.0", + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3", + "proc-log": "^3.0.0", + "semver": "^7.3.7", + "sigstore": "^1.4.0", + "ssri": "^10.0.1" + } + }, + "libnpmsearch": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-registry-fetch": "^14.0.3" + } + }, + "libnpmteam": { + "version": "5.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + } + }, + "libnpmversion": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/git": "^4.0.1", + "@npmcli/run-script": "^6.0.0", + "json-parse-even-better-errors": "^3.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7" + } + }, + "lru-cache": { + "version": "7.18.3", + "bundled": true, + "dev": true, + "peer": true + }, + "make-fetch-happen": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + } + }, + "minimatch": { + "version": "9.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "minipass-collect": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-fetch": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^5.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "minipass-flush": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-sized": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minizlib": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "peer": true + }, + "ms": { + "version": "2.1.3", + "bundled": true, + "dev": true, + "peer": true + }, + "mute-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "negotiator": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "peer": true + }, + "node-gyp": { + "version": "9.4.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "are-we-there-yet": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "gauge": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nopt": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "abbrev": "^1.0.0" + } + }, + "npmlog": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, + "readable-stream": { + "version": "3.6.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "signal-exit": { + "version": "3.0.7", + "bundled": true, + "dev": true, + "peer": true + }, + "which": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "nopt": { + "version": "7.2.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "abbrev": "^2.0.0" + } + }, + "normalize-package-data": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-audit-report": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "npm-bundled": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-normalize-package-bin": "^3.0.0" + } + }, + "npm-install-checks": { + "version": "6.1.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-normalize-package-bin": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "npm-package-arg": { + "version": "10.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + } + }, + "npm-packlist": { + "version": "7.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ignore-walk": "^6.0.0" + } + }, + "npm-pick-manifest": { + "version": "8.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + } + }, + "npm-profile": { + "version": "7.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0" + } + }, + "npm-registry-fetch": { + "version": "14.0.5", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + } + }, + "npm-user-validate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "npmlog": { + "version": "7.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "wrappy": "1" + } + }, + "p-map": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "pacote": { + "version": "15.2.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + } + }, + "parse-conflict-json": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "path-key": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "peer": true + }, + "path-scurry": { + "version": "1.9.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.2" + }, + "dependencies": { + "lru-cache": { + "version": "9.1.1", + "bundled": true, + "dev": true, + "peer": true + } + } + }, + "postcss-selector-parser": { + "version": "6.0.13", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "proc-log": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "process": { + "version": "0.11.10", + "bundled": true, + "dev": true, + "peer": true + }, + "promise-all-reject-late": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "promise-call-limit": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "promise-retry": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "promzard": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "read": "^2.0.0" + } + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "peer": true + }, + "read": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "mute-stream": "~1.0.0" + } + }, + "read-cmd-shim": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "read-package-json": { + "version": "6.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + } + }, + "read-package-json-fast": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + } + }, + "readable-stream": { + "version": "4.4.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + } + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "peer": true + }, + "rimraf": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true, + "peer": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true, + "peer": true + }, + "semver": { + "version": "7.5.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "shebang-command": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "signal-exit": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "sigstore": { + "version": "1.7.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.1", + "make-fetch-happen": "^11.0.1" + } + }, + "smart-buffer": { + "version": "4.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "socks": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, + "spdx-correct": { + "version": "3.2.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "peer": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.13", + "bundled": true, + "dev": true, + "peer": true + }, + "ssri": { + "version": "10.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^5.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "9.3.1", + "bundled": true, + "dev": true, + "peer": true + }, + "tar": { + "version": "6.1.15", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "fs-minipass": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + } + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "peer": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "peer": true + }, + "treeverse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true + }, + "tuf-js": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + } + }, + "unique-filename": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "builtins": "^5.0.0" + } + }, + "walk-up-path": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "peer": true + }, + "ansi-styles": { + "version": "6.2.1", + "bundled": true, + "dev": true, + "peer": true + }, + "emoji-regex": { + "version": "9.2.2", + "bundled": true, + "dev": true, + "peer": true + }, + "string-width": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "peer": true + }, + "write-file-atomic": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "peer": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "yallist": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "peer": true + } + } + }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "peer": true, + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "peer": true + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "peer": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "dev": true, + "peer": true + }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, + "p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "peer": true, + "requires": { + "p-map": "^5.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true + }, + "p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "peer": true, + "requires": { + "aggregate-error": "^4.0.0" + }, + "dependencies": { + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "5.0.0" + } + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true + } + } + }, + "p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "dev": true, + "peer": true + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "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 + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "peer": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "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 + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "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, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + } + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "dev": true, + "peer": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "peer": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "peer": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "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, + "peer": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "peer": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "peer": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "peer": true + } + } + }, + "prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true + }, + "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 + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "peer": true + }, + "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, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true + }, + "querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "peer": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "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, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "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, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "peer": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "peer": true, + "requires": { + "@pnpm/npm-conf": "^2.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "peer": true + }, + "responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semantic-release": { + "version": "21.0.7", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-21.0.7.tgz", + "integrity": "sha512-peRDSXN+hF8EFSKzze90ff/EnAmgITHQ/a3SZpRV3479ny0BIZWEJ33uX6/GlOSKdaSxo9hVRDyv2/u2MuF+Bw==", + "dev": true, + "peer": true, + "requires": { + "@semantic-release/commit-analyzer": "^10.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^10.0.2", + "@semantic-release/release-notes-generator": "^11.0.0", + "aggregate-error": "^4.0.1", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^9.0.0", + "execa": "^7.0.0", + "figures": "^5.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^6.0.0", + "lodash-es": "^4.17.21", + "marked": "^5.0.0", + "marked-terminal": "^5.1.1", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^10.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "dependencies": { + "@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "peer": true + }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "peer": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "5.0.0" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "peer": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "peer": true + }, + "figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "peer": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true + }, + "json-parse-even-better-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", + "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", + "dev": true, + "peer": true + }, + "lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "peer": true + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "peer": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "peer": true + }, + "normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "peer": true, + "requires": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "peer": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "peer": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "parse-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.0.0.tgz", + "integrity": "sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "peer": true + }, + "read-pkg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.0.0.tgz", + "integrity": "sha512-Ajb9oSjxXBw0YyOiwtQ2dKbAA/vMnUPnY63XcCk+mXo0BwIdQEMgZLZiMWGttQHcUhUgbK0mH85ethMPKXxziw==", + "dev": true, + "peer": true, + "requires": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^5.0.0", + "parse-json": "^7.0.0", + "type-fest": "^3.8.0" + } + }, + "read-pkg-up": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", + "dev": true, + "peer": true, + "requires": { + "find-up": "^6.3.0", + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" + } + }, + "type-fest": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.0.tgz", + "integrity": "sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==", + "dev": true, + "peer": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "peer": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "peer": true + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "peer": true + } + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "peer": true, + "requires": { + "semver": "^7.3.5" + } + }, + "semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "peer": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "peer": true, + "requires": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "peer": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "peer": true + }, + "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 + }, + "spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true, + "peer": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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 + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "requires": { + "readable-stream": "^3.0.0" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "peer": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "requires": { + "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" + } + }, + "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, + "peer": 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, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "peer": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "peer": true + }, + "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, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "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, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "peer": true + }, + "tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "peer": true, + "requires": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "dependencies": { + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "peer": true + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, + "to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "dev": true + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "peer": true + }, + "traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true, + "peer": true + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true + }, + "unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "peer": true, + "requires": { + "crypto-random-string": "^4.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true, + "peer": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "peer": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "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, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "peer": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "peer": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ece5ff0 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "dcfrontend", + "version": "6.0.0", + "description": "Data Controller", + "devDependencies": { + "@saithodev/semantic-release-gitea": "^2.1.0", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^10.0.1", + "@semantic-release/git": "^10.0.1", + "@semantic-release/release-notes-generator": "^11.0.4", + "commit-and-tag-version": "^11.2.2", + "prettier": "3.0.0" + }, + "scripts": { + "install": "cd client && npm i && cd ../sas && npm i", + "build-frontend": "cd client && npm run build", + "release": "commit-and-tag-version", + "lint": "npm run lint:fix", + "lint:fix": "npx prettier --write \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"", + "lint:check": "npx prettier --check \"client/{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\" \"client/cypress/integration/*.tests.ts\"", + "jo": "echo" + }, + "repository": { + "type": "git", + "url": "https://git.datacontroller.io/dc/dc.git" + } +} diff --git a/sas/.sasjslint b/sas/.sasjslint new file mode 100644 index 0000000..4661ea5 --- /dev/null +++ b/sas/.sasjslint @@ -0,0 +1,15 @@ +{ + "noTrailingSpaces": true, + "noEncodedPasswords": true, + "hasDoxygenHeader": true, + "noSpacesInFileNames": true, + "lowerCaseFileNames": true, + "maxLineLength": 180, + "noTabIndentation": true, + "indentationMultiple": 2, + "hasMacroNameInMend": true, + "noNestedMacros": true, + "hasMacroParentheses": true, + "strictMacroDefinition": true, + "ignoreList":["sasjs/scratch"] +} diff --git a/sas/deploy/contextConfigCreate.json b/sas/deploy/contextConfigCreate.json new file mode 100644 index 0000000..ec42a6e --- /dev/null +++ b/sas/deploy/contextConfigCreate.json @@ -0,0 +1,11 @@ +{ + "attributes": { + "reuseServerProcesses": true, + "runServerAs": "cas" + }, + "name": "ViyaCiContext", + "launchContext": { + "contextName": "Datacontroller compute context" + }, + "launchType": "service" +} diff --git a/sas/deploy/contextConfigCreateProduction.json b/sas/deploy/contextConfigCreateProduction.json new file mode 100644 index 0000000..32c5624 --- /dev/null +++ b/sas/deploy/contextConfigCreateProduction.json @@ -0,0 +1,11 @@ +{ + "attributes": { + "reuseServerProcesses": true, + "runServerAs": "cas" + }, + "name": "ProductionCiContext", + "launchContext": { + "contextName": "Datacontroller compute context" + }, + "launchType": "service" +} diff --git a/sas/deploy/contextConfigEdit.json b/sas/deploy/contextConfigEdit.json new file mode 100644 index 0000000..e265d7d --- /dev/null +++ b/sas/deploy/contextConfigEdit.json @@ -0,0 +1,6 @@ +{ + "environment": { + "autoExecLines": ["%put hello;"] + }, + "name": "ViyaCiContext" +} \ No newline at end of file diff --git a/sas/deploy/contextConfigEditProduction.json b/sas/deploy/contextConfigEditProduction.json new file mode 100644 index 0000000..dd9d32a --- /dev/null +++ b/sas/deploy/contextConfigEditProduction.json @@ -0,0 +1,6 @@ +{ + "environment": { + "autoExecLines": ["%put hello;"] + }, + "name": "ProductionCiContext" +} \ No newline at end of file diff --git a/sas/deploy/makeData4GL.json b/sas/deploy/makeData4GL.json new file mode 100644 index 0000000..efa9c59 --- /dev/null +++ b/sas/deploy/makeData4GL.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "dcgroup", + "DCPATH": "/opt/data/DataController" + } + ] +} diff --git a/sas/deploy/makeDataSas9.json b/sas/deploy/makeDataSas9.json new file mode 100644 index 0000000..c2a3e53 --- /dev/null +++ b/sas/deploy/makeDataSas9.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "dc-admin", + "DCPATH": "/tmp/dcsas9" + } + ] +} diff --git a/sas/deploy/makeDataServer.json b/sas/deploy/makeDataServer.json new file mode 100644 index 0000000..6baad90 --- /dev/null +++ b/sas/deploy/makeDataServer.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "DCDEFAULT", + "DCPATH": "/tmp/mihajlo/dcserverfrs" + } + ] +} diff --git a/sas/deploy/makeDataV4.json b/sas/deploy/makeDataV4.json new file mode 100644 index 0000000..0567cc4 --- /dev/null +++ b/sas/deploy/makeDataV4.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "viyagroup08", + "DCPATH": "/export/pvs/sasdata/homes/viyademo08f/dc" + } + ] +} diff --git a/sas/deploy/makeDataViya.json b/sas/deploy/makeDataViya.json new file mode 100644 index 0000000..da01357 --- /dev/null +++ b/sas/deploy/makeDataViya.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "DC Demo Group", + "DCPATH": "/tmp/dcviya" + } + ] +} \ No newline at end of file diff --git a/sas/deploy/requestConfig.json b/sas/deploy/requestConfig.json new file mode 100644 index 0000000..32c639e --- /dev/null +++ b/sas/deploy/requestConfig.json @@ -0,0 +1,3 @@ +{ + "debug": true +} \ No newline at end of file diff --git a/sas/deploy/requestData.json b/sas/deploy/requestData.json new file mode 100644 index 0000000..a979e19 --- /dev/null +++ b/sas/deploy/requestData.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "SASAdministrators", + "DCPATH": "/tmp/dc" + } + ] +} \ No newline at end of file diff --git a/sas/deploy/requestDataProduction.json b/sas/deploy/requestDataProduction.json new file mode 100644 index 0000000..1575e00 --- /dev/null +++ b/sas/deploy/requestDataProduction.json @@ -0,0 +1,8 @@ +{ + "fromjs": [ + { + "ADMIN": "SASAdministrators", + "DCPATH": "/opt/data/dcprod" + } + ] +} \ No newline at end of file diff --git a/sas/mocks/sas9/sasjs/sasjsconfig.json b/sas/mocks/sas9/sasjs/sasjsconfig.json new file mode 100644 index 0000000..fdf535a --- /dev/null +++ b/sas/mocks/sas9/sasjs/sasjsconfig.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://raw.githubusercontent.com/sasjs/utils/main/src/types/sasjsconfig-schema.json", + "defaultTarget": "sas9-mocks", + "syncFolder": "sasjs", + "targets": [ + { + "name": "sas9-mocks", + "serverUrl": "http://localhost:5000", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": true + }, + "appLoc": "/User Folders/sasdemo/" + } + ] +} diff --git a/sas/mocks/sas9/sasjs/services/approvers/getapprovals.js b/sas/mocks/sas9/sasjs/services/approvers/getapprovals.js new file mode 100644 index 0000000..c758dc2 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/approvers/getapprovals.js @@ -0,0 +1,28 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:46" +, "fromsas": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/approvers/getapprovals" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80579DF8B43940ABDE0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:46:48.647000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/approvers/gethistory.js b/sas/mocks/sas9/sasjs/services/approvers/gethistory.js new file mode 100644 index 0000000..5c5a10f --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/approvers/gethistory.js @@ -0,0 +1,38 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "fromsas": +[ +{ +"TABLE_ID": "DC20220926T084322234_729360_2744", +"BASE_TABLE": "DC996664.MPE_X_TEST", +"SUBMITTED": " 2022-09-26 08:43:22", +"SUBMITTED_REASON_TXT": "", +"SUBMITTER": "sasdemo", +"REVIEWED": " 2022-09-26 08:43:52", +"STATUS": "APPROVED", +"REVIEWED_ON_DTTM": 1979801032.54, +"APPROVER": "sasdemo" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/approvers/gethistory" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD805772B147AE40AB1E0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:55.321000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/approvers/rejection.js b/sas/mocks/sas9/sasjs/services/approvers/rejection.js new file mode 100644 index 0000000..7ab2a00 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/approvers/rejection.js @@ -0,0 +1,37 @@ +_webout=`{"SYSDATE" : "27SEP22" +,"SYSTIME" : "07:56" +, "fromsas": +[ + { + "RESPONSE": "SUCCESS!", + "TABLE_ID": "DC20220927T075630819_560700_2598", + "REVIEWED_BY_NM": "sasdemo", + "BASE_TABLE": "DC996664.MPE_X_TEST", + "REVIEW_STATUS_ID": "REJECTED", + "REVIEWED_ON_DTTM": "27SEP22:07:56:53.47", + "REVIEW_REASON_TXT": "Test" + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/approvers/rejection" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80A91145F3B64092AC0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25980" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-27T07:56:53.688000" +,"MEMSIZE" : "82GB" +} +` diff --git a/sas/mocks/sas9/sasjs/services/auditors/getstagetable.js b/sas/mocks/sas9/sasjs/services/auditors/getstagetable.js new file mode 100644 index 0000000..c432b58 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/auditors/getstagetable.js @@ -0,0 +1,28 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "stagetable": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_BESTNUM":44 ,"SOME_CHAR":"this is dummy datass" ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_SHORTNUM":3 ,"SOME_TIME":42 ,"_____DELETE__THIS__RECORD_____":"No" } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/auditors/getstagetable" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576B5820C540A6200000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-09-26T08:43:25.714000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/auditors/postdata.js b/sas/mocks/sas9/sasjs/services/auditors/postdata.js new file mode 100644 index 0000000..02372f3 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/auditors/postdata.js @@ -0,0 +1,143 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "params": +[ +{ +"TABLE_ID": "DC20220926T084322234_729360_2744", +"SUBMIT_STATUS_CD": "SUBMITTED", +"BASE_LIB": "DC996664", +"BASE_DS": "MPE_X_TEST", +"SUBMITTED_BY_NM": "sasdemo", +"SUBMITTED_ON_DTTM": "26SEP22:08:43:22.38", +"SUBMITTED_REASON_TXT": "", +"INPUT_OBS": 1, +"INPUT_VARS": 10, +"NUM_OF_APPROVALS_REQUIRED": 1, +"NUM_OF_APPROVALS_REMAINING": 1, +"REVIEWED_BY_NM": "", +"REVIEWED_ON_DTTM": null, +"LIBDS": "DC996664.MPE_X_TEST", +"REVIEWED_ON": " .", +"DIFFTIME": "26SEP22:08:43:33.07", +"DIFFS_CSV": "tempDiffs_20220926_084334.csv", +"FILESIZE": " 456.0KB", +"FILESIZE_RAW": 466944, +"TRUNCATED": "NO", +"NUM_ADDED": 0, +"NUM_DELETED": 0, +"NUM_UPDATED": 1, +"SUBMITTED_ON": " 26SEP2022:08:43:22", +"ISAPPROVER": "YES" +} +] +, "cols": +[ +{ +"NAME": "PRIMARY_KEY_FIELD", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "" +}, +{ +"NAME": "SOME_CHAR", +"TYPE": 2, +"LENGTH": 32767, +"FORMAT": "" +}, +{ +"NAME": "SOME_DROPDOWN", +"TYPE": 2, +"LENGTH": 128, +"FORMAT": "" +}, +{ +"NAME": "SOME_NUM", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "" +}, +{ +"NAME": "SOME_DATE", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "DATE" +}, +{ +"NAME": "SOME_DATETIME", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "DATETIME" +}, +{ +"NAME": "SOME_TIME", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "TIME" +}, +{ +"NAME": "SOME_SHORTNUM", +"TYPE": 1, +"LENGTH": 4, +"FORMAT": "" +}, +{ +"NAME": "SOME_BESTNUM", +"TYPE": 1, +"LENGTH": 8, +"FORMAT": "BEST" +} +] +, "submits": +[ + +] +, "deleted": +[ +] +, "new": +[ +] +, "updates": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"this is dummy datass" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_TIME":42 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +] +, "originals": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_TIME":42 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +] +, "fmt_deleted": +[ +] +, "fmt_new": +[ +] +, "fmt_updates": +[ +{"PRIMARY_KEY_FIELD":"0" ,"SOME_CHAR":"this is dummy datass" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"01JAN1960:00:00:42" ,"SOME_TIME":"0:00:42" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +] +, "fmt_originals": +[ +{"PRIMARY_KEY_FIELD":"0" ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"01JAN1960:00:00:42" ,"SOME_TIME":"0:00:42" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/auditors/postdata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576D34BC6A406AE00000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "21468" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:40.967000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/editors/getdata.js b/sas/mocks/sas9/sasjs/services/editors/getdata.js new file mode 100644 index 0000000..05c147a --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/editors/getdata.js @@ -0,0 +1,521 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:30" +, "approvers": +[ +{ +"PERSONNAME": "sasdemo", +"EMAIL": "sasdemo", +"USERID": "sasdemo" +} +] +, "cols": +[ +{ +"NAME": "PRIMARY_KEY_FIELD", +"VARNUM": 1, +"LABEL": "PRIMARY_KEY_FIELD", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_BESTNUM", +"VARNUM": 9, +"LABEL": "SOME_BESTNUM", +"FMTNAME": "BEST", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_CHAR", +"VARNUM": 2, +"LABEL": "SOME_CHAR", +"FMTNAME": "", +"DDTYPE": "CHARACTER", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DATE", +"VARNUM": 5, +"LABEL": "SOME_DATE", +"FMTNAME": "DATE", +"DDTYPE": "DATE", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DATETIME", +"VARNUM": 6, +"LABEL": "SOME_DATETIME", +"FMTNAME": "DATETIME", +"DDTYPE": "DATETIME", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DROPDOWN", +"VARNUM": 3, +"LABEL": "SOME_DROPDOWN", +"FMTNAME": "", +"DDTYPE": "CHARACTER", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_NUM", +"VARNUM": 4, +"LABEL": "SOME_NUM", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_SHORTNUM", +"VARNUM": 8, +"LABEL": "SOME_SHORTNUM", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_TIME", +"VARNUM": 7, +"LABEL": "SOME_TIME", +"FMTNAME": "TIME", +"DDTYPE": "TIME", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +} +] +, "dqdata": +[ +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 1", +"SELECTBOX_ORDER": 1 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 2", +"SELECTBOX_ORDER": 2 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 3", +"SELECTBOX_ORDER": 2 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "This is a long option. This option is very long. It is optional, though.", +"SELECTBOX_ORDER": 3 +} +] +, "dqrules": +[ +{ +"BASE_COL": "PRIMARY_KEY_FIELD", +"RULE_TYPE": "NOTNULL", +"RULE_VALUE": "", +"X": 0 +}, +{ +"BASE_COL": "SOME_NUM", +"RULE_TYPE": "HARDSELECT_HOOK", +"RULE_VALUE": "services/validations/mpe_x_test.some_num", +"X": 0 +} +] +, "dsmeta": +[ +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Name", +"VALUE": "DC996664.MPE_X_TEST" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observations", +"VALUE": "496" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Member Type", +"VALUE": "DATA" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Variables", +"VALUE": "9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Engine", +"VALUE": "V9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Indexes", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Created", +"VALUE": "09/26/2022 08:24:39" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Integrity Constraints", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Last Modified", +"VALUE": "09/26/2022 08:24:45" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observation Length", +"VALUE": "32947" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Protection", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Deleted Observations", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Type", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Compressed", +"VALUE": "CHAR" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Label", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Reuse Space", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Representation", +"VALUE": "WINDOWS_64" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Point to Observations", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Encoding", +"VALUE": "wlatin1 Western (Windows)" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Sorted", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Data Set Page Size", +"VALUE": "262144" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Pages", +"VALUE": "3" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Index File Page Size", +"VALUE": "4096" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Index File Pages", +"VALUE": "4" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Repairs", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "ExtendObsCounter", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Filename", +"VALUE": "C:\DataController\DC996664\mpe_x_test.sas7bdat" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Release Created", +"VALUE": "9.0401M7" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Host Created", +"VALUE": "X64_DSRV16" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Owner Name", +"VALUE": "BUILTIN\Administrators" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size", +"VALUE": " 1MB" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size (bytes)", +"VALUE": "1048576" +} +] +, "maxvarlengths": +[ +{ +"NAME": "_____DELETE__THIS__RECORD_____", +"MAXLEN": 3 +}, +{ +"NAME": "PRIMARY_KEY_FIELD", +"MAXLEN": 4 +}, +{ +"NAME": "some_char", +"MAXLEN": 591 +}, +{ +"NAME": "some_dropdown", +"MAXLEN": 8 +}, +{ +"NAME": "some_num", +"MAXLEN": 8 +}, +{ +"NAME": "some_date", +"MAXLEN": 10 +}, +{ +"NAME": "some_datetime", +"MAXLEN": 19 +}, +{ +"NAME": "some_time", +"MAXLEN": 8 +}, +{ +"NAME": "some_shortnum", +"MAXLEN": 3 +}, +{ +"NAME": "some_bestnum", +"MAXLEN": 3 +} +] +, "query": +[ + +] +, "sasdata": +[ +{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:00:42" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1 ,"SOME_CHAR":"more dummy data" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:07:02" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":2 ,"SOME_CHAR":"even more dummy data" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:02:22" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":3 ,"SOME_CHAR":"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":1613.001 ,"SOME_DATE":"1961-02-27" ,"SOME_DATETIME":"1960-01-01 00:07:03" ,"SOME_TIME":"00:00:44" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":4 ,"SOME_CHAR":"if you can fill the unforgiving minute" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":1613.0011235 ,"SOME_DATE":"1971-08-02" ,"SOME_DATETIME":"1973-05-29 06:12:03" ,"SOME_TIME":"00:06:52" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1010 ,"SOME_CHAR":"10 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3677867113 ,"SOME_DATE":"1961-03-05" ,"SOME_DATETIME":"1960-01-01 08:16:44" ,"SOME_TIME":"00:00:35" ,"SOME_SHORTNUM":1 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1011 ,"SOME_CHAR":"11 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8693330497 ,"SOME_DATE":"1961-01-20" ,"SOME_DATETIME":"1960-01-01 01:25:19" ,"SOME_TIME":"00:00:01" ,"SOME_SHORTNUM":6 ,"SOME_BESTNUM":54 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1012 ,"SOME_CHAR":"12 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5432779065 ,"SOME_DATE":"1961-10-06" ,"SOME_DATETIME":"1960-01-01 02:57:35" ,"SOME_TIME":"00:00:35" ,"SOME_SHORTNUM":54 ,"SOME_BESTNUM":62 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1013 ,"SOME_CHAR":"13 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5051939867 ,"SOME_DATE":"1962-02-20" ,"SOME_DATETIME":"1960-01-01 06:47:55" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":38 ,"SOME_BESTNUM":4 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1014 ,"SOME_CHAR":"14 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0130502507 ,"SOME_DATE":"1960-01-13" ,"SOME_DATETIME":"1960-01-01 03:48:13" ,"SOME_TIME":"00:00:14" ,"SOME_SHORTNUM":92 ,"SOME_BESTNUM":57 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1015 ,"SOME_CHAR":"15 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5822708009 ,"SOME_DATE":"1962-07-12" ,"SOME_DATETIME":"1960-01-01 12:05:18" ,"SOME_TIME":"00:00:54" ,"SOME_SHORTNUM":92 ,"SOME_BESTNUM":80 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1016 ,"SOME_CHAR":"16 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1382724979 ,"SOME_DATE":"1960-08-29" ,"SOME_DATETIME":"1960-01-01 02:48:01" ,"SOME_TIME":"00:00:01" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":91 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1017 ,"SOME_CHAR":"17 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.892701324 ,"SOME_DATE":"1961-09-14" ,"SOME_DATETIME":"1960-01-01 07:03:58" ,"SOME_TIME":"00:01:37" ,"SOME_SHORTNUM":91 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1018 ,"SOME_CHAR":"18 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1852788567 ,"SOME_DATE":"1961-03-08" ,"SOME_DATETIME":"1960-01-01 00:22:48" ,"SOME_TIME":"00:00:32" ,"SOME_SHORTNUM":93 ,"SOME_BESTNUM":79 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1019 ,"SOME_CHAR":"19 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0737551018 ,"SOME_DATE":"1961-01-24" ,"SOME_DATETIME":"1960-01-01 03:14:33" ,"SOME_TIME":"00:00:21" ,"SOME_SHORTNUM":22 ,"SOME_BESTNUM":90 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1020 ,"SOME_CHAR":"20 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7128569939 ,"SOME_DATE":"1961-02-08" ,"SOME_DATETIME":"1960-01-01 01:50:23" ,"SOME_TIME":"00:01:40" ,"SOME_SHORTNUM":65 ,"SOME_BESTNUM":34 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1021 ,"SOME_CHAR":"21 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6706138443 ,"SOME_DATE":"1961-03-09" ,"SOME_DATETIME":"1960-01-01 04:52:55" ,"SOME_TIME":"00:00:13" ,"SOME_SHORTNUM":44 ,"SOME_BESTNUM":97 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1022 ,"SOME_CHAR":"22 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1423215792 ,"SOME_DATE":"1962-07-22" ,"SOME_DATETIME":"1960-01-01 07:25:01" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":66 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1023 ,"SOME_CHAR":"23 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1259848066 ,"SOME_DATE":"1962-09-01" ,"SOME_DATETIME":"1960-01-01 09:32:34" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":44 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1024 ,"SOME_CHAR":"24 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3899468637 ,"SOME_DATE":"1961-12-06" ,"SOME_DATETIME":"1960-01-01 06:53:51" ,"SOME_TIME":"00:00:33" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":90 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1025 ,"SOME_CHAR":"25 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0310356193 ,"SOME_DATE":"1960-03-01" ,"SOME_DATETIME":"1960-01-01 02:58:07" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":73 ,"SOME_BESTNUM":59 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1026 ,"SOME_CHAR":"26 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9057884239 ,"SOME_DATE":"1960-10-04" ,"SOME_DATETIME":"1960-01-01 11:17:28" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":82 ,"SOME_BESTNUM":46 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1027 ,"SOME_CHAR":"27 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5920675856 ,"SOME_DATE":"1962-07-15" ,"SOME_DATETIME":"1960-01-01 03:35:41" ,"SOME_TIME":"00:00:22" ,"SOME_SHORTNUM":46 ,"SOME_BESTNUM":73 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1028 ,"SOME_CHAR":"28 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6580030046 ,"SOME_DATE":"1960-10-08" ,"SOME_DATETIME":"1960-01-01 13:13:30" ,"SOME_TIME":"00:00:40" ,"SOME_SHORTNUM":35 ,"SOME_BESTNUM":40 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1029 ,"SOME_CHAR":"29 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.807042594 ,"SOME_DATE":"1960-12-26" ,"SOME_DATETIME":"1960-01-01 11:57:14" ,"SOME_TIME":"00:00:19" ,"SOME_SHORTNUM":80 ,"SOME_BESTNUM":12 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1030 ,"SOME_CHAR":"30 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8801450408 ,"SOME_DATE":"1961-05-15" ,"SOME_DATETIME":"1960-01-01 10:11:05" ,"SOME_TIME":"00:00:25" ,"SOME_SHORTNUM":70 ,"SOME_BESTNUM":19 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1031 ,"SOME_CHAR":"31 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4150194705 ,"SOME_DATE":"1962-01-27" ,"SOME_DATETIME":"1960-01-01 11:27:09" ,"SOME_TIME":"00:01:04" ,"SOME_SHORTNUM":94 ,"SOME_BESTNUM":48 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1032 ,"SOME_CHAR":"32 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9743401203 ,"SOME_DATE":"1962-01-09" ,"SOME_DATETIME":"1960-01-01 07:44:35" ,"SOME_TIME":"00:01:07" ,"SOME_SHORTNUM":43 ,"SOME_BESTNUM":3 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1033 ,"SOME_CHAR":"33 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2035595692 ,"SOME_DATE":"1960-09-07" ,"SOME_DATETIME":"1960-01-01 11:52:19" ,"SOME_TIME":"00:00:42" ,"SOME_SHORTNUM":29 ,"SOME_BESTNUM":56 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1034 ,"SOME_CHAR":"34 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6792435556 ,"SOME_DATE":"1960-04-21" ,"SOME_DATETIME":"1960-01-01 07:17:04" ,"SOME_TIME":"00:01:14" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":9 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1035 ,"SOME_CHAR":"35 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9494116972 ,"SOME_DATE":"1960-01-19" ,"SOME_DATETIME":"1960-01-01 10:15:38" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":91 ,"SOME_BESTNUM":10 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1036 ,"SOME_CHAR":"36 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5446134911 ,"SOME_DATE":"1960-10-26" ,"SOME_DATETIME":"1960-01-01 03:55:27" ,"SOME_TIME":"00:01:24" ,"SOME_SHORTNUM":72 ,"SOME_BESTNUM":36 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1037 ,"SOME_CHAR":"37 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.458775894 ,"SOME_DATE":"1960-11-21" ,"SOME_DATETIME":"1960-01-01 13:34:37" ,"SOME_TIME":"00:01:35" ,"SOME_SHORTNUM":97 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1038 ,"SOME_CHAR":"38 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1537194239 ,"SOME_DATE":"1961-05-06" ,"SOME_DATETIME":"1960-01-01 06:14:13" ,"SOME_TIME":"00:00:29" ,"SOME_SHORTNUM":60 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1039 ,"SOME_CHAR":"39 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4935002562 ,"SOME_DATE":"1960-06-05" ,"SOME_DATETIME":"1960-01-01 06:59:42" ,"SOME_TIME":"00:00:45" ,"SOME_SHORTNUM":95 ,"SOME_BESTNUM":55 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1040 ,"SOME_CHAR":"40 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.124728859 ,"SOME_DATE":"1961-03-09" ,"SOME_DATETIME":"1960-01-01 03:03:06" ,"SOME_TIME":"00:01:23" ,"SOME_SHORTNUM":35 ,"SOME_BESTNUM":79 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1041 ,"SOME_CHAR":"41 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2794422001 ,"SOME_DATE":"1962-07-06" ,"SOME_DATETIME":"1960-01-01 05:29:26" ,"SOME_TIME":"00:00:51" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1042 ,"SOME_CHAR":"42 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7030775499 ,"SOME_DATE":"1960-08-11" ,"SOME_DATETIME":"1960-01-01 12:11:24" ,"SOME_TIME":"00:00:38" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":97 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1043 ,"SOME_CHAR":"43 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0701107537 ,"SOME_DATE":"1961-01-29" ,"SOME_DATETIME":"1960-01-01 03:44:09" ,"SOME_TIME":"00:00:03" ,"SOME_SHORTNUM":25 ,"SOME_BESTNUM":8 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1044 ,"SOME_CHAR":"44 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6423292927 ,"SOME_DATE":"1962-01-15" ,"SOME_DATETIME":"1960-01-01 00:57:07" ,"SOME_TIME":"00:00:09" ,"SOME_SHORTNUM":97 ,"SOME_BESTNUM":37 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1045 ,"SOME_CHAR":"45 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7206447743 ,"SOME_DATE":"1961-10-14" ,"SOME_DATETIME":"1960-01-01 12:25:32" ,"SOME_TIME":"00:00:07" ,"SOME_SHORTNUM":58 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1046 ,"SOME_CHAR":"46 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0431997366 ,"SOME_DATE":"1960-09-12" ,"SOME_DATETIME":"1960-01-01 05:12:57" ,"SOME_TIME":"00:01:35" ,"SOME_SHORTNUM":17 ,"SOME_BESTNUM":8 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1047 ,"SOME_CHAR":"47 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3704071368 ,"SOME_DATE":"1960-07-01" ,"SOME_DATETIME":"1960-01-01 02:44:37" ,"SOME_TIME":"00:00:06" ,"SOME_SHORTNUM":45 ,"SOME_BESTNUM":26 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1048 ,"SOME_CHAR":"48 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.654417035 ,"SOME_DATE":"1961-05-04" ,"SOME_DATETIME":"1960-01-01 01:23:07" ,"SOME_TIME":"00:01:38" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":13 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1049 ,"SOME_CHAR":"49 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1300212565 ,"SOME_DATE":"1961-01-06" ,"SOME_DATETIME":"1960-01-01 05:27:29" ,"SOME_TIME":"00:01:21" ,"SOME_SHORTNUM":37 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1050 ,"SOME_CHAR":"50 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0058409725 ,"SOME_DATE":"1960-07-23" ,"SOME_DATETIME":"1960-01-01 00:04:24" ,"SOME_TIME":"00:00:40" ,"SOME_SHORTNUM":15 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1051 ,"SOME_CHAR":"51 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7239382587 ,"SOME_DATE":"1960-06-09" ,"SOME_DATETIME":"1960-01-01 03:15:09" ,"SOME_TIME":"00:00:04" ,"SOME_SHORTNUM":42 ,"SOME_BESTNUM":82 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1052 ,"SOME_CHAR":"52 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8319003712 ,"SOME_DATE":"1960-08-13" ,"SOME_DATETIME":"1960-01-01 07:38:35" ,"SOME_TIME":"00:00:36" ,"SOME_SHORTNUM":69 ,"SOME_BESTNUM":81 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1053 ,"SOME_CHAR":"53 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5030828875 ,"SOME_DATE":"1961-06-22" ,"SOME_DATETIME":"1960-01-01 11:25:29" ,"SOME_TIME":"00:00:53" ,"SOME_SHORTNUM":39 ,"SOME_BESTNUM":75 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1054 ,"SOME_CHAR":"54 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7148045514 ,"SOME_DATE":"1960-08-26" ,"SOME_DATETIME":"1960-01-01 10:10:09" ,"SOME_TIME":"00:00:39" ,"SOME_SHORTNUM":6 ,"SOME_BESTNUM":4 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1055 ,"SOME_CHAR":"55 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8557945787 ,"SOME_DATE":"1960-10-19" ,"SOME_DATETIME":"1960-01-01 02:17:32" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":93 ,"SOME_BESTNUM":36 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1056 ,"SOME_CHAR":"56 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9700463307 ,"SOME_DATE":"1962-07-11" ,"SOME_DATETIME":"1960-01-01 11:18:41" ,"SOME_TIME":"00:00:51" ,"SOME_SHORTNUM":25 ,"SOME_BESTNUM":35 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1057 ,"SOME_CHAR":"57 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9380399426 ,"SOME_DATE":"1961-06-26" ,"SOME_DATETIME":"1960-01-01 13:15:13" ,"SOME_TIME":"00:00:52" ,"SOME_SHORTNUM":57 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1058 ,"SOME_CHAR":"58 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8484499486 ,"SOME_DATE":"1960-06-02" ,"SOME_DATETIME":"1960-01-01 01:14:51" ,"SOME_TIME":"00:00:00" ,"SOME_SHORTNUM":80 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1059 ,"SOME_CHAR":"59 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1415707628 ,"SOME_DATE":"1961-07-28" ,"SOME_DATETIME":"1960-01-01 06:33:16" ,"SOME_TIME":"00:00:58" ,"SOME_SHORTNUM":11 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1060 ,"SOME_CHAR":"60 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.282674513 ,"SOME_DATE":"1962-03-27" ,"SOME_DATETIME":"1960-01-01 00:25:37" ,"SOME_TIME":"00:00:56" ,"SOME_SHORTNUM":79 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1061 ,"SOME_CHAR":"61 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.372728008 ,"SOME_DATE":"1962-01-04" ,"SOME_DATETIME":"1960-01-01 05:07:43" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":92 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1062 ,"SOME_CHAR":"62 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9517337316 ,"SOME_DATE":"1961-08-29" ,"SOME_DATETIME":"1960-01-01 02:40:05" ,"SOME_TIME":"00:00:05" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":93 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1063 ,"SOME_CHAR":"63 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0967498683 ,"SOME_DATE":"1962-02-17" ,"SOME_DATETIME":"1960-01-01 07:30:41" ,"SOME_TIME":"00:00:29" ,"SOME_SHORTNUM":90 ,"SOME_BESTNUM":82 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1064 ,"SOME_CHAR":"64 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0540671353 ,"SOME_DATE":"1961-05-26" ,"SOME_DATETIME":"1960-01-01 13:13:43" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":45 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1065 ,"SOME_CHAR":"65 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6461636464 ,"SOME_DATE":"1962-01-27" ,"SOME_DATETIME":"1960-01-01 02:56:41" ,"SOME_TIME":"00:00:19" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":38 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1066 ,"SOME_CHAR":"66 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9053011983 ,"SOME_DATE":"1960-10-02" ,"SOME_DATETIME":"1960-01-01 03:35:49" ,"SOME_TIME":"00:01:04" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":39 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1067 ,"SOME_CHAR":"67 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.977525881 ,"SOME_DATE":"1962-07-19" ,"SOME_DATETIME":"1960-01-01 05:53:20" ,"SOME_TIME":"00:00:28" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":34 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1068 ,"SOME_CHAR":"68 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2165553161 ,"SOME_DATE":"1960-05-13" ,"SOME_DATETIME":"1960-01-01 01:44:02" ,"SOME_TIME":"00:01:12" ,"SOME_SHORTNUM":63 ,"SOME_BESTNUM":23 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1069 ,"SOME_CHAR":"69 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2248352795 ,"SOME_DATE":"1961-05-09" ,"SOME_DATETIME":"1960-01-01 00:04:33" ,"SOME_TIME":"00:00:09" ,"SOME_SHORTNUM":26 ,"SOME_BESTNUM":93 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1070 ,"SOME_CHAR":"70 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1386283367 ,"SOME_DATE":"1962-05-18" ,"SOME_DATETIME":"1960-01-01 03:32:00" ,"SOME_TIME":"00:01:36" ,"SOME_SHORTNUM":83 ,"SOME_BESTNUM":89 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1071 ,"SOME_CHAR":"71 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9337331415 ,"SOME_DATE":"1961-05-16" ,"SOME_DATETIME":"1960-01-01 13:46:54" ,"SOME_TIME":"00:00:47" ,"SOME_SHORTNUM":27 ,"SOME_BESTNUM":56 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1072 ,"SOME_CHAR":"72 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0352235506 ,"SOME_DATE":"1961-06-06" ,"SOME_DATETIME":"1960-01-01 09:09:20" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":7 ,"SOME_BESTNUM":27 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1073 ,"SOME_CHAR":"73 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3206662695 ,"SOME_DATE":"1960-03-13" ,"SOME_DATETIME":"1960-01-01 10:38:11" ,"SOME_TIME":"00:01:08" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":50 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1074 ,"SOME_CHAR":"74 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4610861705 ,"SOME_DATE":"1961-08-31" ,"SOME_DATETIME":"1960-01-01 09:35:41" ,"SOME_TIME":"00:01:08" ,"SOME_SHORTNUM":54 ,"SOME_BESTNUM":68 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1075 ,"SOME_CHAR":"75 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4527745622 ,"SOME_DATE":"1962-01-16" ,"SOME_DATETIME":"1960-01-01 06:49:27" ,"SOME_TIME":"00:00:45" ,"SOME_SHORTNUM":96 ,"SOME_BESTNUM":63 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1076 ,"SOME_CHAR":"76 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3581244058 ,"SOME_DATE":"1960-05-16" ,"SOME_DATETIME":"1960-01-01 00:56:40" ,"SOME_TIME":"00:01:13" ,"SOME_SHORTNUM":72 ,"SOME_BESTNUM":24 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1077 ,"SOME_CHAR":"77 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8939921334 ,"SOME_DATE":"1961-01-21" ,"SOME_DATETIME":"1960-01-01 09:16:31" ,"SOME_TIME":"00:01:15" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":69 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1078 ,"SOME_CHAR":"78 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2445727066 ,"SOME_DATE":"1960-12-22" ,"SOME_DATETIME":"1960-01-01 03:11:14" ,"SOME_TIME":"00:01:37" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1079 ,"SOME_CHAR":"79 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9683029465 ,"SOME_DATE":"1961-08-14" ,"SOME_DATETIME":"1960-01-01 04:45:43" ,"SOME_TIME":"00:01:09" ,"SOME_SHORTNUM":51 ,"SOME_BESTNUM":60 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1080 ,"SOME_CHAR":"80 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1303541368 ,"SOME_DATE":"1962-02-28" ,"SOME_DATETIME":"1960-01-01 02:14:50" ,"SOME_TIME":"00:00:21" ,"SOME_SHORTNUM":79 ,"SOME_BESTNUM":87 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1081 ,"SOME_CHAR":"81 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7656979653 ,"SOME_DATE":"1961-08-03" ,"SOME_DATETIME":"1960-01-01 06:49:50" ,"SOME_TIME":"00:01:31" ,"SOME_SHORTNUM":58 ,"SOME_BESTNUM":30 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1082 ,"SOME_CHAR":"82 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1855629674 ,"SOME_DATE":"1960-12-16" ,"SOME_DATETIME":"1960-01-01 06:27:21" ,"SOME_TIME":"00:00:33" ,"SOME_SHORTNUM":1 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1083 ,"SOME_CHAR":"83 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4782178642 ,"SOME_DATE":"1961-04-16" ,"SOME_DATETIME":"1960-01-01 08:05:23" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":0 ,"SOME_BESTNUM":1 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1084 ,"SOME_CHAR":"84 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1670272132 ,"SOME_DATE":"1962-06-21" ,"SOME_DATETIME":"1960-01-01 13:43:20" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":53 ,"SOME_BESTNUM":6 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1085 ,"SOME_CHAR":"85 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6068249189 ,"SOME_DATE":"1960-05-21" ,"SOME_DATETIME":"1960-01-01 11:05:11" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":17 ,"SOME_BESTNUM":68 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1086 ,"SOME_CHAR":"86 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0936049917 ,"SOME_DATE":"1962-07-20" ,"SOME_DATETIME":"1960-01-01 07:16:09" ,"SOME_TIME":"00:00:46" ,"SOME_SHORTNUM":73 ,"SOME_BESTNUM":37 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1087 ,"SOME_CHAR":"87 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6538249178 ,"SOME_DATE":"1960-04-24" ,"SOME_DATETIME":"1960-01-01 02:06:54" ,"SOME_TIME":"00:00:59" ,"SOME_SHORTNUM":95 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1088 ,"SOME_CHAR":"88 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8846158562 ,"SOME_DATE":"1961-11-19" ,"SOME_DATETIME":"1960-01-01 05:35:27" ,"SOME_TIME":"00:01:01" ,"SOME_SHORTNUM":87 ,"SOME_BESTNUM":30 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1089 ,"SOME_CHAR":"89 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1578208316 ,"SOME_DATE":"1961-03-03" ,"SOME_DATETIME":"1960-01-01 09:02:02" ,"SOME_TIME":"00:00:23" ,"SOME_SHORTNUM":60 ,"SOME_BESTNUM":53 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1090 ,"SOME_CHAR":"90 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4225753753 ,"SOME_DATE":"1960-03-19" ,"SOME_DATETIME":"1960-01-01 12:14:04" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":57 ,"SOME_BESTNUM":64 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1091 ,"SOME_CHAR":"91 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6598943354 ,"SOME_DATE":"1961-09-17" ,"SOME_DATETIME":"1960-01-01 03:03:13" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":28 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1092 ,"SOME_CHAR":"92 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6293501689 ,"SOME_DATE":"1961-10-18" ,"SOME_DATETIME":"1960-01-01 00:21:13" ,"SOME_TIME":"00:01:11" ,"SOME_SHORTNUM":64 ,"SOME_BESTNUM":7 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1093 ,"SOME_CHAR":"93 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4378844986 ,"SOME_DATE":"1961-06-24" ,"SOME_DATETIME":"1960-01-01 10:20:39" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":78 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1094 ,"SOME_CHAR":"94 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9838584969 ,"SOME_DATE":"1962-05-25" ,"SOME_DATETIME":"1960-01-01 02:59:06" ,"SOME_TIME":"00:00:59" ,"SOME_SHORTNUM":48 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1095 ,"SOME_CHAR":"95 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.089252377 ,"SOME_DATE":"1961-06-16" ,"SOME_DATETIME":"1960-01-01 04:54:20" ,"SOME_TIME":"00:00:10" ,"SOME_SHORTNUM":75 ,"SOME_BESTNUM":33 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1096 ,"SOME_CHAR":"96 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4578205154 ,"SOME_DATE":"1960-01-20" ,"SOME_DATETIME":"1960-01-01 10:36:00" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":14 ,"SOME_BESTNUM":17 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1097 ,"SOME_CHAR":"97 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5863271587 ,"SOME_DATE":"1962-04-20" ,"SOME_DATETIME":"1960-01-01 11:14:11" ,"SOME_TIME":"00:01:28" ,"SOME_SHORTNUM":66 ,"SOME_BESTNUM":84 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1098 ,"SOME_CHAR":"98 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2994232058 ,"SOME_DATE":"1960-07-04" ,"SOME_DATETIME":"1960-01-01 08:15:41" ,"SOME_TIME":"00:01:28" ,"SOME_SHORTNUM":99 ,"SOME_BESTNUM":85 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1099 ,"SOME_CHAR":"99 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0981378053 ,"SOME_DATE":"1960-02-05" ,"SOME_DATETIME":"1960-01-01 11:10:11" ,"SOME_TIME":"00:00:43" ,"SOME_SHORTNUM":23 ,"SOME_BESTNUM":65 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10100 ,"SOME_CHAR":"100 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9829722652 ,"SOME_DATE":"1960-02-01" ,"SOME_DATETIME":"1960-01-01 05:45:06" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10101 ,"SOME_CHAR":"101 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4540794913 ,"SOME_DATE":"1962-08-03" ,"SOME_DATETIME":"1960-01-01 09:27:03" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":42 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10102 ,"SOME_CHAR":"102 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8452174369 ,"SOME_DATE":"1960-10-02" ,"SOME_DATETIME":"1960-01-01 03:08:47" ,"SOME_TIME":"00:00:23" ,"SOME_SHORTNUM":10 ,"SOME_BESTNUM":14 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10103 ,"SOME_CHAR":"103 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5904919606 ,"SOME_DATE":"1960-07-30" ,"SOME_DATETIME":"1960-01-01 13:09:58" ,"SOME_TIME":"00:00:10" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":53 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10104 ,"SOME_CHAR":"104 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7083388677 ,"SOME_DATE":"1960-07-24" ,"SOME_DATETIME":"1960-01-01 05:49:50" ,"SOME_TIME":"00:01:29" ,"SOME_SHORTNUM":84 ,"SOME_BESTNUM":33 } +] +, "$sasdata":{"vars":{ +"_____DELETE__THIS__RECORD_____" :{"format":"$3." ,"label":"_____DELETE__THIS__RECORD_____" ,"length":"3" ,"type":"char" } +,"PRIMARY_KEY_FIELD" :{"format":"best." ,"label":"PRIMARY_KEY_FIELD" ,"length":"8" ,"type":"num" } +,"SOME_CHAR" :{"format":"$32767." ,"label":"SOME_CHAR" ,"length":"32767" ,"type":"char" } +,"SOME_DROPDOWN" :{"format":"$128." ,"label":"SOME_DROPDOWN" ,"length":"128" ,"type":"char" } +,"SOME_NUM" :{"format":"best." ,"label":"SOME_NUM" ,"length":"8" ,"type":"num" } +,"SOME_DATE" :{"format":"$200." ,"label":"SOME_DATE" ,"length":"200" ,"type":"char" } +,"SOME_DATETIME" :{"format":"$200." ,"label":"SOME_DATETIME" ,"length":"200" ,"type":"char" } +,"SOME_TIME" :{"format":"$200." ,"label":"SOME_TIME" ,"length":"200" ,"type":"char" } +,"SOME_SHORTNUM" :{"format":"best." ,"label":"SOME_SHORTNUM" ,"length":"4" ,"type":"num" } +,"SOME_BESTNUM" :{"format":"BEST." ,"label":"SOME_BESTNUM" ,"length":"8" ,"type":"num" } +}} +, "sasparams": +[ +{ +"COLHEADERS": "_____DELETE__THIS__RECORD_____,PRIMARY_KEY_FIELD,SOME_CHAR,SOME_DROPDOWN,SOME_NUM,SOME_DATE,SOME_DATETIME,SOME_TIME,SOME_SHORTNUM,SOME_BESTNUM", +"FILTER_TEXT": "", +"PKCNT": 1, +"PK": "PRIMARY_KEY_FIELD", +"DTVARS": " SOME_DATE", +"DTTMVARS": " SOME_DATETIME", +"TMVARS": " SOME_TIME", +"COLTYPE": "{\\"data\\":\\"_____DELETE__THIS__RECORD_____\\",\\"type\\":\\"dropdown\\",\\"source\\":[\\"No\\",\\"Yes\\"]},{\\"data\\":\\"PRIMARY_KEY_FIELD\\",\\"type\\":\\"numeric\\",\\"format\\":\\"0\\"},{\\"data\\":\\"SOME_CHAR\\"},{\\"data\\":\\"SOME_DROPDOWN\\"},{\\"data\\":\\"SOME_NUM\\",\\"type\\":\\"numeric\\",\\"format\\":\\"0\\"},{\\"data\\":\\"SOME_DATE\\",\\"type\\":\\"date\\",\\"dateFormat\\":\\"YYYY-MM-DD\\",\\"correctFormat\\":\\"true\\"},{\\"data\\":\\"SOME_DATETIME\\",\\"type\\":\\"date\\",\\"dateFormat\\":\\"YYYY-MM-DD HH:mm:ss\\",\\"correctFormat\\":\\"true\\"},{\\"data\\":\\"SOME_TIME\\",\\"type\\":\\"time\\",\\"timeFormat\\":\\"HH:mm:ss\\",\\"correctFormat\\":\\"true\\"},{\\"data\\":\\"SOME_SHORTNUM\\",\\"type\\":\\"numeric\\",\\"format\\":\\"0\\"},{\\"data\\":\\"SOME_BESTNUM\\",\\"type\\":\\"numeric\\",\\"format\\":\\"0\\"}", +"LOADTYPE": "UPDATE", +"RK_FLAG": 0, +"CLS_FLAG": 0 +} +] +, "xl_rules": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/getdata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8056A491DB23409E940000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:30:13.853000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/editors/getdynamiccolvals.js b/sas/mocks/sas9/sasjs/services/editors/getdynamiccolvals.js new file mode 100644 index 0000000..a1445da --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/editors/getdynamiccolvals.js @@ -0,0 +1,2510 @@ +_webout=`{"SYSDATE" : "29SEP22" +,"SYSTIME" : "11:51" +, "dynamic_values": +[ + [ + 1, + "0.0010556476", + 0.00105564761956 + ], + [ + 2, + "0.0052189599", + 0.00521895988156 + ], + [ + 3, + "0.0058409725", + 0.0058409725343 + ], + [ + 4, + "0.006130504", + 0.00613050395908 + ], + [ + 5, + "0.0130502507", + 0.01305025071513 + ], + [ + 6, + "0.0144214248", + 0.01442142483518 + ], + [ + 7, + "0.0242283885", + 0.02422838845487 + ], + [ + 8, + "0.0256445333", + 0.0256445333481 + ], + [ + 9, + "0.0262452592", + 0.02624525922641 + ], + [ + 10, + "0.0289132246", + 0.02891322459509 + ], + [ + 11, + "0.029728665", + 0.02972866503043 + ], + [ + 12, + "0.0310356193", + 0.03103561933666 + ], + [ + 13, + "0.0315013211", + 0.03150132113671 + ], + [ + 14, + "0.0352235506", + 0.03522355064527 + ], + [ + 15, + "0.0352940625", + 0.03529406247441 + ], + [ + 16, + "0.0397578571", + 0.03975785711768 + ], + [ + 17, + "0.0431997366", + 0.04319973664507 + ], + [ + 18, + "0.0452116919", + 0.04521169189606 + ], + [ + 19, + "0.0478734295", + 0.04787342951068 + ], + [ + 20, + "0.0494814422", + 0.04948144222119 + ], + [ + 21, + "0.0509991274", + 0.05099912735214 + ], + [ + 22, + "0.0511230966", + 0.05112309663143 + ], + [ + 23, + "0.0540671353", + 0.05406713534801 + ], + [ + 24, + "0.0545679247", + 0.05456792472608 + ], + [ + 25, + "0.0560880252", + 0.05608802524213 + ], + [ + 26, + "0.0564905135", + 0.0564905135224 + ], + [ + 27, + "0.0565994717", + 0.05659947174442 + ], + [ + 28, + "0.0627542204", + 0.06275422035844 + ], + [ + 29, + "0.0628753263", + 0.06287532628647 + ], + [ + 30, + "0.0667286301", + 0.06672863013424 + ], + [ + 31, + "0.0701107537", + 0.0701107536769 + ], + [ + 32, + "0.0711784712", + 0.07117847123703 + ], + [ + 33, + "0.0737551018", + 0.07375510180078 + ], + [ + 34, + "0.0766677759", + 0.07666777590134 + ], + [ + 35, + "0.0812941534", + 0.08129415338919 + ], + [ + 36, + "0.0816029059", + 0.08160290591493 + ], + [ + 37, + "0.0871032426", + 0.0871032425608 + ], + [ + 38, + "0.0887682015", + 0.08876820145583 + ], + [ + 39, + "0.089252377", + 0.08925237697048 + ], + [ + 40, + "0.0913677868", + 0.09136778679274 + ], + [ + 41, + "0.0925364206", + 0.09253642060446 + ], + [ + 42, + "0.0933360565", + 0.0933360564957 + ], + [ + 43, + "0.0936049917", + 0.09360499172173 + ], + [ + 44, + "0.0967498683", + 0.09674986828898 + ], + [ + 45, + "0.0981378053", + 0.09813780528406 + ], + [ + 46, + "0.104656633", + 0.10465663303837 + ], + [ + 47, + "0.1081672963", + 0.10816729632586 + ], + [ + 48, + "0.1096644709", + 0.10966447093974 + ], + [ + 49, + "0.1156573501", + 0.11565735010227 + ], + [ + 50, + "0.1175322771", + 0.11753227706883 + ], + [ + 51, + "0.1195091284", + 0.11950912844366 + ], + [ + 52, + "0.1197331572", + 0.11973315715777 + ], + [ + 53, + "0.120146513", + 0.12014651304117 + ], + [ + 54, + "0.1212504833", + 0.12125048326386 + ], + [ + 55, + "0.124728859", + 0.12472885899465 + ], + [ + 56, + "0.1259848066", + 0.12598480662609 + ], + [ + 57, + "0.1289282409", + 0.12892824091433 + ], + [ + 58, + "0.1300212565", + 0.13002125645523 + ], + [ + 59, + "0.1303541368", + 0.13035413675492 + ], + [ + 60, + "0.1319413279", + 0.13194132788662 + ], + [ + 61, + "0.1323780209", + 0.13237802085111 + ], + [ + 62, + "0.1379828803", + 0.13798288029524 + ], + [ + 63, + "0.1382724979", + 0.13827249786736 + ], + [ + 64, + "0.1386283367", + 0.13862833666551 + ], + [ + 65, + "0.1415707628", + 0.14157076279705 + ], + [ + 66, + "0.1420672057", + 0.14206720569267 + ], + [ + 67, + "0.1423215792", + 0.14232157922457 + ], + [ + 68, + "0.1439077361", + 0.14390773612256 + ], + [ + 69, + "0.144336483", + 0.14433648304284 + ], + [ + 70, + "0.1449067272", + 0.14490672719893 + ], + [ + 71, + "0.1462393632", + 0.14623936319082 + ], + [ + 72, + "0.1462428794", + 0.14624287939921 + ], + [ + 73, + "0.1529210709", + 0.15292107088161 + ], + [ + 74, + "0.152996922", + 0.15299692198308 + ], + [ + 75, + "0.1537194239", + 0.15371942387601 + ], + [ + 76, + "0.1569773956", + 0.15697739560016 + ], + [ + 77, + "0.1578208316", + 0.15782083159211 + ], + [ + 78, + "0.1670272132", + 0.16702721322282 + ], + [ + 79, + "0.1693538531", + 0.1693538530587 + ], + [ + 80, + "0.1744914386", + 0.17449143863026 + ], + [ + 81, + "0.177699349", + 0.17769934897203 + ], + [ + 82, + "0.1820049724", + 0.18200497244578 + ], + [ + 83, + "0.1826881851", + 0.1826881850989 + ], + [ + 84, + "0.18323942", + 0.18323942002991 + ], + [ + 85, + "0.1852788567", + 0.18527885674744 + ], + [ + 86, + "0.1855629674", + 0.18556296740917 + ], + [ + 87, + "0.1876353227", + 0.18763532265445 + ], + [ + 88, + "0.1892374359", + 0.18923743590211 + ], + [ + 89, + "0.1941492833", + 0.19414928331698 + ], + [ + 90, + "0.1951624854", + 0.19516248544452 + ], + [ + 91, + "0.1962652361", + 0.1962652361003 + ], + [ + 92, + "0.2007414457", + 0.20074144573916 + ], + [ + 93, + "0.2009625971", + 0.20096259713217 + ], + [ + 94, + "0.2012765562", + 0.20127655621677 + ], + [ + 95, + "0.2035595692", + 0.20355956917794 + ], + [ + 96, + "0.2047977723", + 0.20479777232035 + ], + [ + 97, + "0.2058004682", + 0.20580046819793 + ], + [ + 98, + "0.2135380591", + 0.21353805913288 + ], + [ + 99, + "0.2165553161", + 0.21655531610201 + ], + [ + 100, + "0.2211957947", + 0.22119579474497 + ], + [ + 101, + "0.2214682853", + 0.22146828529493 + ], + [ + 102, + "0.2243504483", + 0.22435044833661 + ], + [ + 103, + "0.2248352795", + 0.22483527950236 + ], + [ + 104, + "0.2339701779", + 0.23397017793449 + ], + [ + 105, + "0.2342108727", + 0.23421087266607 + ], + [ + 106, + "0.2345068465", + 0.23450684651476 + ], + [ + 107, + "0.2349950388", + 0.23499503882368 + ], + [ + 108, + "0.2363862056", + 0.23638620564545 + ], + [ + 109, + "0.2381973272", + 0.23819732723673 + ], + [ + 110, + "0.2445727066", + 0.24457270663444 + ], + [ + 111, + "0.2472797596", + 0.24727975961159 + ], + [ + 112, + "0.2474831744", + 0.24748317443182 + ], + [ + 113, + "0.2498985614", + 0.24989856139286 + ], + [ + 114, + "0.2507105862", + 0.25071058620266 + ], + [ + 115, + "0.2527495829", + 0.25274958287028 + ], + [ + 116, + "0.2531839876", + 0.2531839875752 + ], + [ + 117, + "0.2537911871", + 0.25379118707673 + ], + [ + 118, + "0.2559820187", + 0.25598201866074 + ], + [ + 119, + "0.2582184958", + 0.25821849576114 + ], + [ + 120, + "0.2594222428", + 0.25942224276225 + ], + [ + 121, + "0.2611002812", + 0.26110028115152 + ], + [ + 122, + "0.2611194152", + 0.26111941517382 + ], + [ + 123, + "0.2656607904", + 0.26566079038458 + ], + [ + 124, + "0.2672296191", + 0.26722961909474 + ], + [ + 125, + "0.2704750268", + 0.27047502681169 + ], + [ + 126, + "0.2776136004", + 0.2776136003796 + ], + [ + 127, + "0.2794422001", + 0.27944220010165 + ], + [ + 128, + "0.2815401746", + 0.28154017463398 + ], + [ + 129, + "0.282674513", + 0.28267451295753 + ], + [ + 130, + "0.2827376883", + 0.28273768829309 + ], + [ + 131, + "0.2835610128", + 0.28356101283969 + ], + [ + 132, + "0.2836767511", + 0.28367675109006 + ], + [ + 133, + "0.2862014506", + 0.28620145064136 + ], + [ + 134, + "0.2874902935", + 0.28749029351747 + ], + [ + 135, + "0.2921020027", + 0.29210200267476 + ], + [ + 136, + "0.2921788075", + 0.29217880745054 + ], + [ + 137, + "0.2922141674", + 0.2922141674404 + ], + [ + 138, + "0.2959326474", + 0.29593264744427 + ], + [ + 139, + "0.2994232058", + 0.29942320580567 + ], + [ + 140, + "0.3030040531", + 0.30300405309675 + ], + [ + 141, + "0.3072776535", + 0.30727765350941 + ], + [ + 142, + "0.3083657815", + 0.30836578146944 + ], + [ + 143, + "0.3091963638", + 0.30919636381286 + ], + [ + 144, + "0.3103368815", + 0.31033688146171 + ], + [ + 145, + "0.3116543509", + 0.31165435086547 + ], + [ + 146, + "0.3119503438", + 0.31195034380627 + ], + [ + 147, + "0.3125689832", + 0.31256898320865 + ], + [ + 148, + "0.3128095354", + 0.31280953544788 + ], + [ + 149, + "0.3137571762", + 0.31375717619143 + ], + [ + 150, + "0.3141113638", + 0.31411136375465 + ], + [ + 151, + "0.3155595764", + 0.31555957641245 + ], + [ + 152, + "0.3183550259", + 0.31835502587182 + ], + [ + 153, + "0.319197504", + 0.3191975039985 + ], + [ + 154, + "0.3198258208", + 0.31982582077375 + ], + [ + 155, + "0.3202724426", + 0.32027244256822 + ], + [ + 156, + "0.3206662695", + 0.32066626954854 + ], + [ + 157, + "0.3246063573", + 0.32460635729348 + ], + [ + 158, + "0.3265619778", + 0.32656197777323 + ], + [ + 159, + "0.3267726765", + 0.32677267646732 + ], + [ + 160, + "0.3281118005", + 0.32811180051793 + ], + [ + 161, + "0.3300200963", + 0.33002009630669 + ], + [ + 162, + "0.3325596104", + 0.33255961040619 + ], + [ + 163, + "0.3383520904", + 0.338352090371 + ], + [ + 164, + "0.3418517105", + 0.34185171050105 + ], + [ + 165, + "0.3420869644", + 0.34208696444616 + ], + [ + 166, + "0.3429290007", + 0.34292900066027 + ], + [ + 167, + "0.3493668583", + 0.34936685829859 + ], + [ + 168, + "0.3515388879", + 0.3515388878768 + ], + [ + 169, + "0.3564928693", + 0.35649286925629 + ], + [ + 170, + "0.356953426", + 0.35695342596478 + ], + [ + 171, + "0.3581244058", + 0.35812440577807 + ], + [ + 172, + "0.3597661026", + 0.35976610256348 + ], + [ + 173, + "0.35980724", + 0.35980724001294 + ], + [ + 174, + "0.3612681815", + 0.36126818152203 + ], + [ + 175, + "0.361830231", + 0.36183023097078 + ], + [ + 176, + "0.3618709479", + 0.3618709479281 + ], + [ + 177, + "0.3677867113", + 0.36778671125312 + ], + [ + 178, + "0.3682404889", + 0.36824048886459 + ], + [ + 179, + "0.3704071368", + 0.3704071367953 + ], + [ + 180, + "0.3713489284", + 0.37134892836741 + ], + [ + 181, + "0.372728008", + 0.37272800801914 + ], + [ + 182, + "0.3738538126", + 0.37385381263394 + ], + [ + 183, + "0.3744010908", + 0.37440109084099 + ], + [ + 184, + "0.3761253238", + 0.37612532376131 + ], + [ + 185, + "0.3781310042", + 0.37813100422645 + ], + [ + 186, + "0.378220983", + 0.37822098302572 + ], + [ + 187, + "0.3783546949", + 0.37835469487046 + ], + [ + 188, + "0.3805264069", + 0.38052640686767 + ], + [ + 189, + "0.3830738665", + 0.38307386654572 + ], + [ + 190, + "0.383970143", + 0.38397014298661 + ], + [ + 191, + "0.3880386531", + 0.38803865312972 + ], + [ + 192, + "0.3893924595", + 0.38939245948074 + ], + [ + 193, + "0.3899468637", + 0.38994686370247 + ], + [ + 194, + "0.3976062771", + 0.39760627709217 + ], + [ + 195, + "0.4007478316", + 0.4007478316318 + ], + [ + 196, + "0.4041808939", + 0.4041808938627 + ], + [ + 197, + "0.4048613139", + 0.40486131394508 + ], + [ + 198, + "0.4063810457", + 0.40638104565738 + ], + [ + 199, + "0.4085182563", + 0.40851825634414 + ], + [ + 200, + "0.4089814818", + 0.40898148175747 + ], + [ + 201, + "0.4150194705", + 0.41501947046025 + ], + [ + 202, + "0.4162862289", + 0.41628622888414 + ], + [ + 203, + "0.4176403854", + 0.41764038541244 + ], + [ + 204, + "0.4184582934", + 0.41845829338694 + ], + [ + 205, + "0.4225753753", + 0.42257537526198 + ], + [ + 206, + "0.4236965931", + 0.4236965931131 + ], + [ + 207, + "0.4242641187", + 0.42426411873859 + ], + [ + 208, + "0.4249742881", + 0.42497428805798 + ], + [ + 209, + "0.4285296958", + 0.42852969580727 + ], + [ + 210, + "0.4358694048", + 0.43586940478341 + ], + [ + 211, + "0.4378844986", + 0.43788449859148 + ], + [ + 212, + "0.4383217452", + 0.43832174522724 + ], + [ + 213, + "0.4434180783", + 0.443418078331 + ], + [ + 214, + "0.4487700213", + 0.44877002129739 + ], + [ + 215, + "0.4527745622", + 0.45277456215246 + ], + [ + 216, + "0.4540794913", + 0.45407949129775 + ], + [ + 217, + "0.4578205154", + 0.45782051536153 + ], + [ + 218, + "0.4586652529", + 0.45866525287677 + ], + [ + 219, + "0.458775894", + 0.45877589399869 + ], + [ + 220, + "0.4601080424", + 0.46010804244322 + ], + [ + 221, + "0.4610861705", + 0.46108617049692 + ], + [ + 222, + "0.4633602372", + 0.46336023717343 + ], + [ + 223, + "0.4651395569", + 0.46513955689274 + ], + [ + 224, + "0.469918695", + 0.46991869503162 + ], + [ + 225, + "0.4712498465", + 0.47124984649533 + ], + [ + 226, + "0.4743374281", + 0.47433742809777 + ], + [ + 227, + "0.4754464964", + 0.47544649638023 + ], + [ + 228, + "0.475602078", + 0.47560207800734 + ], + [ + 229, + "0.4782178642", + 0.47821786416611 + ], + [ + 230, + "0.479468757", + 0.47946875704427 + ], + [ + 231, + "0.4819296959", + 0.48192969592378 + ], + [ + 232, + "0.4857948518", + 0.48579485178263 + ], + [ + 233, + "0.4860294845", + 0.48602948453558 + ], + [ + 234, + "0.489890096", + 0.48989009600593 + ], + [ + 235, + "0.4920524813", + 0.49205248127321 + ], + [ + 236, + "0.4932398379", + 0.49323983792832 + ], + [ + 237, + "0.4935002562", + 0.4935002562094 + ], + [ + 238, + "0.4964019216", + 0.49640192161146 + ], + [ + 239, + "0.496795092", + 0.49679509200937 + ], + [ + 240, + "0.499331618", + 0.49933161796039 + ], + [ + 241, + "0.5030828875", + 0.50308288750382 + ], + [ + 242, + "0.5033447056", + 0.50334470556273 + ], + [ + 243, + "0.5051939867", + 0.50519398669954 + ], + [ + 244, + "0.5059393726", + 0.50593937258512 + ], + [ + 245, + "0.5070585681", + 0.50705856806927 + ], + [ + 246, + "0.5090773215", + 0.5090773215094 + ], + [ + 247, + "0.5164117192", + 0.51641171915289 + ], + [ + 248, + "0.5166014081", + 0.51660140814101 + ], + [ + 249, + "0.5171571814", + 0.51715718140693 + ], + [ + 250, + "0.5225919325", + 0.52259193245442 + ], + [ + 251, + "0.5261947948", + 0.52619479481419 + ], + [ + 252, + "0.5275636159", + 0.52756361594775 + ], + [ + 253, + "0.5330098092", + 0.5330098092244 + ], + [ + 254, + "0.5344165617", + 0.53441656172946 + ], + [ + 255, + "0.53766182", + 0.53766181996914 + ], + [ + 256, + "0.5385407007", + 0.53854070070131 + ], + [ + 257, + "0.5418435021", + 0.54184350210327 + ], + [ + 258, + "0.5432779065", + 0.54327790650691 + ], + [ + 259, + "0.5446134911", + 0.54461349106608 + ], + [ + 260, + "0.5462143787", + 0.54621437869324 + ], + [ + 261, + "0.5482190571", + 0.54821905705529 + ], + [ + 262, + "0.5503190246", + 0.55031902461793 + ], + [ + 263, + "0.5555936049", + 0.55559360494631 + ], + [ + 264, + "0.5594416352", + 0.55944163518 + ], + [ + 265, + "0.5611671268", + 0.56116712678278 + ], + [ + 266, + "0.5650453091", + 0.56504530905049 + ], + [ + 267, + "0.565516237", + 0.56551623696718 + ], + [ + 268, + "0.5676668196", + 0.56766681958346 + ], + [ + 269, + "0.5678722689", + 0.56787226887786 + ], + [ + 270, + "0.5678896818", + 0.56788968181604 + ], + [ + 271, + "0.5701570546", + 0.57015705461155 + ], + [ + 272, + "0.5702627821", + 0.57026278207556 + ], + [ + 273, + "0.5716964167", + 0.57169641674109 + ], + [ + 274, + "0.5762077442", + 0.57620774422595 + ], + [ + 275, + "0.5822708009", + 0.58227080087283 + ], + [ + 276, + "0.5825441305", + 0.58254413054443 + ], + [ + 277, + "0.5826698898", + 0.5826698898257 + ], + [ + 278, + "0.5848126917", + 0.58481269170754 + ], + [ + 279, + "0.5856470697", + 0.58564706965612 + ], + [ + 280, + "0.5862519981", + 0.58625199812755 + ], + [ + 281, + "0.5863271587", + 0.58632715865332 + ], + [ + 282, + "0.5904919606", + 0.59049196056578 + ], + [ + 283, + "0.5920675856", + 0.59206758560243 + ], + [ + 284, + "0.5937247666", + 0.59372476655697 + ], + [ + 285, + "0.5968111752", + 0.59681117515862 + ], + [ + 286, + "0.6001805093", + 0.60018050931402 + ], + [ + 287, + "0.6050176926", + 0.60501769259805 + ], + [ + 288, + "0.6058371373", + 0.60583713725481 + ], + [ + 289, + "0.6068249189", + 0.60682491893266 + ], + [ + 290, + "0.6099196866", + 0.60991968662008 + ], + [ + 291, + "0.6109455929", + 0.61094559291887 + ], + [ + 292, + "0.6118795865", + 0.61187958652706 + ], + [ + 293, + "0.6124320466", + 0.61243204661292 + ], + [ + 294, + "0.6152676272", + 0.61526762722771 + ], + [ + 295, + "0.6196319371", + 0.61963193706219 + ], + [ + 296, + "0.6207422123", + 0.62074221233871 + ], + [ + 297, + "0.625352654", + 0.62535265396598 + ], + [ + 298, + "0.6261752432", + 0.62617524323341 + ], + [ + 299, + "0.6271740052", + 0.62717400520442 + ], + [ + 300, + "0.6283833318", + 0.62838333175908 + ], + [ + 301, + "0.6293501689", + 0.62935016892354 + ], + [ + 302, + "0.6339364614", + 0.63393646135643 + ], + [ + 303, + "0.6423292927", + 0.64232929267097 + ], + [ + 304, + "0.643764003", + 0.64376400301408 + ], + [ + 305, + "0.6438509126", + 0.6438509126398 + ], + [ + 306, + "0.6461636464", + 0.64616364643264 + ], + [ + 307, + "0.6471605886", + 0.64716058859935 + ], + [ + 308, + "0.6472982353", + 0.64729823528197 + ], + [ + 309, + "0.6481599396", + 0.64815993963189 + ], + [ + 310, + "0.6519840749", + 0.65198407492227 + ], + [ + 311, + "0.6538249178", + 0.65382491781088 + ], + [ + 312, + "0.654417035", + 0.65441703500897 + ], + [ + 313, + "0.6551565023", + 0.65515650233959 + ], + [ + 314, + "0.6580030046", + 0.65800300457421 + ], + [ + 315, + "0.6585909131", + 0.65859091312558 + ], + [ + 316, + "0.6598943354", + 0.65989433539095 + ], + [ + 317, + "0.6628110109", + 0.66281101091895 + ], + [ + 318, + "0.6652203061", + 0.66522030609902 + ], + [ + 319, + "0.6657726218", + 0.66577262182988 + ], + [ + 320, + "0.6672786696", + 0.66727866961959 + ], + [ + 321, + "0.6682578873", + 0.66825788732071 + ], + [ + 322, + "0.6706138443", + 0.67061384425992 + ], + [ + 323, + "0.6728389774", + 0.6728389773857 + ], + [ + 324, + "0.6738104656", + 0.6738104655751 + ], + [ + 325, + "0.6739414286", + 0.67394142862127 + ], + [ + 326, + "0.6789427873", + 0.67894278731147 + ], + [ + 327, + "0.6792435556", + 0.67924355560878 + ], + [ + 328, + "0.6839609233", + 0.68396092331221 + ], + [ + 329, + "0.6843712538", + 0.68437125379423 + ], + [ + 330, + "0.686917588", + 0.68691758796894 + ], + [ + 331, + "0.6886296313", + 0.68862963127374 + ], + [ + 332, + "0.6897600837", + 0.68976008365385 + ], + [ + 333, + "0.6902719348", + 0.6902719348158 + ], + [ + 334, + "0.6965584935", + 0.69655849351387 + ], + [ + 335, + "0.6982833937", + 0.69828339372681 + ], + [ + 336, + "0.6993319917", + 0.69933199170014 + ], + [ + 337, + "0.7005978272", + 0.70059782718336 + ], + [ + 338, + "0.7030775499", + 0.70307754990788 + ], + [ + 339, + "0.7083388677", + 0.70833886773713 + ], + [ + 340, + "0.7095440625", + 0.70954406247918 + ], + [ + 341, + "0.7128569939", + 0.71285699387679 + ], + [ + 342, + "0.7129457475", + 0.71294574752121 + ], + [ + 343, + "0.7148045514", + 0.71480455143135 + ], + [ + 344, + "0.7163206705", + 0.71632067054338 + ], + [ + 345, + "0.7194143854", + 0.71941438537063 + ], + [ + 346, + "0.7206447743", + 0.72064477425098 + ], + [ + 347, + "0.7221357979", + 0.72213579794491 + ], + [ + 348, + "0.7237609353", + 0.72376093534927 + ], + [ + 349, + "0.7239382587", + 0.7239382587019 + ], + [ + 350, + "0.7243118704", + 0.72431187039441 + ], + [ + 351, + "0.726473275", + 0.72647327497902 + ], + [ + 352, + "0.7296714185", + 0.72967141854095 + ], + [ + 353, + "0.7351543967", + 0.73515439673101 + ], + [ + 354, + "0.7355358548", + 0.73553585481622 + ], + [ + 355, + "0.7421012711", + 0.74210127105102 + ], + [ + 356, + "0.7431389316", + 0.74313893157203 + ], + [ + 357, + "0.7439721426", + 0.74397214257343 + ], + [ + 358, + "0.745112982", + 0.74511298199422 + ], + [ + 359, + "0.7457633935", + 0.74576339346625 + ], + [ + 360, + "0.7471672286", + 0.74716722860334 + ], + [ + 361, + "0.7481874147", + 0.74818741471887 + ], + [ + 362, + "0.7482518003", + 0.74825180030812 + ], + [ + 363, + "0.7485077012", + 0.74850770120905 + ], + [ + 364, + "0.7505016126", + 0.75050161255081 + ], + [ + 365, + "0.7530099637", + 0.75300996366562 + ], + [ + 366, + "0.754795242", + 0.75479524198677 + ], + [ + 367, + "0.7557260197", + 0.75572601973811 + ], + [ + 368, + "0.7562984739", + 0.75629847392267 + ], + [ + 369, + "0.7598333898", + 0.75983338978133 + ], + [ + 370, + "0.7600311771", + 0.7600311770849 + ], + [ + 371, + "0.7601212798", + 0.76012127975007 + ], + [ + 372, + "0.7640370269", + 0.76403702691385 + ], + [ + 373, + "0.7656979653", + 0.76569796528932 + ], + [ + 374, + "0.7679536002", + 0.76795360016075 + ], + [ + 375, + "0.7680506472", + 0.7680506472327 + ], + [ + 376, + "0.7683535613", + 0.76835356129722 + ], + [ + 377, + "0.7695589502", + 0.76955895022002 + ], + [ + 378, + "0.7719003185", + 0.77190031845676 + ], + [ + 379, + "0.7721947607", + 0.77219476074548 + ], + [ + 380, + "0.7730772094", + 0.77307720937443 + ], + [ + 381, + "0.7781522706", + 0.77815227060492 + ], + [ + 382, + "0.7822206192", + 0.78222061916357 + ], + [ + 383, + "0.7828206866", + 0.78282068659682 + ], + [ + 384, + "0.7894097486", + 0.78940974864615 + ], + [ + 385, + "0.789710713", + 0.78971071298686 + ], + [ + 386, + "0.7914886022", + 0.79148860219469 + ], + [ + 387, + "0.7948410128", + 0.79484101282192 + ], + [ + 388, + "0.8025113385", + 0.80251133851823 + ], + [ + 389, + "0.807042594", + 0.80704259397789 + ], + [ + 390, + "0.8079456518", + 0.80794565184411 + ], + [ + 391, + "0.8089167535", + 0.80891675353465 + ], + [ + 392, + "0.8097375109", + 0.80973751089057 + ], + [ + 393, + "0.8114332509", + 0.81143325092803 + ], + [ + 394, + "0.8127308357", + 0.81273083566349 + ], + [ + 395, + "0.8143003941", + 0.81430039406488 + ], + [ + 396, + "0.8183699259", + 0.81836992586886 + ], + [ + 397, + "0.8183761732", + 0.8183761731807 + ], + [ + 398, + "0.8191833593", + 0.81918335930406 + ], + [ + 399, + "0.8277966272", + 0.82779662722153 + ], + [ + 400, + "0.8281171298", + 0.82811712977854 + ], + [ + 401, + "0.8300228849", + 0.83002288491931 + ], + [ + 402, + "0.8319003712", + 0.83190037116031 + ], + [ + 403, + "0.8335338011", + 0.83353380106088 + ], + [ + 404, + "0.8382751536", + 0.83827515358025 + ], + [ + 405, + "0.8427027133", + 0.84270271325609 + ], + [ + 406, + "0.8444202141", + 0.84442021411118 + ], + [ + 407, + "0.8452174369", + 0.84521743694563 + ], + [ + 408, + "0.8468697895", + 0.84686978945828 + ], + [ + 409, + "0.8484499486", + 0.84844994863888 + ], + [ + 410, + "0.8530562175", + 0.85305621747535 + ], + [ + 411, + "0.8552265628", + 0.85522656275668 + ], + [ + 412, + "0.8554183398", + 0.85541833977001 + ], + [ + 413, + "0.8557945787", + 0.85579457872351 + ], + [ + 414, + "0.8560648569", + 0.85606485691669 + ], + [ + 415, + "0.8575603132", + 0.85756031324042 + ], + [ + 416, + "0.8575992262", + 0.85759922622591 + ], + [ + 417, + "0.8619446959", + 0.86194469587036 + ], + [ + 418, + "0.862746885", + 0.86274688498244 + ], + [ + 419, + "0.8637428497", + 0.86374284972611 + ], + [ + 420, + "0.8638405962", + 0.86384059622131 + ], + [ + 421, + "0.8667194014", + 0.86671940137945 + ], + [ + 422, + "0.8693330497", + 0.86933304968724 + ], + [ + 423, + "0.8706746715", + 0.870674671545 + ], + [ + 424, + "0.8726787776", + 0.87267877760933 + ], + [ + 425, + "0.8727606055", + 0.87276060547342 + ], + [ + 426, + "0.8727652737", + 0.87276527372783 + ], + [ + 427, + "0.8740768828", + 0.87407688278429 + ], + [ + 428, + "0.8801450408", + 0.88014504075057 + ], + [ + 429, + "0.8845914518", + 0.88459145179232 + ], + [ + 430, + "0.8846158562", + 0.88461585616907 + ], + [ + 431, + "0.8870095545", + 0.88700955448998 + ], + [ + 432, + "0.8874592939", + 0.88745929388676 + ], + [ + 433, + "0.8890389995", + 0.88903899951327 + ], + [ + 434, + "0.8911287784", + 0.89112877840694 + ], + [ + 435, + "0.892701324", + 0.89270132402549 + ], + [ + 436, + "0.893638656", + 0.89363865595946 + ], + [ + 437, + "0.8939921334", + 0.89399213338922 + ], + [ + 438, + "0.9002775321", + 0.90027753212502 + ], + [ + 439, + "0.9019281095", + 0.90192810953684 + ], + [ + 440, + "0.9037487516", + 0.90374875157314 + ], + [ + 441, + "0.9047026345", + 0.90470263450625 + ], + [ + 442, + "0.9050359586", + 0.90503595858115 + ], + [ + 443, + "0.9053011983", + 0.9053011983192 + ], + [ + 444, + "0.9054982611", + 0.90549826105381 + ], + [ + 445, + "0.9057884239", + 0.90578842391529 + ], + [ + 446, + "0.9078596592", + 0.90785965924517 + ], + [ + 447, + "0.9101276025", + 0.91012760247575 + ], + [ + 448, + "0.9110809797", + 0.9110809797007 + ], + [ + 449, + "0.9136646748", + 0.91366467481184 + ], + [ + 450, + "0.9159638099", + 0.9159638098981 + ], + [ + 451, + "0.9166537476", + 0.91665374763154 + ], + [ + 452, + "0.9186017285", + 0.9186017284722 + ], + [ + 453, + "0.919220488", + 0.91922048801519 + ], + [ + 454, + "0.9212328652", + 0.92123286515531 + ], + [ + 455, + "0.9217749945", + 0.92177499454551 + ], + [ + 456, + "0.9218236827", + 0.92182368269275 + ], + [ + 457, + "0.9225795371", + 0.92257953710974 + ], + [ + 458, + "0.923005158", + 0.92300515804579 + ], + [ + 459, + "0.9295114483", + 0.9295114483356 + ], + [ + 460, + "0.9334455854", + 0.93344558539495 + ], + [ + 461, + "0.9337331415", + 0.93373314148454 + ], + [ + 462, + "0.9358259239", + 0.93582592389351 + ], + [ + 463, + "0.9380399426", + 0.93803994261568 + ], + [ + 464, + "0.9392540212", + 0.93925402124377 + ], + [ + 465, + "0.9408260081", + 0.94082600806878 + ], + [ + 466, + "0.9412178755", + 0.94121787554641 + ], + [ + 467, + "0.9421049645", + 0.94210496449009 + ], + [ + 468, + "0.9443434551", + 0.9443434551099 + ], + [ + 469, + "0.947649973", + 0.9476499729546 + ], + [ + 470, + "0.9494116972", + 0.9494116971965 + ], + [ + 471, + "0.9497451694", + 0.94974516935169 + ], + [ + 472, + "0.9517337316", + 0.95173373164224 + ], + [ + 473, + "0.9577067233", + 0.95770672334251 + ], + [ + 474, + "0.9624094944", + 0.96240949442722 + ], + [ + 475, + "0.9642330622", + 0.96423306221339 + ], + [ + 476, + "0.9677599529", + 0.96775995286542 + ], + [ + 477, + "0.9683029465", + 0.96830294652297 + ], + [ + 478, + "0.9700463307", + 0.97004633069506 + ], + [ + 479, + "0.9729755972", + 0.97297559723862 + ], + [ + 480, + "0.9743401203", + 0.9743401203185 + ], + [ + 481, + "0.977525881", + 0.97752588101547 + ], + [ + 482, + "0.9788602395", + 0.97886023948847 + ], + [ + 483, + "0.9829722652", + 0.98297226521324 + ], + [ + 484, + "0.9838584969", + 0.9838584968745 + ], + [ + 485, + "0.986392145", + 0.98639214503876 + ], + [ + 486, + "0.9886501227", + 0.98865012265213 + ], + [ + 487, + "0.9908347088", + 0.99083470878695 + ], + [ + 488, + "0.9918390666", + 0.99183906660966 + ], + [ + 489, + "0.9933680082", + 0.99336800817091 + ], + [ + 490, + "0.9935915098", + 0.99359150975644 + ], + [ + 491, + "0.9990555178", + 0.99905551783696 + ], + [ + 492, + "1613.001", + 1613.001 + ], + [ + 493, + "1613.0011235", + 1613.001123456 + ], + [ + 494, + "42", + 42 + ] +] +, "dynamic_extended_values": +[ + [ + null, + "", + "", + "", + null, + "", + null + ] +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/getdynamiccolvals" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD815F932A6E9840B6ED0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T11:51:41.486000" +,"MEMSIZE" : "93GB" +} +` diff --git a/sas/mocks/sas9/sasjs/services/editors/getsubmits.js b/sas/mocks/sas9/sasjs/services/editors/getsubmits.js new file mode 100644 index 0000000..5200367 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/editors/getsubmits.js @@ -0,0 +1,28 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:46" +, "fromsas": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/getsubmits" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80579E87CED940AC8C0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:46:50.549000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/editors/loadfile.js b/sas/mocks/sas9/sasjs/services/editors/loadfile.js new file mode 100644 index 0000000..3486d17 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/editors/loadfile.js @@ -0,0 +1,32 @@ +_webout=`{"SYSDATE" : "29SEP22" +,"SYSTIME" : "11:57" +, "sasparams": +[ + { + "STATUS": "SUCCESS", + "DSID": "DC20220929T115713486_609542_1443" + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/loadfile" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD815FE643C6A840C0278000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T11:57:14.118000" +,"MEMSIZE" : "93GB" +} +` diff --git a/sas/mocks/sas9/sasjs/services/editors/stagedata.js b/sas/mocks/sas9/sasjs/services/editors/stagedata.js new file mode 100644 index 0000000..5397eb3 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/editors/stagedata.js @@ -0,0 +1,32 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "sasparams": +[ +{ +"STATUS": "SUCCESS", +"DSID": "DC20220926T084322234_729360_2744", +"URL": "http://SAS.demo.sas.com:80/SASStoredProcess?_program=/Projects/app/dc/services/editors/getlog&table=DC20220926T084322234_729360_2744" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/stagedata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576A63958140A31C0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:24.624000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/lineage/backup/fetchcollineage.js b/sas/mocks/sas9/sasjs/services/lineage/backup/fetchcollineage.js new file mode 100644 index 0000000..c5f5a8f --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/backup/fetchcollineage.js @@ -0,0 +1,57 @@ +_webout=`{"SYSDATE" : "29MAR23" +,"SYSTIME" : "08:33" +, "fromsas": +[ + { + "STRING": "digraph G { concentrate=true; node [style=filled,shape=plain]; labelloc = \\"t\\";" + }, + { + "STRING": "label=<
REVERSE Lineage for COUNTRY_NM
Library:
Digital Generated by:sasdemo
Table:DIGITAL_ACTIVITY_PATH_ANALYSIS Generated on: 29MAR2023:08:33:42
>" + }, + { + "STRING": "x [label=\\"No lineage found\\" shape=Mdiamond]}" + } +] +, "clickableids": +[ + +] +, "info": +[ + { + "COLURI": "", + "COLNAME": "COUNTRY_NM", + "TABURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR00001O", + "TABNAME": "DIGITAL_ACTIVITY_PATH_ANALYSIS", + "LIBURI": "OMSOBJ:SASLibrary\A59LNVZG.B500000E", + "LIBREF": "Digital", + "RC": 0 + } +] +, "flatdata": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS-AAP" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc2/services/lineage/fetchcollineage" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS-AAP" +,"SYSPROCESSID" : "41DDBCFBD96EE979408F300000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25672" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "70068130" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M8P011823" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2023-03-29T08:33:42.390000" +,"MEMSIZE" : "44GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sas9/sasjs/services/lineage/backup/fetchtablelineage.js b/sas/mocks/sas9/sasjs/services/lineage/backup/fetchtablelineage.js new file mode 100644 index 0000000..466294d --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/backup/fetchtablelineage.js @@ -0,0 +1,45 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:54" +, "finalfinal": +[ + +] +, "info": +[ +{ +"TABLEID": "A59LNVZG.BR00002J", +"TABLENAME": "MPE_DATALOADS", +"LIBURI": "OMSOBJ:SASLibrary\A59LNVZG.B500000K", +"LIBREF": "DC996664" +} +] +, "flatdata": +[ + +] +, "idlookup": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/fetchtablelineage" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD805811AA4DD340C4BD8000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:54:31.395000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/lineage/fetchcollineage.js b/sas/mocks/sas9/sasjs/services/lineage/fetchcollineage.js new file mode 100644 index 0000000..20e4523 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/fetchcollineage.js @@ -0,0 +1,57 @@ +_webout=`{"SYSDATE" : "29MAR23" +,"SYSTIME" : "09:26" +, "fromsas": +[ + { + "STRING": "digraph G { concentrate=true; node [style=filled,shape=plain]; labelloc = \\"t\\";" + }, + { + "STRING": "label=<
REVERSE Lineage for duration
Library:
Generated by:sasdemo
Table:WEBTEST4 Generated on: 29MAR2023:09:26:26
>" + }, + { + "STRING": "x [label=\\"No lineage found\\" shape=Mdiamond]}" + } +] +, "clickableids": +[ + +] +, "info": +[ + { + "COLURI": "", + "COLNAME": "duration", + "TABURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR000024", + "TABNAME": "WEBTEST4", + "LIBURI": "OMSOBJ:DatabaseSchema\A59LNVZG.BJ000001", + "LIBREF": "", + "RC": -2 + } +] +, "flatdata": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS-AAP" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc2/services/lineage/fetchcollineage" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS-AAP" +,"SYSPROCESSID" : "41DDBCFEF06F1AA040AA980000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25672" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "70068130" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M8P011823" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2023-03-29T09:26:26.387000" +,"MEMSIZE" : "44GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sas9/sasjs/services/lineage/fetchlineage.js b/sas/mocks/sas9/sasjs/services/lineage/fetchlineage.js new file mode 100644 index 0000000..342e4db --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/fetchlineage.js @@ -0,0 +1,73 @@ +_webout=`{ +"SYSDATE" : "26SEP22" +, "SYSTIME" : "08:54" +, "fromsas": +[ +{ +"STRING": "digraph G { concentrate=true; node [style=filled,shape=plain]; labelloc = \\"t\\";" +}, +{ +"STRING": "label=< +< tr > + + + + + + + + + + + + + + +
REVERSE Lineage for changed_records
Library:
DC996664Generated by:sasdemo
Table:MPE_DATALOADSGenerated on: 26SEP2022:08:54:38
> " +}, +{ +"STRING": "x [label=\\"No lineage found\\" shape=Mdiamond]}" +} +] +, "clickableids": +[ + +] +, "info": +[ +{ +"COLURI": "", +"COLNAME": "changed_records", +"TABURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR00002J", +"TABNAME": "MPE_DATALOADS", +"LIBURI": "OMSOBJ:SASLibrary\A59LNVZG.B500000K", +"LIBREF": "DC996664", +"RC": 0 +} +] +, "flatdata": +[ + +] +, "_DEBUG" : "" +, "_METAUSER": "sasdemo@SAS" +, "_METAPERSON": "sasdemo" +, "_PROGRAM" : "/Projects/app/dc/services/lineage/fetchcollineage" +, "AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +, "MF_GETUSER" : "sasdemo" +, "SYSCC" : "0" +, "SYSENCODING" : "wlatin1" +, "SYSERRORTEXT" : "" +, "SYSHOSTNAME" : "SAS" +, "SYSPROCESSID" : "41DD8058137FCED940C5250000000000" +, "SYSPROCESSMODE" : "SAS Stored Process Server" +, "SYSPROCESSNAME" : "" +, "SYSJOBID" : "27448" +, "SYSSCPL" : "X64_DSRV16" +, "SYSSITE" : "123" +, "SYSUSERID" : "sassrv" +, "SYSVLONG" : "9.04.01M7P080520" +, "SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +, "END_DTTM" : "2022-09-26T08:54:39.013000" +, "MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/lineage/fetchtablelineage.js b/sas/mocks/sas9/sasjs/services/lineage/fetchtablelineage.js new file mode 100644 index 0000000..c1d75e1 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/fetchtablelineage.js @@ -0,0 +1,121 @@ +_webout=`{"SYSDATE" : "29MAR23" +,"SYSTIME" : "09:26" +, "finalfinal": +[ + { + "LINE": "strict digraph \\"nolib.WEBTEST4\\" {" + }, + { + "LINE": "rankdir=LR; nodesep=0.5; node [shape = octagon];" + }, + { + "LINE": "subgraph cluster_libs { label=\\"Libraries\\";" + }, + { + "LINE": "SANKEY [label=\\"SANKEY\\"; style=\\"filled\\"; color=\\"#e6194b\\", shape = Mrecord, fontcolor=white]" + }, + { + "LINE": "nolib [label=\\"nolib\\"; style=\\"filled\\"; color=\\"#3cb44b\\", shape = Mrecord, fontcolor=white]" + }, + { + "LINE": "}" + }, + { + "LINE": "\\"A59LNVZG.BR000023\\" [label=\\"WEBTEST4\\", color=\\"#e6194b\\", shape=cylinder,style=filled,fontcolor=white];" + }, + { + "LINE": "\\"A59LNVZG.BR000024\\" [label=\\"WEBTEST4\\", color=\\"#3cb44b\\", shape=cylinder,style=filled,fontcolor=white];" + }, + { + "LINE": "\\"A59LNVZG.BX00000E\\" [label=\\"WEBTEST4 - LOAD JOB 0109151127AM\\"];" + }, + { + "LINE": "\\"A59LNVZG.BR000023\\" -> \\"A59LNVZG.BX00000E\\" [color=\\"#e6194b\\"];" + }, + { + "LINE": "\\"A59LNVZG.BR000024\\" -> \\"A59LNVZG.BX00000E\\" [color=\\"#3cb44b\\"];" + }, + { + "LINE": "\\"A59LNVZG.BX00000E\\" -> \\"A59LNVZG.BR000024\\" [color=\\"#3cb44b\\"];" + }, + { + "LINE": "}" + } +] +, "info": +[ + { + "TABLEID": "A59LNVZG.BR000024", + "TABLENAME": "WEBTEST4", + "LIBURI": "OMSOBJ:DatabaseSchema\A59LNVZG.BJ000001", + "LIBREF": "nolib" + } +] +, "flatdata": +[ + { + "JOBID": "A59LNVZG.BX00000E", + "SRCTABLEID": "A59LNVZG.BR000023", + "TGTTABLEID": "A59LNVZG.BR000024", + "JOBNAME": "WEBTEST4 - LOAD JOB 0109151127AM", + "SRCTABLETYPE": "PhysicalTable", + "SRCTABLENAME": "WEBTEST4", + "SRCLIBREF": "SANKEY", + "TGTTABLETYPE": "PhysicalTable", + "TGTTABLENAME": "WEBTEST4", + "TGTLIBREF": "nolib" + }, + { + "JOBID": "A59LNVZG.BX00000E", + "SRCTABLEID": "A59LNVZG.BR000024", + "TGTTABLEID": "A59LNVZG.BR000024", + "JOBNAME": "WEBTEST4 - LOAD JOB 0109151127AM", + "SRCTABLETYPE": "PhysicalTable", + "SRCTABLENAME": "WEBTEST4", + "SRCLIBREF": "nolib", + "TGTTABLETYPE": "PhysicalTable", + "TGTTABLENAME": "WEBTEST4", + "TGTLIBREF": "nolib" + } +] +, "idlookup": +[ + { + "METAID": "A59LNVZG.BR000023", + "METATYPE": "TABLE", + "METANAME": "SANKEY.WEBTEST4" + }, + { + "METAID": "A59LNVZG.BR000024", + "METATYPE": "TABLE", + "METANAME": "nolib.WEBTEST4" + }, + { + "METAID": "A59LNVZG.BX00000E", + "METATYPE": "JOB", + "METANAME": "WEBTEST4 - LOAD JOB 0109151127AM" + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS-AAP" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc2/services/lineage/fetchtablelineage" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS-AAP" +,"SYSPROCESSID" : "41DDBCFEEF35C28F40A7840000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25672" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "70068130" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M8P011823" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2023-03-29T09:26:22.584000" +,"MEMSIZE" : "44GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sas9/sasjs/services/lineage/getmetacols.js b/sas/mocks/sas9/sasjs/services/lineage/getmetacols.js new file mode 100644 index 0000000..1725146 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/getmetacols.js @@ -0,0 +1,82 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:54" +, "metacols": +[ +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L8", +"COLNAME": "changed_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LA", +"COLNAME": "deleted_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L5", +"COLNAME": "dsn", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LB", +"COLNAME": "duration", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L6", +"COLNAME": "etlsource", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L4", +"COLNAME": "libref", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L7", +"COLNAME": "loadtype", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LE", +"COLNAME": "mac_ver", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L9", +"COLNAME": "new_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LD", +"COLNAME": "processed_dttm", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LC", +"COLNAME": "user_nm", +"COLDESC": "" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/getmetacols" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8058115E041940C4910000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:54:29.833000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/lineage/getmetatables.js b/sas/mocks/sas9/sasjs/services/lineage/getmetatables.js new file mode 100644 index 0000000..2d4ca3a --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/lineage/getmetatables.js @@ -0,0 +1,41 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:53" +, "metatables": +[ +{ +"LIBNAME": "Sankey", +"SERVERCONTEXT": "SASApp", +"AUTHDOMAIN": "", +"PATH_SCHEMA": "D:\MyDemo\Sankey", +"TABLEURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR000023", +"ID": "A59LNVZG.B600000M", +"LIBDESC": "", +"LIBREF": "sankey", +"ENGINE": "BASE", +"ISDBMSLIBNAME": "0", +"ISPREASSIGNED": "0", +"TABLENAME": "WEBTEST4" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/getmetatables" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8058084D916840C4690000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:53:53.567000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/metanav/metadetails.js b/sas/mocks/sas9/sasjs/services/metanav/metadetails.js new file mode 100644 index 0000000..e47f7d4 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/metanav/metadetails.js @@ -0,0 +1,100 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "attributes": +[ +{ +"TYPE": "Attr", +"NAME": "ChangeState", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "Desc", +"VALUE": "Input Stream." +}, +{ +"TYPE": "Attr", +"NAME": "Id", +"VALUE": "A59LNVZG.BW000001" +}, +{ +"TYPE": "Attr", +"NAME": "IsHidden", +"VALUE": "0" +}, +{ +"TYPE": "Attr", +"NAME": "LockedBy", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "MetadataCreated", +"VALUE": "19Aug2020:11:12:46" +}, +{ +"TYPE": "Attr", +"NAME": "MetadataUpdated", +"VALUE": "19Aug2020:11:12:46" +}, +{ +"TYPE": "Attr", +"NAME": "Name", +"VALUE": "instream" +}, +{ +"TYPE": "Attr", +"NAME": "Protocol", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "PublicType", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "UsageVersion", +"VALUE": "0" +}, +{ +"TYPE": "Prop", +"NAME": "MultiPass", +"VALUE": "1" +} +] +, "associations": +[ +{ +"ASSOC": "Properties", +"ASSOCURI": "OMSOBJ:Property\A59LNVZG.AC0003EG", +"NAME": "MultiPass" +}, +{ +"ASSOC": "Reports", +"ASSOCURI": "OMSOBJ:Report\A59LNVZG.BV000001", +"NAME": "instream" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metadetails" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D94B645A40C1608000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:45.706000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/metanav/metaobjects.js b/sas/mocks/sas9/sasjs/services/metanav/metaobjects.js new file mode 100644 index 0000000..654734a --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/metanav/metaobjects.js @@ -0,0 +1,31 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "objects": +[ +{ +"ID": "A59LNVZG.BW000001", +"NAME": "instream" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metaobjects" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D89978D540C1368000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:42.814000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/metanav/metarepos.js b/sas/mocks/sas9/sasjs/services/metanav/metarepos.js new file mode 100644 index 0000000..d52b95d --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/metanav/metarepos.js @@ -0,0 +1,35 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "outrepos": +[ +{ +"ID": "A0000001.A573PBI4", +"NAME": "BILineage" +}, +{ +"ID": "A0000001.A59LNVZG", +"NAME": "Foundation" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metarepos" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "4" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D3E04189409F380000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "21468" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:23.895000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/metanav/metatypes.js b/sas/mocks/sas9/sasjs/services/metanav/metatypes.js new file mode 100644 index 0000000..4ef7868 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/metanav/metatypes.js @@ -0,0 +1,382 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "types": +[ +{ +"ID": "AccessControlEntry", +"DESC": "Access control entry", +"HASSUBTYPES": "0" +}, +{ +"ID": "AccessControlTemplate", +"DESC": "Access control template", +"HASSUBTYPES": "0" +}, +{ +"ID": "Action", +"DESC": "Action", +"HASSUBTYPES": "0" +}, +{ +"ID": "AnalyticContext", +"DESC": "Analytic context", +"HASSUBTYPES": "0" +}, +{ +"ID": "ApplicationAction", +"DESC": "Application action", +"HASSUBTYPES": "0" +}, +{ +"ID": "AssociationProperty", +"DESC": "Association property", +"HASSUBTYPES": "0" +}, +{ +"ID": "AttributeProperty", +"DESC": "Attribute property", +"HASSUBTYPES": "0" +}, +{ +"ID": "AuthenticationDomain", +"DESC": "Authentication domain", +"HASSUBTYPES": "0" +}, +{ +"ID": "ClassifierMap", +"DESC": "Classifier map", +"HASSUBTYPES": "1" +}, +{ +"ID": "Column", +"DESC": "Column", +"HASSUBTYPES": "1" +}, +{ +"ID": "Condition", +"DESC": "Condition", +"HASSUBTYPES": "0" +}, +{ +"ID": "ConditionActionSet", +"DESC": "Condition action set", +"HASSUBTYPES": "0" +}, +{ +"ID": "ConfiguredComponent", +"DESC": "Configured component", +"HASSUBTYPES": "1" +}, +{ +"ID": "CustomAssociation", +"DESC": "Custom association", +"HASSUBTYPES": "0" +}, +{ +"ID": "DatabaseCatalog", +"DESC": "Database catalog", +"HASSUBTYPES": "0" +}, +{ +"ID": "DatabaseSchema", +"DESC": "Database schema", +"HASSUBTYPES": "0" +}, +{ +"ID": "DeployedComponent", +"DESC": "Deployed component", +"HASSUBTYPES": "1" +}, +{ +"ID": "Directory", +"DESC": "Directory", +"HASSUBTYPES": "1" +}, +{ +"ID": "Document", +"DESC": "Document", +"HASSUBTYPES": "0" +}, +{ +"ID": "Extension", +"DESC": "Extension", +"HASSUBTYPES": "0" +}, +{ +"ID": "ExternalIdentity", +"DESC": "External identity", +"HASSUBTYPES": "0" +}, +{ +"ID": "FavoritesContainer", +"DESC": "Favorites container", +"HASSUBTYPES": "0" +}, +{ +"ID": "File", +"DESC": "File", +"HASSUBTYPES": "1" +}, +{ +"ID": "Group", +"DESC": "Group", +"HASSUBTYPES": "1" +}, +{ +"ID": "ITChannel", +"DESC": "IT channel", +"HASSUBTYPES": "0" +}, +{ +"ID": "IdentityGroup", +"DESC": "Identity group", +"HASSUBTYPES": "0" +}, +{ +"ID": "Index", +"DESC": "Index", +"HASSUBTYPES": "0" +}, +{ +"ID": "InternalLogin", +"DESC": "Internal login", +"HASSUBTYPES": "0" +}, +{ +"ID": "Job", +"DESC": "Job", +"HASSUBTYPES": "0" +}, +{ +"ID": "Keyword", +"DESC": "Keyword", +"HASSUBTYPES": "0" +}, +{ +"ID": "LogicalServer", +"DESC": "Logical server", +"HASSUBTYPES": "0" +}, +{ +"ID": "Login", +"DESC": "Login", +"HASSUBTYPES": "0" +}, +{ +"ID": "Machine", +"DESC": "Machine", +"HASSUBTYPES": "0" +}, +{ +"ID": "NamedService", +"DESC": "Named service", +"HASSUBTYPES": "0" +}, +{ +"ID": "OLAPSchema", +"DESC": "OLAP schema", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSColumnLayoutComponent", +"DESC": "PS column layout component", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSPortalPage", +"DESC": "PS portal page", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSPortlet", +"DESC": "PS portlet", +"HASSUBTYPES": "0" +}, +{ +"ID": "Permission", +"DESC": "Permission", +"HASSUBTYPES": "0" +}, +{ +"ID": "Person", +"DESC": "People", +"HASSUBTYPES": "0" +}, +{ +"ID": "PhysicalTable", +"DESC": "Physical table", +"HASSUBTYPES": "1" +}, +{ +"ID": "Prompt", +"DESC": "Prompt", +"HASSUBTYPES": "0" +}, +{ +"ID": "PromptGroup", +"DESC": "Prompt group", +"HASSUBTYPES": "0" +}, +{ +"ID": "Property", +"DESC": "Property", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertyGroup", +"DESC": "Property group", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertySet", +"DESC": "Property set", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertyType", +"DESC": "Property type", +"HASSUBTYPES": "0" +}, +{ +"ID": "Prototype", +"DESC": "Prototype", +"HASSUBTYPES": "0" +}, +{ +"ID": "Report", +"DESC": "Report", +"HASSUBTYPES": "0" +}, +{ +"ID": "ResponsibleParty", +"DESC": "Responsible party", +"HASSUBTYPES": "0" +}, +{ +"ID": "SASClientConnection", +"DESC": "SAS client connection", +"HASSUBTYPES": "0" +}, +{ +"ID": "SASLibrary", +"DESC": "SAS library", +"HASSUBTYPES": "1" +}, +{ +"ID": "SASPassword", +"DESC": "SAS password", +"HASSUBTYPES": "0" +}, +{ +"ID": "Search", +"DESC": "Search", +"HASSUBTYPES": "0" +}, +{ +"ID": "SecurityRuleScheme", +"DESC": "Security rule scheme", +"HASSUBTYPES": "0" +}, +{ +"ID": "SecurityTypeContainmentRule", +"DESC": "Security type containment rule", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServerComponent", +"DESC": "Server component", +"HASSUBTYPES": "1" +}, +{ +"ID": "ServerContext", +"DESC": "Server context", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServiceComponent", +"DESC": "Service component", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServiceType", +"DESC": "Service type", +"HASSUBTYPES": "0" +}, +{ +"ID": "SoftwareComponent", +"DESC": "Software component", +"HASSUBTYPES": "1" +}, +{ +"ID": "Stream", +"DESC": "Stream", +"HASSUBTYPES": "0" +}, +{ +"ID": "TCPIPConnection", +"DESC": "TCPIP connection", +"HASSUBTYPES": "0" +}, +{ +"ID": "TextStore", +"DESC": "Text store", +"HASSUBTYPES": "0" +}, +{ +"ID": "Timestamp", +"DESC": "Timestamp", +"HASSUBTYPES": "0" +}, +{ +"ID": "Transformation", +"DESC": "Transformation", +"HASSUBTYPES": "1" +}, +{ +"ID": "TransformationActivity", +"DESC": "Transformation activity", +"HASSUBTYPES": "0" +}, +{ +"ID": "TransformationStep", +"DESC": "Transformation step", +"HASSUBTYPES": "1" +}, +{ +"ID": "Tree", +"DESC": "Metadata Trees", +"HASSUBTYPES": "0" +}, +{ +"ID": "TypeDefinition", +"DESC": "Type definition", +"HASSUBTYPES": "0" +}, +{ +"ID": "UniqueKey", +"DESC": "Unique key", +"HASSUBTYPES": "0" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metatypes" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D3E020C540C10F8000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:23.928000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/getchangeinfo.js b/sas/mocks/sas9/sasjs/services/public/getchangeinfo.js new file mode 100644 index 0000000..e773643 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/getchangeinfo.js @@ -0,0 +1,47 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "jsparams": +[ +{ +"TABLE_ID": "DC20220926T084322234_729360_2744", +"SUBMIT_STATUS_CD": "SUBMITTED", +"BASE_LIB": "DC996664", +"BASE_DS": "MPE_X_TEST", +"SUBMITTED_BY_NM": "sasdemo", +"SUBMITTED_ON": "26SEP22:08:43:22.38", +"SUBMITTED_REASON_TXT": "", +"INPUT_OBS": 1, +"INPUT_VARS": 10, +"NUM_OF_APPROVALS_REQUIRED": 1, +"NUM_OF_APPROVALS_REMAINING": 1, +"REVIEWED_BY_NM": "", +"REVIEWED_ON": null, +"TABLE_NM": "DC996664.MPE_X_TEST", +"BASE_TABLE": "DC996664.MPE_X_TEST", +"REVIEWED_ON_DTTM": " .", +"SUBMITTED_ON_DTTM": " 26SEP2022:08:43:22", +"LIB_ENGINE": "V9" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/getchangeinfo" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576B36041940A5600000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:25.235000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/getcolvals.js b/sas/mocks/sas9/sasjs/services/public/getcolvals.js new file mode 100644 index 0000000..1d5d321 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/getcolvals.js @@ -0,0 +1,138 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:49" +, "vals": +[ +{"FORMATTED":"0" ,"UNFORMATTED":0 } +,{"FORMATTED":"1" ,"UNFORMATTED":1 } +,{"FORMATTED":"3" ,"UNFORMATTED":3 } +,{"FORMATTED":"4" ,"UNFORMATTED":4 } +,{"FORMATTED":"5" ,"UNFORMATTED":5 } +,{"FORMATTED":"6" ,"UNFORMATTED":6 } +,{"FORMATTED":"7" ,"UNFORMATTED":7 } +,{"FORMATTED":"8" ,"UNFORMATTED":8 } +,{"FORMATTED":"9" ,"UNFORMATTED":9 } +,{"FORMATTED":"10" ,"UNFORMATTED":10 } +,{"FORMATTED":"11" ,"UNFORMATTED":11 } +,{"FORMATTED":"12" ,"UNFORMATTED":12 } +,{"FORMATTED":"13" ,"UNFORMATTED":13 } +,{"FORMATTED":"14" ,"UNFORMATTED":14 } +,{"FORMATTED":"15" ,"UNFORMATTED":15 } +,{"FORMATTED":"16" ,"UNFORMATTED":16 } +,{"FORMATTED":"17" ,"UNFORMATTED":17 } +,{"FORMATTED":"18" ,"UNFORMATTED":18 } +,{"FORMATTED":"19" ,"UNFORMATTED":19 } +,{"FORMATTED":"20" ,"UNFORMATTED":20 } +,{"FORMATTED":"21" ,"UNFORMATTED":21 } +,{"FORMATTED":"22" ,"UNFORMATTED":22 } +,{"FORMATTED":"23" ,"UNFORMATTED":23 } +,{"FORMATTED":"24" ,"UNFORMATTED":24 } +,{"FORMATTED":"25" ,"UNFORMATTED":25 } +,{"FORMATTED":"26" ,"UNFORMATTED":26 } +,{"FORMATTED":"27" ,"UNFORMATTED":27 } +,{"FORMATTED":"28" ,"UNFORMATTED":28 } +,{"FORMATTED":"29" ,"UNFORMATTED":29 } +,{"FORMATTED":"30" ,"UNFORMATTED":30 } +,{"FORMATTED":"31" ,"UNFORMATTED":31 } +,{"FORMATTED":"32" ,"UNFORMATTED":32 } +,{"FORMATTED":"33" ,"UNFORMATTED":33 } +,{"FORMATTED":"34" ,"UNFORMATTED":34 } +,{"FORMATTED":"35" ,"UNFORMATTED":35 } +,{"FORMATTED":"36" ,"UNFORMATTED":36 } +,{"FORMATTED":"37" ,"UNFORMATTED":37 } +,{"FORMATTED":"38" ,"UNFORMATTED":38 } +,{"FORMATTED":"39" ,"UNFORMATTED":39 } +,{"FORMATTED":"40" ,"UNFORMATTED":40 } +,{"FORMATTED":"41" ,"UNFORMATTED":41 } +,{"FORMATTED":"42" ,"UNFORMATTED":42 } +,{"FORMATTED":"43" ,"UNFORMATTED":43 } +,{"FORMATTED":"44" ,"UNFORMATTED":44 } +,{"FORMATTED":"45" ,"UNFORMATTED":45 } +,{"FORMATTED":"46" ,"UNFORMATTED":46 } +,{"FORMATTED":"47" ,"UNFORMATTED":47 } +,{"FORMATTED":"48" ,"UNFORMATTED":48 } +,{"FORMATTED":"49" ,"UNFORMATTED":49 } +,{"FORMATTED":"50" ,"UNFORMATTED":50 } +,{"FORMATTED":"51" ,"UNFORMATTED":51 } +,{"FORMATTED":"52" ,"UNFORMATTED":52 } +,{"FORMATTED":"53" ,"UNFORMATTED":53 } +,{"FORMATTED":"54" ,"UNFORMATTED":54 } +,{"FORMATTED":"55" ,"UNFORMATTED":55 } +,{"FORMATTED":"56" ,"UNFORMATTED":56 } +,{"FORMATTED":"57" ,"UNFORMATTED":57 } +,{"FORMATTED":"58" ,"UNFORMATTED":58 } +,{"FORMATTED":"59" ,"UNFORMATTED":59 } +,{"FORMATTED":"60" ,"UNFORMATTED":60 } +,{"FORMATTED":"61" ,"UNFORMATTED":61 } +,{"FORMATTED":"62" ,"UNFORMATTED":62 } +,{"FORMATTED":"63" ,"UNFORMATTED":63 } +,{"FORMATTED":"64" ,"UNFORMATTED":64 } +,{"FORMATTED":"65" ,"UNFORMATTED":65 } +,{"FORMATTED":"66" ,"UNFORMATTED":66 } +,{"FORMATTED":"67" ,"UNFORMATTED":67 } +,{"FORMATTED":"68" ,"UNFORMATTED":68 } +,{"FORMATTED":"69" ,"UNFORMATTED":69 } +,{"FORMATTED":"70" ,"UNFORMATTED":70 } +,{"FORMATTED":"71" ,"UNFORMATTED":71 } +,{"FORMATTED":"72" ,"UNFORMATTED":72 } +,{"FORMATTED":"73" ,"UNFORMATTED":73 } +,{"FORMATTED":"74" ,"UNFORMATTED":74 } +,{"FORMATTED":"75" ,"UNFORMATTED":75 } +,{"FORMATTED":"76" ,"UNFORMATTED":76 } +,{"FORMATTED":"77" ,"UNFORMATTED":77 } +,{"FORMATTED":"78" ,"UNFORMATTED":78 } +,{"FORMATTED":"79" ,"UNFORMATTED":79 } +,{"FORMATTED":"80" ,"UNFORMATTED":80 } +,{"FORMATTED":"81" ,"UNFORMATTED":81 } +,{"FORMATTED":"82" ,"UNFORMATTED":82 } +,{"FORMATTED":"83" ,"UNFORMATTED":83 } +,{"FORMATTED":"84" ,"UNFORMATTED":84 } +,{"FORMATTED":"85" ,"UNFORMATTED":85 } +,{"FORMATTED":"86" ,"UNFORMATTED":86 } +,{"FORMATTED":"87" ,"UNFORMATTED":87 } +,{"FORMATTED":"88" ,"UNFORMATTED":88 } +,{"FORMATTED":"89" ,"UNFORMATTED":89 } +,{"FORMATTED":"90" ,"UNFORMATTED":90 } +,{"FORMATTED":"91" ,"UNFORMATTED":91 } +,{"FORMATTED":"92" ,"UNFORMATTED":92 } +,{"FORMATTED":"93" ,"UNFORMATTED":93 } +,{"FORMATTED":"94" ,"UNFORMATTED":94 } +,{"FORMATTED":"95" ,"UNFORMATTED":95 } +,{"FORMATTED":"96" ,"UNFORMATTED":96 } +,{"FORMATTED":"97" ,"UNFORMATTED":97 } +,{"FORMATTED":"98" ,"UNFORMATTED":98 } +,{"FORMATTED":"99" ,"UNFORMATTED":99 } +,{"FORMATTED":"100" ,"UNFORMATTED":100 } +] +, "$vals":{"vars":{ +"FORMATTED" :{"format":"$12." ,"label":"FORMATTED" ,"length":"12" ,"type":"char" } +,"UNFORMATTED" :{"format":"best." ,"label":"UNFORMATTED" ,"length":"8" ,"type":"num" } +}} +, "meta": +[ +{ +"COLUMN": "SOME_BESTNUM", +"SASFORMAT": "BEST." +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/getcolvals" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057C8923D7140BEF70000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:49:39.137000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/getgroups.js b/sas/mocks/sas9/sasjs/services/public/getgroups.js new file mode 100644 index 0000000..aaf0d44 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/getgroups.js @@ -0,0 +1,162 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "groups": +[ +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001C", +"GROUPNAME": "BI Dashboard Administrators", +"GROUPDESC": "The members of this group are allowed to administer content for the SAS BI Dashboard product. The SAS Trusted User is made a member during initial deployment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001D", +"GROUPNAME": "BI Dashboard Users", +"GROUPDESC": "The members of this group are allowed general viewing access of content for the SAS BI Dashboard product." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000P", +"GROUPNAME": "BI Web Services Users", +"GROUPDESC": "Allows members to create and delete SAS BI Web Services." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000T", +"GROUPNAME": "Data Management Administrators", +"GROUPDESC": "Administrative users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000W", +"GROUPNAME": "Data Management Business Approvers", +"GROUPDESC": "Business approvers of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000V", +"GROUPNAME": "Data Management Business Users", +"GROUPDESC": "Business users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000Y", +"GROUPNAME": "Data Management Executives", +"GROUPDESC": "Executive users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000X", +"GROUPNAME": "Data Management Power Users", +"GROUPDESC": "Power users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000U", +"GROUPNAME": "Data Management Stewards", +"GROUPDESC": "Steward users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001F", +"GROUPNAME": "Decision Manager Common Administrators", +"GROUPDESC": "Decision Manager Administrative Group" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001G", +"GROUPNAME": "Decision Manager Users", +"GROUPDESC": "Decision Manager Users Group" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000021", +"GROUPNAME": "Factory Miner Database Users", +"GROUPDESC": "" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000002", +"GROUPNAME": "PUBLIC", +"GROUPDESC": "Everyone who can access the metadata server." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000008", +"GROUPNAME": "SAS General Servers", +"GROUPDESC": "Allows members to be used for launching stored process servers and pooled workspace servers." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000007", +"GROUPNAME": "SAS System Services", +"GROUPDESC": "Service identities that need access to server definitions or other system resources." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000003", +"GROUPNAME": "SASAdministrators", +"GROUPDESC": "Users who perform metadata administrative tasks." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000001", +"GROUPNAME": "SASUSERS", +"GROUPDESC": "Everyone who has a metadata identity. SASUSERS is a subset of PUBLIC." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001W", +"GROUPNAME": "SAS_EV_AppServer_Tier", +"GROUPDESC": "SAS Environment Manager App Server Tier Users" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001V", +"GROUPNAME": "SAS_EV_Guest", +"GROUPDESC": "SAS Environment Manager Guests" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001U", +"GROUPNAME": "SAS_EV_Super_User", +"GROUPDESC": "SAS Environment Manager Super Users" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000Q", +"GROUPNAME": "ThemeDesigner Administrators", +"GROUPDESC": "" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000I", +"GROUPNAME": "Visual Analytics Data Administrators", +"GROUPDESC": "Visual Analytics Data Administrators" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000013", +"GROUPNAME": "Visual Analytics Users", +"GROUPDESC": "Registered users of SAS Visual Analytics." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000J", +"GROUPNAME": "Visual Data Builder Administrators", +"GROUPDESC": "Visual Data Builder Administrators" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001O", +"GROUPNAME": "mdlmgradminusers", +"GROUPDESC": "Administrative Users for Model Manager" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001P", +"GROUPNAME": "mdlmgradvusers", +"GROUPDESC": "Advanced Users for Model Manager" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001Q", +"GROUPNAME": "mdlmgrusers", +"GROUPDESC": "Limited write access users of Model Manager" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/getgroups" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057DE0624DD40C2100000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:04.736000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/refreshlibinfo.js b/sas/mocks/sas9/sasjs/services/public/refreshlibinfo.js new file mode 100644 index 0000000..520ba8c --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/refreshlibinfo.js @@ -0,0 +1,39 @@ +_webout=`{"SYSDATE" : "29SEP22" +,"SYSTIME" : "12:02" +, "libinfo": +[ + { + "ENGINE": "BASE", + "LIBNAME": "Data Controller(DC996664)", + "PATHS": "(\\"C:\DataController\DC996664\\")", + "PERMS": "", + "OWNERS": "BUILTIN\Administrators", + "SCHEMAS": "", + "LIBID": "A59LNVZG.B500000K", + "LIBSIZE": " 13MB", + "TABLE_CNT": 32 + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/refreshlibinfo" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "A connection to the LASR Analytic Server on 'SAS.demo.sas.com', port 10011, could not be made. Make sure that the host and port are correctly specified, that you are attempting to connect to a LASR Analytic Server of the correct vintage, and that the server is still running." +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD816037A1CAC140C2B00000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T12:02:44.445000" +,"MEMSIZE" : "93GB" +} +` diff --git a/sas/mocks/sas9/sasjs/services/public/startupservice.js b/sas/mocks/sas9/sasjs/services/public/startupservice.js new file mode 100644 index 0000000..6e44e37 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/startupservice.js @@ -0,0 +1,102 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:29" +, "sasdatasets": +[ +{ +"LIBREF": "DC996664", +"DSN": "MPE_ALERTS" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_COLUMN_LEVEL_SECURITY" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_CONFIG" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_DATADICTIONARY" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_EMAILS" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_EXCEL_CONFIG" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_GROUPS" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_LOCKANYTABLE" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_ROW_LEVEL_SECURITY" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_SECURITY" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_SELECTBOX" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_TABLES" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_VALIDATIONS" +}, +{ +"LIBREF": "DC996664", +"DSN": "MPE_X_TEST" +} +] +, "saslibs": +[ +{ +"LIBREF": "DC996664" +} +] +, "globvars": +[ +{ +"DCLIB": "DC996664", +"SAS9LINEAGE_ENABLED": 1, +"ISREGISTERED": 1, +"REGISTERCOUNT": 1, +"DC_ADMIN_GROUP": "Data Management Business Approvers", +"LICENCE_KEY": "", +"ACTIVATION_KEY": "", +"DC_RESTRICT_EDITRECORD": "NO" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/startupservice" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8056944A8F5C409C500000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:29:06.092000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/validatefilter.js b/sas/mocks/sas9/sasjs/services/public/validatefilter.js new file mode 100644 index 0000000..75c45f6 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/validatefilter.js @@ -0,0 +1,32 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:49" +, "result": +[ +{ +"FILTER_RK": 1, +"FILTER_HASH": "FFE9C1E5F7AEC3B71F315EF2FEFC2296", +"FILTER_TABLE": "DC996664.MPE_X_TEST" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/validatefilter" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057CAEDE35440BF960000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:49:48.696000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/viewdata.js b/sas/mocks/sas9/sasjs/services/public/viewdata.js new file mode 100644 index 0000000..819ca5e --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/viewdata.js @@ -0,0 +1,3064 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "cls_rules": +[ + +] +, "cols": +[ +{ +"NAME": "PRIMARY_KEY_FIELD", +"LENGTH": 8, +"VARNUM": 1, +"LABEL": "PRIMARY_KEY_FIELD", +"FMTNAME": "", +"FORMAT": "8.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_BESTNUM", +"LENGTH": 8, +"VARNUM": 9, +"LABEL": "SOME_BESTNUM", +"FMTNAME": "BEST", +"FORMAT": "BEST.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_CHAR", +"LENGTH": 32767, +"VARNUM": 2, +"LABEL": "SOME_CHAR", +"FMTNAME": "", +"FORMAT": "$32767.", +"TYPE": "C", +"DDTYPE": "CHARACTER" +}, +{ +"NAME": "SOME_DATE", +"LENGTH": 8, +"VARNUM": 5, +"LABEL": "SOME_DATE", +"FMTNAME": "DATE", +"FORMAT": "DATE9.", +"TYPE": "N", +"DDTYPE": "DATE" +}, +{ +"NAME": "SOME_DATETIME", +"LENGTH": 8, +"VARNUM": 6, +"LABEL": "SOME_DATETIME", +"FMTNAME": "DATETIME", +"FORMAT": "DATETIME19.", +"TYPE": "N", +"DDTYPE": "DATETIME" +}, +{ +"NAME": "SOME_DROPDOWN", +"LENGTH": 128, +"VARNUM": 3, +"LABEL": "SOME_DROPDOWN", +"FMTNAME": "", +"FORMAT": "$128.", +"TYPE": "C", +"DDTYPE": "CHARACTER" +}, +{ +"NAME": "SOME_NUM", +"LENGTH": 8, +"VARNUM": 4, +"LABEL": "SOME_NUM", +"FMTNAME": "", +"FORMAT": "8.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_SHORTNUM", +"LENGTH": 4, +"VARNUM": 8, +"LABEL": "SOME_SHORTNUM", +"FMTNAME": "", +"FORMAT": "4.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_TIME", +"LENGTH": 8, +"VARNUM": 7, +"LABEL": "SOME_TIME", +"FMTNAME": "TIME", +"FORMAT": "TIME8.", +"TYPE": "N", +"DDTYPE": "TIME" +} +] +, "dsmeta": +[ +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Name", +"VALUE": "DC996664.MPE_X_TEST" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observations", +"VALUE": "496" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Member Type", +"VALUE": "DATA" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Variables", +"VALUE": "9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Engine", +"VALUE": "V9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Indexes", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Created", +"VALUE": "09/26/2022 08:24:39" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Integrity Constraints", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Last Modified", +"VALUE": "09/26/2022 08:47:46" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observation Length", +"VALUE": "32947" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Protection", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Deleted Observations", +"VALUE": "2" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Type", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Compressed", +"VALUE": "CHAR" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Label", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Reuse Space", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Representation", +"VALUE": "WINDOWS_64" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Point to Observations", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Encoding", +"VALUE": "wlatin1 Western (Windows)" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Sorted", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Data Set Page Size", +"VALUE": "262144" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Pages", +"VALUE": "3" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Index File Page Size", +"VALUE": "4096" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Index File Pages", +"VALUE": "4" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Repairs", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "ExtendObsCounter", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Filename", +"VALUE": "C:\DataController\DC996664\mpe_x_test.sas7bdat" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Release Created", +"VALUE": "9.0401M7" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Host Created", +"VALUE": "X64_DSRV16" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Owner Name", +"VALUE": "BUILTIN\Administrators" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size", +"VALUE": " 1MB" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size (bytes)", +"VALUE": "1048576" +} +] +, "query": +[ + +] +, "sasparams": +[ +{ +"TABLEURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR000036", +"TABLENAME": "MPE_X_TEST", +"FILTER_TEXT": "", +"PK_FIELDS": "PRIMARY_KEY_FIELD", +"NOBS": 496, +"VARS": 9, +"MAXROWS": 250 +} +] +, "viewdata": +[ +{ +"PRIMARY_KEY_FIELD": 2, +"SOME_CHAR": "even more dummy data", +"SOME_DROPDOWN": "Option 3", +"SOME_NUM": 42, +"SOME_DATE": "12FEB1960", +"SOME_DATETIME": " 01JAN1960:00:00:42", +"SOME_TIME": " 0:02:22", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 3, +"SOME_CHAR": "It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:", +"SOME_DROPDOWN": "Option 2", +"SOME_NUM": 1613.001, +"SOME_DATE": "27FEB1961", +"SOME_DATETIME": " 01JAN1960:00:07:03", +"SOME_TIME": " 0:00:44", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 4, +"SOME_CHAR": "if you can fill the unforgiving minute", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 1613.00112346, +"SOME_DATE": "02AUG1971", +"SOME_DATETIME": " 29MAY1973:06:12:03", +"SOME_TIME": " 0:06:52", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 1010, +"SOME_CHAR": "10 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.367786711253, +"SOME_DATE": "05MAR1961", +"SOME_DATETIME": " 01JAN1960:08:16:44", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 1, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1011, +"SOME_CHAR": "11 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.869333049687, +"SOME_DATE": "20JAN1961", +"SOME_DATETIME": " 01JAN1960:01:25:19", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 54 +}, +{ +"PRIMARY_KEY_FIELD": 1012, +"SOME_CHAR": "12 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.543277906507, +"SOME_DATE": "06OCT1961", +"SOME_DATETIME": " 01JAN1960:02:57:35", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 62 +}, +{ +"PRIMARY_KEY_FIELD": 1013, +"SOME_CHAR": "13 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.5051939867, +"SOME_DATE": "20FEB1962", +"SOME_DATETIME": " 01JAN1960:06:47:55", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 1014, +"SOME_CHAR": "14 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0130502507151, +"SOME_DATE": "13JAN1960", +"SOME_DATETIME": " 01JAN1960:03:48:13", +"SOME_TIME": " 0:00:14", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 57 +}, +{ +"PRIMARY_KEY_FIELD": 1015, +"SOME_CHAR": "15 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.582270800873, +"SOME_DATE": "12JUL1962", +"SOME_DATETIME": " 01JAN1960:12:05:18", +"SOME_TIME": " 0:00:54", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 80 +}, +{ +"PRIMARY_KEY_FIELD": 1016, +"SOME_CHAR": "16 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.138272497867, +"SOME_DATE": "29AUG1960", +"SOME_DATETIME": " 01JAN1960:02:48:01", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 1017, +"SOME_CHAR": "17 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.892701324025, +"SOME_DATE": "14SEP1961", +"SOME_DATETIME": " 01JAN1960:07:03:58", +"SOME_TIME": " 0:01:37", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1018, +"SOME_CHAR": "18 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.185278856747, +"SOME_DATE": "08MAR1961", +"SOME_DATETIME": " 01JAN1960:00:22:48", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 1019, +"SOME_CHAR": "19 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0737551018008, +"SOME_DATE": "24JAN1961", +"SOME_DATETIME": " 01JAN1960:03:14:33", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 1020, +"SOME_CHAR": "20 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.712856993877, +"SOME_DATE": "08FEB1961", +"SOME_DATETIME": " 01JAN1960:01:50:23", +"SOME_TIME": " 0:01:40", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 1021, +"SOME_CHAR": "21 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.67061384426, +"SOME_DATE": "09MAR1961", +"SOME_DATETIME": " 01JAN1960:04:52:55", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 1022, +"SOME_CHAR": "22 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.142321579225, +"SOME_DATE": "22JUL1962", +"SOME_DATETIME": " 01JAN1960:07:25:01", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 66, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1023, +"SOME_CHAR": "23 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.125984806626, +"SOME_DATE": "01SEP1962", +"SOME_DATETIME": " 01JAN1960:09:32:34", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1024, +"SOME_CHAR": "24 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.389946863702, +"SOME_DATE": "06DEC1961", +"SOME_DATETIME": " 01JAN1960:06:53:51", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 1025, +"SOME_CHAR": "25 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0310356193367, +"SOME_DATE": "01MAR1960", +"SOME_DATETIME": " 01JAN1960:02:58:07", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 1026, +"SOME_CHAR": "26 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905788423915, +"SOME_DATE": "04OCT1960", +"SOME_DATETIME": " 01JAN1960:11:17:28", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 82, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 1027, +"SOME_CHAR": "27 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.592067585602, +"SOME_DATE": "15JUL1962", +"SOME_DATETIME": " 01JAN1960:03:35:41", +"SOME_TIME": " 0:00:22", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 73 +}, +{ +"PRIMARY_KEY_FIELD": 1028, +"SOME_CHAR": "28 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.658003004574, +"SOME_DATE": "08OCT1960", +"SOME_DATETIME": " 01JAN1960:13:13:30", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 40 +}, +{ +"PRIMARY_KEY_FIELD": 1029, +"SOME_CHAR": "29 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.807042593978, +"SOME_DATE": "26DEC1960", +"SOME_DATETIME": " 01JAN1960:11:57:14", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 12 +}, +{ +"PRIMARY_KEY_FIELD": 1030, +"SOME_CHAR": "30 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.880145040751, +"SOME_DATE": "15MAY1961", +"SOME_DATETIME": " 01JAN1960:10:11:05", +"SOME_TIME": " 0:00:25", +"SOME_SHORTNUM": 70, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 1031, +"SOME_CHAR": "31 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.41501947046, +"SOME_DATE": "27JAN1962", +"SOME_DATETIME": " 01JAN1960:11:27:09", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 94, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 1032, +"SOME_CHAR": "32 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.974340120319, +"SOME_DATE": "09JAN1962", +"SOME_DATETIME": " 01JAN1960:07:44:35", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 3 +}, +{ +"PRIMARY_KEY_FIELD": 1033, +"SOME_CHAR": "33 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.203559569178, +"SOME_DATE": "07SEP1960", +"SOME_DATETIME": " 01JAN1960:11:52:19", +"SOME_TIME": " 0:00:42", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 1034, +"SOME_CHAR": "34 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.679243555609, +"SOME_DATE": "21APR1960", +"SOME_DATETIME": " 01JAN1960:07:17:04", +"SOME_TIME": " 0:01:14", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 1035, +"SOME_CHAR": "35 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.949411697197, +"SOME_DATE": "19JAN1960", +"SOME_DATETIME": " 01JAN1960:10:15:38", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 1036, +"SOME_CHAR": "36 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.544613491066, +"SOME_DATE": "26OCT1960", +"SOME_DATETIME": " 01JAN1960:03:55:27", +"SOME_TIME": " 0:01:24", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 1037, +"SOME_CHAR": "37 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.458775893999, +"SOME_DATE": "21NOV1960", +"SOME_DATETIME": " 01JAN1960:13:34:37", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1038, +"SOME_CHAR": "38 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.153719423876, +"SOME_DATE": "06MAY1961", +"SOME_DATETIME": " 01JAN1960:06:14:13", +"SOME_TIME": " 0:00:29", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1039, +"SOME_CHAR": "39 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.493500256209, +"SOME_DATE": "05JUN1960", +"SOME_DATETIME": " 01JAN1960:06:59:42", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 55 +}, +{ +"PRIMARY_KEY_FIELD": 1040, +"SOME_CHAR": "40 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.124728858995, +"SOME_DATE": "09MAR1961", +"SOME_DATETIME": " 01JAN1960:03:03:06", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 1041, +"SOME_CHAR": "41 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.279442200102, +"SOME_DATE": "06JUL1962", +"SOME_DATETIME": " 01JAN1960:05:29:26", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1042, +"SOME_CHAR": "42 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.703077549908, +"SOME_DATE": "11AUG1960", +"SOME_DATETIME": " 01JAN1960:12:11:24", +"SOME_TIME": " 0:00:38", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 1043, +"SOME_CHAR": "43 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0701107536769, +"SOME_DATE": "29JAN1961", +"SOME_DATETIME": " 01JAN1960:03:44:09", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 1044, +"SOME_CHAR": "44 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.642329292671, +"SOME_DATE": "15JAN1962", +"SOME_DATETIME": " 01JAN1960:00:57:07", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 37 +}, +{ +"PRIMARY_KEY_FIELD": 1045, +"SOME_CHAR": "45 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.720644774251, +"SOME_DATE": "14OCT1961", +"SOME_DATETIME": " 01JAN1960:12:25:32", +"SOME_TIME": " 0:00:07", +"SOME_SHORTNUM": 58, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1046, +"SOME_CHAR": "46 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0431997366451, +"SOME_DATE": "12SEP1960", +"SOME_DATETIME": " 01JAN1960:05:12:57", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 1047, +"SOME_CHAR": "47 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.370407136795, +"SOME_DATE": "01JUL1960", +"SOME_DATETIME": " 01JAN1960:02:44:37", +"SOME_TIME": " 0:00:06", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 26 +}, +{ +"PRIMARY_KEY_FIELD": 1048, +"SOME_CHAR": "48 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.654417035009, +"SOME_DATE": "04MAY1961", +"SOME_DATETIME": " 01JAN1960:01:23:07", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 13 +}, +{ +"PRIMARY_KEY_FIELD": 1049, +"SOME_CHAR": "49 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.130021256455, +"SOME_DATE": "06JAN1961", +"SOME_DATETIME": " 01JAN1960:05:27:29", +"SOME_TIME": " 0:01:21", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1050, +"SOME_CHAR": "50 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.00584097253431, +"SOME_DATE": "23JUL1960", +"SOME_DATETIME": " 01JAN1960:00:04:24", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 15, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1051, +"SOME_CHAR": "51 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.723938258702, +"SOME_DATE": "09JUN1960", +"SOME_DATETIME": " 01JAN1960:03:15:09", +"SOME_TIME": " 0:00:04", +"SOME_SHORTNUM": 42, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 1052, +"SOME_CHAR": "52 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.83190037116, +"SOME_DATE": "13AUG1960", +"SOME_DATETIME": " 01JAN1960:07:38:35", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 1053, +"SOME_CHAR": "53 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.503082887504, +"SOME_DATE": "22JUN1961", +"SOME_DATETIME": " 01JAN1960:11:25:29", +"SOME_TIME": " 0:00:53", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 75 +}, +{ +"PRIMARY_KEY_FIELD": 1054, +"SOME_CHAR": "54 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.714804551431, +"SOME_DATE": "26AUG1960", +"SOME_DATETIME": " 01JAN1960:10:10:09", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 1055, +"SOME_CHAR": "55 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.855794578724, +"SOME_DATE": "19OCT1960", +"SOME_DATETIME": " 01JAN1960:02:17:32", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 1056, +"SOME_CHAR": "56 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.970046330695, +"SOME_DATE": "11JUL1962", +"SOME_DATETIME": " 01JAN1960:11:18:41", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 1057, +"SOME_CHAR": "57 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.938039942616, +"SOME_DATE": "26JUN1961", +"SOME_DATETIME": " 01JAN1960:13:15:13", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 57, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1058, +"SOME_CHAR": "58 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.848449948639, +"SOME_DATE": "02JUN1960", +"SOME_DATETIME": " 01JAN1960:01:14:51", +"SOME_TIME": " 0:00:00", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1059, +"SOME_CHAR": "59 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.141570762797, +"SOME_DATE": "28JUL1961", +"SOME_DATETIME": " 01JAN1960:06:33:16", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1060, +"SOME_CHAR": "60 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.282674512958, +"SOME_DATE": "27MAR1962", +"SOME_DATETIME": " 01JAN1960:00:25:37", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1061, +"SOME_CHAR": "61 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.372728008019, +"SOME_DATE": "04JAN1962", +"SOME_DATETIME": " 01JAN1960:05:07:43", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 1062, +"SOME_CHAR": "62 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.951733731642, +"SOME_DATE": "29AUG1961", +"SOME_DATETIME": " 01JAN1960:02:40:05", +"SOME_TIME": " 0:00:05", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 1063, +"SOME_CHAR": "63 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.096749868289, +"SOME_DATE": "17FEB1962", +"SOME_DATETIME": " 01JAN1960:07:30:41", +"SOME_TIME": " 0:00:29", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 1064, +"SOME_CHAR": "64 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.054067135348, +"SOME_DATE": "26MAY1961", +"SOME_DATETIME": " 01JAN1960:13:13:43", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 45 +}, +{ +"PRIMARY_KEY_FIELD": 1065, +"SOME_CHAR": "65 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.646163646433, +"SOME_DATE": "27JAN1962", +"SOME_DATETIME": " 01JAN1960:02:56:41", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 38 +}, +{ +"PRIMARY_KEY_FIELD": 1066, +"SOME_CHAR": "66 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905301198319, +"SOME_DATE": "02OCT1960", +"SOME_DATETIME": " 01JAN1960:03:35:49", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 39 +}, +{ +"PRIMARY_KEY_FIELD": 1067, +"SOME_CHAR": "67 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.977525881015, +"SOME_DATE": "19JUL1962", +"SOME_DATETIME": " 01JAN1960:05:53:20", +"SOME_TIME": " 0:00:28", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 1068, +"SOME_CHAR": "68 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.216555316102, +"SOME_DATE": "13MAY1960", +"SOME_DATETIME": " 01JAN1960:01:44:02", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 23 +}, +{ +"PRIMARY_KEY_FIELD": 1069, +"SOME_CHAR": "69 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.224835279502, +"SOME_DATE": "09MAY1961", +"SOME_DATETIME": " 01JAN1960:00:04:33", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 1070, +"SOME_CHAR": "70 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.138628336666, +"SOME_DATE": "18MAY1962", +"SOME_DATETIME": " 01JAN1960:03:32:00", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 89 +}, +{ +"PRIMARY_KEY_FIELD": 1071, +"SOME_CHAR": "71 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.933733141485, +"SOME_DATE": "16MAY1961", +"SOME_DATETIME": " 01JAN1960:13:46:54", +"SOME_TIME": " 0:00:47", +"SOME_SHORTNUM": 27, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 1072, +"SOME_CHAR": "72 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0352235506453, +"SOME_DATE": "06JUN1961", +"SOME_DATETIME": " 01JAN1960:09:09:20", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 7, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 1073, +"SOME_CHAR": "73 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.320666269549, +"SOME_DATE": "13MAR1960", +"SOME_DATETIME": " 01JAN1960:10:38:11", +"SOME_TIME": " 0:01:08", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 1074, +"SOME_CHAR": "74 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.461086170497, +"SOME_DATE": "31AUG1961", +"SOME_DATETIME": " 01JAN1960:09:35:41", +"SOME_TIME": " 0:01:08", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 68 +}, +{ +"PRIMARY_KEY_FIELD": 1075, +"SOME_CHAR": "75 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.452774562152, +"SOME_DATE": "16JAN1962", +"SOME_DATETIME": " 01JAN1960:06:49:27", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 96, +"SOME_BESTNUM": 63 +}, +{ +"PRIMARY_KEY_FIELD": 1076, +"SOME_CHAR": "76 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.358124405778, +"SOME_DATE": "16MAY1960", +"SOME_DATETIME": " 01JAN1960:00:56:40", +"SOME_TIME": " 0:01:13", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 24 +}, +{ +"PRIMARY_KEY_FIELD": 1077, +"SOME_CHAR": "77 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.893992133389, +"SOME_DATE": "21JAN1961", +"SOME_DATETIME": " 01JAN1960:09:16:31", +"SOME_TIME": " 0:01:15", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 69 +}, +{ +"PRIMARY_KEY_FIELD": 1078, +"SOME_CHAR": "78 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.244572706634, +"SOME_DATE": "22DEC1960", +"SOME_DATETIME": " 01JAN1960:03:11:14", +"SOME_TIME": " 0:01:37", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1079, +"SOME_CHAR": "79 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.968302946523, +"SOME_DATE": "14AUG1961", +"SOME_DATETIME": " 01JAN1960:04:45:43", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 60 +}, +{ +"PRIMARY_KEY_FIELD": 1080, +"SOME_CHAR": "80 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.130354136755, +"SOME_DATE": "28FEB1962", +"SOME_DATETIME": " 01JAN1960:02:14:50", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 87 +}, +{ +"PRIMARY_KEY_FIELD": 1081, +"SOME_CHAR": "81 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.765697965289, +"SOME_DATE": "03AUG1961", +"SOME_DATETIME": " 01JAN1960:06:49:50", +"SOME_TIME": " 0:01:31", +"SOME_SHORTNUM": 58, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 1082, +"SOME_CHAR": "82 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.185562967409, +"SOME_DATE": "16DEC1960", +"SOME_DATETIME": " 01JAN1960:06:27:21", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 1, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1083, +"SOME_CHAR": "83 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.478217864166, +"SOME_DATE": "16APR1961", +"SOME_DATETIME": " 01JAN1960:08:05:23", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 0, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 1084, +"SOME_CHAR": "84 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.167027213223, +"SOME_DATE": "21JUN1962", +"SOME_DATETIME": " 01JAN1960:13:43:20", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 6 +}, +{ +"PRIMARY_KEY_FIELD": 1085, +"SOME_CHAR": "85 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.606824918933, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:11:05:11", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 68 +}, +{ +"PRIMARY_KEY_FIELD": 1086, +"SOME_CHAR": "86 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0936049917217, +"SOME_DATE": "20JUL1962", +"SOME_DATETIME": " 01JAN1960:07:16:09", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 37 +}, +{ +"PRIMARY_KEY_FIELD": 1087, +"SOME_CHAR": "87 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.653824917811, +"SOME_DATE": "24APR1960", +"SOME_DATETIME": " 01JAN1960:02:06:54", +"SOME_TIME": " 0:00:59", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1088, +"SOME_CHAR": "88 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.884615856169, +"SOME_DATE": "19NOV1961", +"SOME_DATETIME": " 01JAN1960:05:35:27", +"SOME_TIME": " 0:01:01", +"SOME_SHORTNUM": 87, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 1089, +"SOME_CHAR": "89 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.157820831592, +"SOME_DATE": "03MAR1961", +"SOME_DATETIME": " 01JAN1960:09:02:02", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 1090, +"SOME_CHAR": "90 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.422575375262, +"SOME_DATE": "19MAR1960", +"SOME_DATETIME": " 01JAN1960:12:14:04", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 57, +"SOME_BESTNUM": 64 +}, +{ +"PRIMARY_KEY_FIELD": 1091, +"SOME_CHAR": "91 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.659894335391, +"SOME_DATE": "17SEP1961", +"SOME_DATETIME": " 01JAN1960:03:03:13", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 28 +}, +{ +"PRIMARY_KEY_FIELD": 1092, +"SOME_CHAR": "92 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.629350168924, +"SOME_DATE": "18OCT1961", +"SOME_DATETIME": " 01JAN1960:00:21:13", +"SOME_TIME": " 0:01:11", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 1093, +"SOME_CHAR": "93 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.437884498591, +"SOME_DATE": "24JUN1961", +"SOME_DATETIME": " 01JAN1960:10:20:39", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 78 +}, +{ +"PRIMARY_KEY_FIELD": 1094, +"SOME_CHAR": "94 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.983858496875, +"SOME_DATE": "25MAY1962", +"SOME_DATETIME": " 01JAN1960:02:59:06", +"SOME_TIME": " 0:00:59", +"SOME_SHORTNUM": 48, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1095, +"SOME_CHAR": "95 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0892523769705, +"SOME_DATE": "16JUN1961", +"SOME_DATETIME": " 01JAN1960:04:54:20", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 1096, +"SOME_CHAR": "96 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.457820515362, +"SOME_DATE": "20JAN1960", +"SOME_DATETIME": " 01JAN1960:10:36:00", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 14, +"SOME_BESTNUM": 17 +}, +{ +"PRIMARY_KEY_FIELD": 1097, +"SOME_CHAR": "97 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.586327158653, +"SOME_DATE": "20APR1962", +"SOME_DATETIME": " 01JAN1960:11:14:11", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 66, +"SOME_BESTNUM": 84 +}, +{ +"PRIMARY_KEY_FIELD": 1098, +"SOME_CHAR": "98 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.299423205806, +"SOME_DATE": "04JUL1960", +"SOME_DATETIME": " 01JAN1960:08:15:41", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 1099, +"SOME_CHAR": "99 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0981378052841, +"SOME_DATE": "05FEB1960", +"SOME_DATETIME": " 01JAN1960:11:10:11", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 23, +"SOME_BESTNUM": 65 +}, +{ +"PRIMARY_KEY_FIELD": 10100, +"SOME_CHAR": "100 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.982972265213, +"SOME_DATE": "01FEB1960", +"SOME_DATETIME": " 01JAN1960:05:45:06", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 10101, +"SOME_CHAR": "101 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.454079491298, +"SOME_DATE": "03AUG1962", +"SOME_DATETIME": " 01JAN1960:09:27:03", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 42, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 10102, +"SOME_CHAR": "102 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.845217436946, +"SOME_DATE": "02OCT1960", +"SOME_DATETIME": " 01JAN1960:03:08:47", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10103, +"SOME_CHAR": "103 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.590491960566, +"SOME_DATE": "30JUL1960", +"SOME_DATETIME": " 01JAN1960:13:09:58", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 10104, +"SOME_CHAR": "104 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.708338867737, +"SOME_DATE": "24JUL1960", +"SOME_DATETIME": " 01JAN1960:05:49:50", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10105, +"SOME_CHAR": "105 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.318355025872, +"SOME_DATE": "14SEP1961", +"SOME_DATETIME": " 01JAN1960:02:28:34", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10106, +"SOME_CHAR": "106 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.972975597239, +"SOME_DATE": "08AUG1961", +"SOME_DATETIME": " 01JAN1960:04:30:41", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10107, +"SOME_CHAR": "107 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.509077321509, +"SOME_DATE": "23SEP1960", +"SOME_DATETIME": " 01JAN1960:05:20:31", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 73 +}, +{ +"PRIMARY_KEY_FIELD": 10108, +"SOME_CHAR": "108 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.605017692598, +"SOME_DATE": "18MAR1961", +"SOME_DATETIME": " 01JAN1960:02:16:28", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 21 +}, +{ +"PRIMARY_KEY_FIELD": 10109, +"SOME_CHAR": "109 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.361268181522, +"SOME_DATE": "02JAN1962", +"SOME_DATETIME": " 01JAN1960:11:03:06", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 10110, +"SOME_CHAR": "110 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.92257953711, +"SOME_DATE": "30JUN1960", +"SOME_DATETIME": " 01JAN1960:07:37:19", +"SOME_TIME": " 0:00:53", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10111, +"SOME_CHAR": "111 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.576207744226, +"SOME_DATE": "02JAN1960", +"SOME_DATETIME": " 01JAN1960:02:58:52", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 94 +}, +{ +"PRIMARY_KEY_FIELD": 10112, +"SOME_CHAR": "112 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.722135797945, +"SOME_DATE": "03JAN1961", +"SOME_DATETIME": " 01JAN1960:06:46:21", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10113, +"SOME_CHAR": "113 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.683960923312, +"SOME_DATE": "26MAY1962", +"SOME_DATETIME": " 01JAN1960:02:09:46", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10114, +"SOME_CHAR": "114 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0627542203584, +"SOME_DATE": "30AUG1960", +"SOME_DATETIME": " 01JAN1960:10:55:01", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 10115, +"SOME_CHAR": "115 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.146239363191, +"SOME_DATE": "02FEB1962", +"SOME_DATETIME": " 01JAN1960:08:38:32", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10116, +"SOME_CHAR": "116 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.88700955449, +"SOME_DATE": "06APR1961", +"SOME_DATETIME": " 01JAN1960:08:19:07", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 100 +}, +{ +"PRIMARY_KEY_FIELD": 10117, +"SOME_CHAR": "117 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.586251998128, +"SOME_DATE": "11FEB1962", +"SOME_DATETIME": " 01JAN1960:09:18:09", +"SOME_TIME": " 0:01:24", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 65 +}, +{ +"PRIMARY_KEY_FIELD": 10118, +"SOME_CHAR": "118 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.119509128444, +"SOME_DATE": "29MAR1960", +"SOME_DATETIME": " 01JAN1960:05:00:30", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 74, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 10119, +"SOME_CHAR": "119 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.25274958287, +"SOME_DATE": "14MAR1960", +"SOME_DATETIME": " 01JAN1960:11:15:20", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10120, +"SOME_CHAR": "120 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.200962597132, +"SOME_DATE": "18NOV1960", +"SOME_DATETIME": " 01JAN1960:10:17:59", +"SOME_TIME": " 0:00:25", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10121, +"SOME_CHAR": "121 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.517157181407, +"SOME_DATE": "27NOV1961", +"SOME_DATETIME": " 01JAN1960:09:53:43", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10122, +"SOME_CHAR": "122 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.625352653966, +"SOME_DATE": "15DEC1960", +"SOME_DATETIME": " 01JAN1960:05:14:23", +"SOME_TIME": " 0:01:17", +"SOME_SHORTNUM": 55, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10123, +"SOME_CHAR": "123 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0397578571177, +"SOME_DATE": "08SEP1961", +"SOME_DATETIME": " 01JAN1960:00:37:02", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 21, +"SOME_BESTNUM": 21 +}, +{ +"PRIMARY_KEY_FIELD": 10124, +"SOME_CHAR": "124 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.152996921983, +"SOME_DATE": "20FEB1962", +"SOME_DATETIME": " 01JAN1960:08:46:06", +"SOME_TIME": " 0:00:49", +"SOME_SHORTNUM": 77, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10125, +"SOME_CHAR": "125 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.55944163518, +"SOME_DATE": "28APR1962", +"SOME_DATETIME": " 01JAN1960:05:02:05", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10126, +"SOME_CHAR": "126 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0545679247261, +"SOME_DATE": "12APR1960", +"SOME_DATETIME": " 01JAN1960:03:28:48", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 78, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10127, +"SOME_CHAR": "127 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.371348928367, +"SOME_DATE": "12OCT1961", +"SOME_DATETIME": " 01JAN1960:02:16:07", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 88 +}, +{ +"PRIMARY_KEY_FIELD": 10128, +"SOME_CHAR": "128 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.647298235282, +"SOME_DATE": "03APR1960", +"SOME_DATETIME": " 01JAN1960:00:32:14", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 10129, +"SOME_CHAR": "129 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.830022884919, +"SOME_DATE": "05JAN1960", +"SOME_DATETIME": " 01JAN1960:13:45:11", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10130, +"SOME_CHAR": "130 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.265660790385, +"SOME_DATE": "10JUL1961", +"SOME_DATETIME": " 01JAN1960:05:20:20", +"SOME_TIME": " 0:00:44", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10131, +"SOME_CHAR": "131 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.351538887877, +"SOME_DATE": "10APR1961", +"SOME_DATETIME": " 01JAN1960:02:34:28", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 33, +"SOME_BESTNUM": 47 +}, +{ +"PRIMARY_KEY_FIELD": 10132, +"SOME_CHAR": "132 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.584812691708, +"SOME_DATE": "04JAN1961", +"SOME_DATETIME": " 01JAN1960:00:58:07", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 27, +"SOME_BESTNUM": 23 +}, +{ +"PRIMARY_KEY_FIELD": 10133, +"SOME_CHAR": "133 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.359766102563, +"SOME_DATE": "01APR1962", +"SOME_DATETIME": " 01JAN1960:04:32:07", +"SOME_TIME": " 0:00:12", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 10134, +"SOME_CHAR": "134 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.668257887321, +"SOME_DATE": "23NOV1961", +"SOME_DATETIME": " 01JAN1960:12:09:29", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 24 +}, +{ +"PRIMARY_KEY_FIELD": 10135, +"SOME_CHAR": "135 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.673810465575, +"SOME_DATE": "21MAY1961", +"SOME_DATETIME": " 01JAN1960:08:17:36", +"SOME_TIME": " 0:01:25", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10136, +"SOME_CHAR": "136 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.610945592919, +"SOME_DATE": "20DEC1961", +"SOME_DATETIME": " 01JAN1960:06:15:06", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 62 +}, +{ +"PRIMARY_KEY_FIELD": 10137, +"SOME_CHAR": "137 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.903748751573, +"SOME_DATE": "13MAR1960", +"SOME_DATETIME": " 01JAN1960:01:34:57", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10138, +"SOME_CHAR": "138 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.807945651844, +"SOME_DATE": "04OCT1961", +"SOME_DATETIME": " 01JAN1960:11:45:56", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10139, +"SOME_CHAR": "139 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.383073866546, +"SOME_DATE": "06APR1960", +"SOME_DATETIME": " 01JAN1960:07:42:17", +"SOME_TIME": " 0:01:31", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10140, +"SOME_CHAR": "140 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.56504530905, +"SOME_DATE": "20FEB1960", +"SOME_DATETIME": " 01JAN1960:00:07:16", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 10141, +"SOME_CHAR": "141 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.887459293887, +"SOME_DATE": "01MAR1962", +"SOME_DATETIME": " 01JAN1960:00:34:22", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10142, +"SOME_CHAR": "142 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.404861313945, +"SOME_DATE": "05FEB1961", +"SOME_DATETIME": " 01JAN1960:10:57:41", +"SOME_TIME": " 0:00:31", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10143, +"SOME_CHAR": "143 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.460108042443, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:10:35:18", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 5, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 10144, +"SOME_CHAR": "144 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.809737510891, +"SOME_DATE": "26JAN1961", +"SOME_DATETIME": " 01JAN1960:08:06:34", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 51 +}, +{ +"PRIMARY_KEY_FIELD": 10145, +"SOME_CHAR": "145 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.993591509756, +"SOME_DATE": "15MAR1961", +"SOME_DATETIME": " 01JAN1960:12:49:53", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10146, +"SOME_CHAR": "146 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0452116918961, +"SOME_DATE": "28APR1960", +"SOME_DATETIME": " 01JAN1960:06:18:21", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10147, +"SOME_CHAR": "147 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.828117129779, +"SOME_DATE": "17SEP1960", +"SOME_DATETIME": " 01JAN1960:03:32:05", +"SOME_TIME": " 0:00:17", +"SOME_SHORTNUM": 62, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 10148, +"SOME_CHAR": "148 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.108167296326, +"SOME_DATE": "27JUL1962", +"SOME_DATETIME": " 01JAN1960:07:27:20", +"SOME_TIME": " 0:00:50", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10149, +"SOME_CHAR": "149 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.380526406868, +"SOME_DATE": "14NOV1961", +"SOME_DATETIME": " 01JAN1960:00:53:41", +"SOME_TIME": " 0:01:26", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10150, +"SOME_CHAR": "150 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.755726019738, +"SOME_DATE": "09SEP1962", +"SOME_DATETIME": " 01JAN1960:05:18:45", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10151, +"SOME_CHAR": "151 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.144336483043, +"SOME_DATE": "05SEP1962", +"SOME_DATETIME": " 01JAN1960:02:58:32", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10152, +"SOME_CHAR": "152 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0478734295107, +"SOME_DATE": "14JUL1960", +"SOME_DATETIME": " 01JAN1960:05:46:43", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 31 +}, +{ +"PRIMARY_KEY_FIELD": 10153, +"SOME_CHAR": "153 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.99183906661, +"SOME_DATE": "26APR1962", +"SOME_DATETIME": " 01JAN1960:04:48:41", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 75 +}, +{ +"PRIMARY_KEY_FIELD": 10154, +"SOME_CHAR": "154 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.915963809898, +"SOME_DATE": "04SEP1960", +"SOME_DATETIME": " 01JAN1960:01:48:59", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 15 +}, +{ +"PRIMARY_KEY_FIELD": 10155, +"SOME_CHAR": "155 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.368240488865, +"SOME_DATE": "24JAN1962", +"SOME_DATETIME": " 01JAN1960:08:59:46", +"SOME_TIME": " 0:00:14", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 100 +}, +{ +"PRIMARY_KEY_FIELD": 10156, +"SOME_CHAR": "156 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.261119415174, +"SOME_DATE": "31DEC1961", +"SOME_DATETIME": " 01JAN1960:00:43:42", +"SOME_TIME": " 0:00:30", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10157, +"SOME_CHAR": "157 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.889038999513, +"SOME_DATE": "28NOV1960", +"SOME_DATETIME": " 01JAN1960:03:19:35", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10158, +"SOME_CHAR": "158 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.131941327887, +"SOME_DATE": "27AUG1961", +"SOME_DATETIME": " 01JAN1960:07:26:49", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10159, +"SOME_CHAR": "159 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.626175243233, +"SOME_DATE": "23JUN1960", +"SOME_DATETIME": " 01JAN1960:02:32:40", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 48, +"SOME_BESTNUM": 61 +}, +{ +"PRIMARY_KEY_FIELD": 10160, +"SOME_CHAR": "160 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.570262782076, +"SOME_DATE": "27NOV1961", +"SOME_DATETIME": " 01JAN1960:12:11:27", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 10161, +"SOME_CHAR": "161 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.85756031324, +"SOME_DATE": "28SEP1960", +"SOME_DATETIME": " 01JAN1960:13:40:34", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 10162, +"SOME_CHAR": "162 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.182688185099, +"SOME_DATE": "17FEB1960", +"SOME_DATETIME": " 01JAN1960:02:58:44", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10163, +"SOME_CHAR": "163 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.234210872666, +"SOME_DATE": "27APR1961", +"SOME_DATETIME": " 01JAN1960:02:55:22", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 20, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10164, +"SOME_CHAR": "164 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.356953425965, +"SOME_DATE": "10JUN1960", +"SOME_DATETIME": " 01JAN1960:10:48:35", +"SOME_TIME": " 0:00:54", +"SOME_SHORTNUM": 32, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10165, +"SOME_CHAR": "165 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.913664674812, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:10:33:26", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 6 +}, +{ +"PRIMARY_KEY_FIELD": 10166, +"SOME_CHAR": "166 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.999055517837, +"SOME_DATE": "29MAR1962", +"SOME_DATETIME": " 01JAN1960:11:58:00", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10167, +"SOME_CHAR": "167 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.522591932454, +"SOME_DATE": "03MAR1960", +"SOME_DATETIME": " 01JAN1960:13:08:34", +"SOME_TIME": " 0:01:17", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10168, +"SOME_CHAR": "168 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.376125323761, +"SOME_DATE": "31MAR1961", +"SOME_DATETIME": " 01JAN1960:02:55:13", +"SOME_TIME": " 0:01:19", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 41 +}, +{ +"PRIMARY_KEY_FIELD": 10169, +"SOME_CHAR": "169 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.326772676467, +"SOME_DATE": "19JUN1962", +"SOME_DATETIME": " 01JAN1960:11:57:02", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10170, +"SOME_CHAR": "170 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.782820686597, +"SOME_DATE": "07AUG1961", +"SOME_DATETIME": " 01JAN1960:09:55:03", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 96, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 10171, +"SOME_CHAR": "171 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.863840596221, +"SOME_DATE": "18JAN1961", +"SOME_DATETIME": " 01JAN1960:04:31:08", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 52 +}, +{ +"PRIMARY_KEY_FIELD": 10172, +"SOME_CHAR": "172 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.789710712987, +"SOME_DATE": "01OCT1960", +"SOME_DATETIME": " 01JAN1960:11:06:53", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 77 +}, +{ +"PRIMARY_KEY_FIELD": 10173, +"SOME_CHAR": "173 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.802511338518, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:06:53:54", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 24, +"SOME_BESTNUM": 52 +}, +{ +"PRIMARY_KEY_FIELD": 10174, +"SOME_CHAR": "174 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.753009963666, +"SOME_DATE": "26JAN1961", +"SOME_DATETIME": " 01JAN1960:07:06:38", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 10175, +"SOME_CHAR": "175 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.716320670543, +"SOME_DATE": "15AUG1962", +"SOME_DATETIME": " 01JAN1960:04:48:32", +"SOME_TIME": " 0:01:15", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 10176, +"SOME_CHAR": "176 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.791488602195, +"SOME_DATE": "26MAY1960", +"SOME_DATETIME": " 01JAN1960:12:09:38", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 4, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10177, +"SOME_CHAR": "177 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0925364206045, +"SOME_DATE": "18APR1960", +"SOME_DATETIME": " 01JAN1960:01:35:06", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 99 +}, +{ +"PRIMARY_KEY_FIELD": 10178, +"SOME_CHAR": "178 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.117532277069, +"SOME_DATE": "21SEP1961", +"SOME_DATETIME": " 01JAN1960:05:49:58", +"SOME_TIME": " 0:00:30", +"SOME_SHORTNUM": 9, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10179, +"SOME_CHAR": "179 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.768050647233, +"SOME_DATE": "25APR1961", +"SOME_DATETIME": " 01JAN1960:04:38:18", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 40 +}, +{ +"PRIMARY_KEY_FIELD": 10180, +"SOME_CHAR": "180 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.726473274979, +"SOME_DATE": "04JAN1960", +"SOME_DATETIME": " 01JAN1960:00:11:32", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 63 +}, +{ +"PRIMARY_KEY_FIELD": 10181, +"SOME_CHAR": "181 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.611879586527, +"SOME_DATE": "15MAR1962", +"SOME_DATETIME": " 01JAN1960:04:18:35", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 74, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 10182, +"SOME_CHAR": "182 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.378131004226, +"SOME_DATE": "05AUG1962", +"SOME_DATETIME": " 01JAN1960:04:46:05", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 40, +"SOME_BESTNUM": 70 +}, +{ +"PRIMARY_KEY_FIELD": 10183, +"SOME_CHAR": "183 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.772194760745, +"SOME_DATE": "29NOV1960", +"SOME_DATETIME": " 01JAN1960:05:09:32", +"SOME_TIME": " 0:00:47", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 13 +}, +{ +"PRIMARY_KEY_FIELD": 10184, +"SOME_CHAR": "184 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0812941533892, +"SOME_DATE": "28JUN1961", +"SOME_DATETIME": " 01JAN1960:11:39:08", +"SOME_TIME": " 0:01:13", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10185, +"SOME_CHAR": "185 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.312568983209, +"SOME_DATE": "27FEB1962", +"SOME_DATETIME": " 01JAN1960:11:13:19", +"SOME_TIME": " 0:01:19", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10186, +"SOME_CHAR": "186 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.17449143863, +"SOME_DATE": "03MAR1962", +"SOME_DATETIME": " 01JAN1960:13:34:59", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 11 +}, +{ +"PRIMARY_KEY_FIELD": 10187, +"SOME_CHAR": "187 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.967759952865, +"SOME_DATE": "14OCT1960", +"SOME_DATETIME": " 01JAN1960:13:48:30", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10188, +"SOME_CHAR": "188 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.891128778407, +"SOME_DATE": "05MAR1960", +"SOME_DATETIME": " 01JAN1960:05:28:49", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 10189, +"SOME_CHAR": "189 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0667286301342, +"SOME_DATE": "17MAR1960", +"SOME_DATETIME": " 01JAN1960:07:56:56", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 62, +"SOME_BESTNUM": 87 +}, +{ +"PRIMARY_KEY_FIELD": 10190, +"SOME_CHAR": "190 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.940826008069, +"SOME_DATE": "27MAY1960", +"SOME_DATETIME": " 01JAN1960:11:42:13", +"SOME_TIME": " 0:00:34", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 10191, +"SOME_CHAR": "191 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.310336881462, +"SOME_DATE": "16APR1962", +"SOME_DATETIME": " 01JAN1960:08:35:10", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 17 +}, +{ +"PRIMARY_KEY_FIELD": 10192, +"SOME_CHAR": "192 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.187635322654, +"SOME_DATE": "03DEC1960", +"SOME_DATETIME": " 01JAN1960:11:15:21", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 83 +}, +{ +"PRIMARY_KEY_FIELD": 10193, +"SOME_CHAR": "193 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.962409494427, +"SOME_DATE": "18OCT1960", +"SOME_DATETIME": " 01JAN1960:04:17:51", +"SOME_TIME": " 0:00:49", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10194, +"SOME_CHAR": "194 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.818376173181, +"SOME_DATE": "23FEB1961", +"SOME_DATETIME": " 01JAN1960:11:08:28", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10195, +"SOME_CHAR": "195 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.249898561393, +"SOME_DATE": "01NOV1961", +"SOME_DATETIME": " 01JAN1960:04:15:44", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10196, +"SOME_CHAR": "196 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.303004053097, +"SOME_DATE": "24JAN1961", +"SOME_DATETIME": " 01JAN1960:06:32:50", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 49 +}, +{ +"PRIMARY_KEY_FIELD": 10197, +"SOME_CHAR": "197 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.724311870394, +"SOME_DATE": "10SEP1960", +"SOME_DATETIME": " 01JAN1960:09:12:28", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 61 +}, +{ +"PRIMARY_KEY_FIELD": 10198, +"SOME_CHAR": "198 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.281540174634, +"SOME_DATE": "17SEP1962", +"SOME_DATETIME": " 01JAN1960:01:33:10", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 70, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 10199, +"SOME_CHAR": "199 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.919220488015, +"SOME_DATE": "08MAY1960", +"SOME_DATETIME": " 01JAN1960:09:33:28", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 0 +}, +{ +"PRIMARY_KEY_FIELD": 10200, +"SOME_CHAR": "200 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.505939372585, +"SOME_DATE": "17APR1960", +"SOME_DATETIME": " 01JAN1960:05:14:10", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10201, +"SOME_CHAR": "201 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.143907736123, +"SOME_DATE": "04AUG1962", +"SOME_DATETIME": " 01JAN1960:04:44:27", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10202, +"SOME_CHAR": "202 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.221468285295, +"SOME_DATE": "02SEP1961", +"SOME_DATETIME": " 01JAN1960:06:49:19", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 49, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10203, +"SOME_CHAR": "203 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.258218495761, +"SOME_DATE": "25OCT1961", +"SOME_DATETIME": " 01JAN1960:09:37:09", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10204, +"SOME_CHAR": "204 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0766677759013, +"SOME_DATE": "11APR1961", +"SOME_DATETIME": " 01JAN1960:07:32:18", +"SOME_TIME": " 0:00:26", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 10205, +"SOME_CHAR": "205 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.993368008171, +"SOME_DATE": "25NOV1961", +"SOME_DATETIME": " 01JAN1960:04:29:28", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10206, +"SOME_CHAR": "206 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.872760605473, +"SOME_DATE": "30JUL1961", +"SOME_DATETIME": " 01JAN1960:07:00:29", +"SOME_TIME": " 0:01:20", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 10207, +"SOME_CHAR": "207 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.789409748646, +"SOME_DATE": "07JAN1960", +"SOME_DATETIME": " 01JAN1960:13:04:56", +"SOME_TIME": " 0:00:26", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 10208, +"SOME_CHAR": "208 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.34292900066, +"SOME_DATE": "15JAN1960", +"SOME_DATETIME": " 01JAN1960:08:44:18", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 10209, +"SOME_CHAR": "209 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.853056217475, +"SOME_DATE": "20SEP1962", +"SOME_DATETIME": " 01JAN1960:00:37:31", +"SOME_TIME": " 0:01:26", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10210, +"SOME_CHAR": "210 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.1569773956, +"SOME_DATE": "17JUL1960", +"SOME_DATETIME": " 01JAN1960:12:40:44", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10211, +"SOME_CHAR": "211 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.28367675109, +"SOME_DATE": "25JUN1962", +"SOME_DATETIME": " 01JAN1960:03:47:07", +"SOME_TIME": " 0:00:42", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10212, +"SOME_CHAR": "212 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.319825820774, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:02:02:49", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10213, +"SOME_CHAR": "213 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.236386205645, +"SOME_DATE": "10OCT1961", +"SOME_DATETIME": " 01JAN1960:12:17:24", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 55 +}, +{ +"PRIMARY_KEY_FIELD": 10214, +"SOME_CHAR": "214 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.742101271051, +"SOME_DATE": "25JAN1960", +"SOME_DATETIME": " 01JAN1960:05:39:56", +"SOME_TIME": " 0:01:34", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 25 +}, +{ +"PRIMARY_KEY_FIELD": 10215, +"SOME_CHAR": "215 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.863742849726, +"SOME_DATE": "15MAR1960", +"SOME_DATETIME": " 01JAN1960:13:30:58", +"SOME_TIME": " 0:01:40", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10216, +"SOME_CHAR": "216 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.750501612551, +"SOME_DATE": "29FEB1960", +"SOME_DATETIME": " 01JAN1960:12:48:41", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 20, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10217, +"SOME_CHAR": "217 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.665220306099, +"SOME_DATE": "21SEP1962", +"SOME_DATETIME": " 01JAN1960:11:47:48", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 86 +}, +{ +"PRIMARY_KEY_FIELD": 10218, +"SOME_CHAR": "218 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.314111363755, +"SOME_DATE": "17OCT1961", +"SOME_DATETIME": " 01JAN1960:07:34:23", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10219, +"SOME_CHAR": "219 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.475602078007, +"SOME_DATE": "14MAY1961", +"SOME_DATETIME": " 01JAN1960:13:32:24", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 39 +}, +{ +"PRIMARY_KEY_FIELD": 10220, +"SOME_CHAR": "220 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.292178807451, +"SOME_DATE": "14MAY1961", +"SOME_DATETIME": " 01JAN1960:03:16:05", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 10221, +"SOME_CHAR": "221 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.342086964446, +"SOME_DATE": "21FEB1962", +"SOME_DATETIME": " 01JAN1960:13:35:14", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10222, +"SOME_CHAR": "222 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.361870947928, +"SOME_DATE": "18JAN1960", +"SOME_DATETIME": " 01JAN1960:09:45:01", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 32, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10223, +"SOME_CHAR": "223 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.571696416741, +"SOME_DATE": "12SEP1960", +"SOME_DATETIME": " 01JAN1960:11:04:22", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10224, +"SOME_CHAR": "224 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.819183359304, +"SOME_DATE": "22FEB1960", +"SOME_DATETIME": " 01JAN1960:00:11:18", +"SOME_TIME": " 0:00:48", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 10225, +"SOME_CHAR": "225 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0242283884549, +"SOME_DATE": "26MAR1960", +"SOME_DATETIME": " 01JAN1960:11:41:08", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 16, +"SOME_BESTNUM": 80 +}, +{ +"PRIMARY_KEY_FIELD": 10226, +"SOME_CHAR": "226 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.418458293387, +"SOME_DATE": "29OCT1960", +"SOME_DATETIME": " 01JAN1960:06:51:07", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 21, +"SOME_BESTNUM": 94 +}, +{ +"PRIMARY_KEY_FIELD": 10227, +"SOME_CHAR": "227 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.855226562757, +"SOME_DATE": "26JAN1960", +"SOME_DATETIME": " 01JAN1960:01:22:42", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 16, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10228, +"SOME_CHAR": "228 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.612432046613, +"SOME_DATE": "30JUL1960", +"SOME_DATETIME": " 01JAN1960:08:13:43", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 47 +}, +{ +"PRIMARY_KEY_FIELD": 10229, +"SOME_CHAR": "229 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0565994717444, +"SOME_DATE": "14JUN1962", +"SOME_DATETIME": " 01JAN1960:12:06:18", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 43 +}, +{ +"PRIMARY_KEY_FIELD": 10230, +"SOME_CHAR": "230 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.234995038824, +"SOME_DATE": "05MAY1961", +"SOME_DATETIME": " 01JAN1960:01:11:48", +"SOME_TIME": " 0:01:02", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10231, +"SOME_CHAR": "231 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905498261054, +"SOME_DATE": "04FEB1961", +"SOME_DATETIME": " 01JAN1960:01:50:23", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 33, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10232, +"SOME_CHAR": "232 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.489890096006, +"SOME_DATE": "14JAN1962", +"SOME_DATETIME": " 01JAN1960:07:07:05", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10233, +"SOME_CHAR": "233 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.458665252877, +"SOME_DATE": "06AUG1960", +"SOME_DATETIME": " 01JAN1960:12:28:55", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 54 +}, +{ +"PRIMARY_KEY_FIELD": 10234, +"SOME_CHAR": "234 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.85541833977, +"SOME_DATE": "01OCT1961", +"SOME_DATETIME": " 01JAN1960:06:53:06", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 89 +}, +{ +"PRIMARY_KEY_FIELD": 10235, +"SOME_CHAR": "235 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.857599226226, +"SOME_DATE": "30OCT1961", +"SOME_DATETIME": " 01JAN1960:06:13:30", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 99 +}, +{ +"PRIMARY_KEY_FIELD": 10236, +"SOME_CHAR": "236 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.844420214111, +"SOME_DATE": "11APR1960", +"SOME_DATETIME": " 01JAN1960:00:27:45", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10237, +"SOME_CHAR": "237 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.474337428098, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:06:48:00", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10238, +"SOME_CHAR": "238 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.326561977773, +"SOME_DATE": "31MAY1961", +"SOME_DATETIME": " 01JAN1960:12:12:34", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 94, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10239, +"SOME_CHAR": "239 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.921823682693, +"SOME_DATE": "13DEC1961", +"SOME_DATETIME": " 01JAN1960:01:20:43", +"SOME_TIME": " 0:01:11", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10240, +"SOME_CHAR": "240 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.121250483264, +"SOME_DATE": "18DEC1960", +"SOME_DATETIME": " 01JAN1960:02:34:37", +"SOME_TIME": " 0:00:22", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10241, +"SOME_CHAR": "241 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.949745169352, +"SOME_DATE": "07JUN1961", +"SOME_DATETIME": " 01JAN1960:06:48:37", +"SOME_TIME": " 0:00:34", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10242, +"SOME_CHAR": "242 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.255982018661, +"SOME_DATE": "13MAR1962", +"SOME_DATETIME": " 01JAN1960:07:37:42", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 76, +"SOME_BESTNUM": 70 +}, +{ +"PRIMARY_KEY_FIELD": 10243, +"SOME_CHAR": "243 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.759833389781, +"SOME_DATE": "28JUN1960", +"SOME_DATETIME": " 01JAN1960:08:19:49", +"SOME_TIME": " 0:01:01", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10244, +"SOME_CHAR": "244 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.700597827183, +"SOME_DATE": "24JUL1960", +"SOME_DATETIME": " 01JAN1960:05:10:15", +"SOME_TIME": " 0:00:38", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10245, +"SOME_CHAR": "245 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.221195794745, +"SOME_DATE": "05SEP1960", +"SOME_DATETIME": " 01JAN1960:08:59:36", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10246, +"SOME_CHAR": "246 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.200741445739, +"SOME_DATE": "24MAR1960", +"SOME_DATETIME": " 01JAN1960:02:29:02", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 88 +}, +{ +"PRIMARY_KEY_FIELD": 10247, +"SOME_CHAR": "247 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.287490293517, +"SOME_DATE": "24JUL1961", +"SOME_DATETIME": " 01JAN1960:02:55:57", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10248, +"SOME_CHAR": "248 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.561167126783, +"SOME_DATE": "25JUN1960", +"SOME_DATETIME": " 01JAN1960:02:01:02", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 49, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 10249, +"SOME_CHAR": "249 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.349366858299, +"SOME_DATE": "28FEB1961", +"SOME_DATETIME": " 01JAN1960:04:26:52", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 25 +}, +{ +"PRIMARY_KEY_FIELD": 10250, +"SOME_CHAR": "250 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.253183987575, +"SOME_DATE": "04FEB1961", +"SOME_DATETIME": " 01JAN1960:03:37:40", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10251, +"SOME_CHAR": "251 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.747167228603, +"SOME_DATE": "14APR1960", +"SOME_DATETIME": " 01JAN1960:10:00:45", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 10252, +"SOME_CHAR": "252 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.27761360038, +"SOME_DATE": "13SEP1961", +"SOME_DATETIME": " 01JAN1960:09:09:05", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 10253, +"SOME_CHAR": "253 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.10966447094, +"SOME_DATE": "04APR1962", +"SOME_DATETIME": " 01JAN1960:00:26:22", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10254, +"SOME_CHAR": "254 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.205800468198, +"SOME_DATE": "30MAY1961", +"SOME_DATETIME": " 01JAN1960:13:20:29", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 12 +}, +{ +"PRIMARY_KEY_FIELD": 10255, +"SOME_CHAR": "255 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.253791187077, +"SOME_DATE": "12JUN1961", +"SOME_DATETIME": " 01JAN1960:05:43:23", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 50, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 10256, +"SOME_CHAR": "256 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.916653747632, +"SOME_DATE": "06DEC1960", +"SOME_DATETIME": " 01JAN1960:09:22:08", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 18 +} +] +, "$viewdata":{"vars":{ +"PRIMARY_KEY_FIELD" :{"format":"best." ,"label":"PRIMARY_KEY_FIELD" ,"length":"8" ,"type":"num" } +,"SOME_CHAR" :{"format":"$32767." ,"label":"SOME_CHAR" ,"length":"32767" ,"type":"char" } +,"SOME_DROPDOWN" :{"format":"$128." ,"label":"SOME_DROPDOWN" ,"length":"128" ,"type":"char" } +,"SOME_NUM" :{"format":"best." ,"label":"SOME_NUM" ,"length":"8" ,"type":"num" } +,"SOME_DATE" :{"format":"DATE9." ,"label":"SOME_DATE" ,"length":"8" ,"type":"num" } +,"SOME_DATETIME" :{"format":"DATETIME19." ,"label":"SOME_DATETIME" ,"length":"8" ,"type":"num" } +,"SOME_TIME" :{"format":"TIME8." ,"label":"SOME_TIME" ,"length":"8" ,"type":"num" } +,"SOME_SHORTNUM" :{"format":"best." ,"label":"SOME_SHORTNUM" ,"length":"4" ,"type":"num" } +,"SOME_BESTNUM" :{"format":"BEST." ,"label":"SOME_BESTNUM" ,"length":"8" ,"type":"num" } +}} +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewdata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057BBE1CAC140BA860000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:49.746000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/viewlibs.js b/sas/mocks/sas9/sasjs/services/public/viewlibs.js new file mode 100644 index 0000000..166308b --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/viewlibs.js @@ -0,0 +1,135 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "saslibs": +[ +{ +"LIBRARYID": "A59LNVZG.B500000F", +"LIBRARYNAME": "Catalog Sales", +"LIBRARYREF": "catsles", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000D", +"LIBRARYNAME": "Dash", +"LIBRARYREF": "dash", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000K", +"LIBRARYNAME": "Data Controller(DC996664)", +"LIBRARYREF": "DC996664", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000G", +"LIBRARYNAME": "Decision Optimization", +"LIBRARYREF": "DO", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000B", +"LIBRARYNAME": "DemoData", +"LIBRARYREF": "DemoData", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000E", +"LIBRARYNAME": "Digital_Intelligence", +"LIBRARYREF": "Digital", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000008", +"LIBRARYNAME": "Environment Manager Data Mart LASR", +"LIBRARYREF": "EVDMLA", +"ENGINE": "SASIOLA" +}, +{ +"LIBRARYID": "A59LNVZG.B500000C", +"LIBRARYNAME": "Orion Star", +"LIBRARYREF": "orstar", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000001", +"LIBRARYNAME": "SASApp - SASDATA", +"LIBRARYREF": "SASDATA", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000005", +"LIBRARYNAME": "SASApp - valib", +"LIBRARYREF": "valib", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000002", +"LIBRARYNAME": "SASApp - wrsdist", +"LIBRARYREF": "wrsdist", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000003", +"LIBRARYNAME": "SASApp - wrstemp", +"LIBRARYREF": "wrstemp", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000009", +"LIBRARYNAME": "STP Samples", +"LIBRARYREF": "stpsamp", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000I", +"LIBRARYNAME": "Sankey", +"LIBRARYREF": "sankey", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B500000J", +"LIBRARYNAME": "VA Solar Farm - Source Data", +"LIBRARYREF": "Solarsrc", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000006", +"LIBRARYNAME": "Visual Analytics LASR", +"LIBRARYREF": "VALIBLA", +"ENGINE": "SASIOLA" +}, +{ +"LIBRARYID": "A59LNVZG.B5000004", +"LIBRARYNAME": "Visual Analytics Public Data Provider", +"LIBRARYREF": "DPPUBLIC", +"ENGINE": "BASE" +}, +{ +"LIBRARYID": "A59LNVZG.B5000007", +"LIBRARYNAME": "Visual Analytics Public LASR", +"LIBRARYREF": "LASRLIB", +"ENGINE": "SASIOLA" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewlibs" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057B8E6D91740B9650000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:36.451000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/public/viewtables.js b/sas/mocks/sas9/sasjs/services/public/viewtables.js new file mode 100644 index 0000000..9fdb543 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/public/viewtables.js @@ -0,0 +1,127 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "mptables": +[ +{ +"MEMNAME": "MPE_ALERTS" +}, +{ +"MEMNAME": "MPE_AUDIT" +}, +{ +"MEMNAME": "MPE_COLUMN_LEVEL_SECURITY" +}, +{ +"MEMNAME": "MPE_CONFIG" +}, +{ +"MEMNAME": "MPE_DATACATALOG_LIBS" +}, +{ +"MEMNAME": "MPE_DATACATALOG_TABS" +}, +{ +"MEMNAME": "MPE_DATACATALOG_VARS" +}, +{ +"MEMNAME": "MPE_DATADICTIONARY" +}, +{ +"MEMNAME": "MPE_DATALOADS" +}, +{ +"MEMNAME": "MPE_DATASTATUS_LIBS" +}, +{ +"MEMNAME": "MPE_DATASTATUS_TABS" +}, +{ +"MEMNAME": "MPE_EMAILS" +}, +{ +"MEMNAME": "MPE_EXCEL_CONFIG" +}, +{ +"MEMNAME": "MPE_FILTERANYTABLE" +}, +{ +"MEMNAME": "MPE_FILTERSOURCE" +}, +{ +"MEMNAME": "MPE_GROUPS" +}, +{ +"MEMNAME": "MPE_LINEAGE_COLS" +}, +{ +"MEMNAME": "MPE_LINEAGE_TABS" +}, +{ +"MEMNAME": "MPE_LOADS" +}, +{ +"MEMNAME": "MPE_LOCKANYTABLE" +}, +{ +"MEMNAME": "MPE_MAXKEYVALUES" +}, +{ +"MEMNAME": "MPE_REQUESTS" +}, +{ +"MEMNAME": "MPE_REVIEW" +}, +{ +"MEMNAME": "MPE_ROW_LEVEL_SECURITY" +}, +{ +"MEMNAME": "MPE_SECURITY" +}, +{ +"MEMNAME": "MPE_SELECTBOX" +}, +{ +"MEMNAME": "MPE_SIGNOFFS" +}, +{ +"MEMNAME": "MPE_SUBMIT" +}, +{ +"MEMNAME": "MPE_TABLES" +}, +{ +"MEMNAME": "MPE_USERS" +}, +{ +"MEMNAME": "MPE_VALIDATIONS" +}, +{ +"MEMNAME": "MPE_X_TEST" +} +] +, "libinfo": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewtables" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057BAACBC6A40B9E70000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:43.748000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/usernav/usergroupsbymember.js b/sas/mocks/sas9/sasjs/services/usernav/usergroupsbymember.js new file mode 100644 index 0000000..8e0e06b --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/usernav/usergroupsbymember.js @@ -0,0 +1,365 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "emails": +[ + +] +, "groups": +[ +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000W", +"GROUPNAME": "Data Management Business Approvers", +"GROUPDESC": "Business approvers of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000V", +"GROUPNAME": "Data Management Business Users", +"GROUPDESC": "Business users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001G", +"GROUPNAME": "Decision Manager Users", +"GROUPDESC": "Decision Manager Users Group" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000Y", +"GROUPNAME": "Data Management Executives", +"GROUPDESC": "Executive users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000X", +"GROUPNAME": "Data Management Power Users", +"GROUPDESC": "Power users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000P", +"GROUPNAME": "BI Web Services Users", +"GROUPDESC": "Allows members to create and delete SAS BI Web Services." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001O", +"GROUPNAME": "mdlmgradminusers", +"GROUPDESC": "Administrative Users for Model Manager" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001F", +"GROUPNAME": "Decision Manager Common Administrators", +"GROUPDESC": "Decision Manager Administrative Group" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001Q", +"GROUPNAME": "mdlmgrusers", +"GROUPDESC": "Limited write access users of Model Manager" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000U", +"GROUPNAME": "Data Management Stewards", +"GROUPDESC": "Steward users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000T", +"GROUPNAME": "Data Management Administrators", +"GROUPDESC": "Administrative users of the data management environment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001C", +"GROUPNAME": "BI Dashboard Administrators", +"GROUPDESC": "The members of this group are allowed to administer content for the SAS BI Dashboard product. The SAS Trusted User is made a member during initial deployment." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000013", +"GROUPNAME": "Visual Analytics Users", +"GROUPDESC": "Registered users of SAS Visual Analytics." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000J", +"GROUPNAME": "Visual Data Builder Administrators", +"GROUPDESC": "Visual Data Builder Administrators" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001D", +"GROUPNAME": "BI Dashboard Users", +"GROUPDESC": "The members of this group are allowed general viewing access of content for the SAS BI Dashboard product." +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000Q", +"GROUPNAME": "ThemeDesigner Administrators", +"GROUPDESC": "" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001P", +"GROUPNAME": "mdlmgradvusers", +"GROUPDESC": "Advanced Users for Model Manager" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000021", +"GROUPNAME": "Factory Miner Database Users", +"GROUPDESC": "" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000I", +"GROUPNAME": "Visual Analytics Data Administrators", +"GROUPDESC": "Visual Analytics Data Administrators" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001W", +"GROUPNAME": "SAS_EV_AppServer_Tier", +"GROUPDESC": "SAS Environment Manager App Server Tier Users" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001U", +"GROUPNAME": "SAS_EV_Super_User", +"GROUPDESC": "SAS Environment Manager Super Users" +}, +{ +"GROUPURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001V", +"GROUPNAME": "SAS_EV_Guest", +"GROUPDESC": "SAS Environment Manager Guests" +} +] +, "roles": +[ +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000B", +"ROLENAME": "Add-In for Microsoft Office: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in PivotTables and provides other capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000N", +"ROLENAME": "Job Execution: Job Designer", +"ROLEDESC": "Provides job and task definition capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000S", +"ROLENAME": "Fonts Administrator", +"ROLEDESC": "Font Administrator can reload fonts to update the fonts metadata." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000014", +"ROLENAME": "Visual Analytics: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001R", +"ROLENAME": "mdlmgradminusage", +"ROLEDESC": "Provides ability to perform all Model Manager tasks" +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000016", +"ROLENAME": "Visual Analytics: Data Building", +"ROLEDESC": "Provides data preparation capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001Z", +"ROLENAME": "Factory Miner: User", +"ROLEDESC": "Provides Factory Miner User capabilities to create projects and run models." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000M", +"ROLENAME": "Job Execution: Job Submitter", +"ROLEDESC": "Provides normal job submission capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001N", +"ROLENAME": "SAS Studio: Report Consumer", +"ROLEDESC": "Provides access to view or run existing SAS Studio reports without general access to SAS programming environment." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001M", +"ROLENAME": "SAS Studio: Usage", +"ROLEDESC": "Provides access to the SAS programming environment." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000K", +"ROLENAME": "Comments: Administrator", +"ROLEDESC": "" +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001A", +"ROLENAME": "Web Report Studio: Report Creation", +"ROLEDESC": "Provides report creation capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001Y", +"ROLENAME": "Time Series Studio: User", +"ROLEDESC": "Enables normal user access to the product and features." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000009", +"ROLENAME": "Add-In for Microsoft Office: Advanced", +"ROLEDESC": "Provides all capabilities in the SAS Add-In for Microsoft Office." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000C", +"ROLENAME": "Enterprise Guide: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Enterprise Guide." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001E", +"ROLENAME": "BI Dashboard: Administration", +"ROLEDESC": "Provides SAS BI Dashboard administration capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000O", +"ROLENAME": "Job Execution: Job Scheduler", +"ROLEDESC": "Provides job scheduling capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000R", +"ROLENAME": "Theme Designer: Administration", +"ROLEDESC": "Provides Theme Designer administration capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001S", +"ROLENAME": "mdlmgradvusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for administrative tasks" +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001H", +"ROLENAME": "Decision Manager Common: Administration", +"ROLEDESC": "Decision Manager Common Administrative role" +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000012", +"ROLENAME": "Home: Usage", +"ROLEDESC": "Provides all non-administrative capabilities for the home page (hub)." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001J", +"ROLENAME": "Forecast Server: Analyst", +"ROLEDESC": "Provides capabiliites for a Forecasting Analyst." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000L", +"ROLENAME": "Job Execution: Job Administrator", +"ROLEDESC": "Provides all capabilities for the Job Execution Service, a component of the Web Infra Platform Services." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000020", +"ROLENAME": "Factory Miner: Admin", +"ROLEDESC": "Provides Factory Miner Admin capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000E", +"ROLENAME": "Enterprise Guide: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in the OLAP Analyzer and provides other capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001I", +"ROLENAME": "Forecast Server: Browser", +"ROLEDESC": "Provides basic forecasting viewing and reporting capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001T", +"ROLENAME": "mdlmgrusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for advanced or administrative tasks" +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001X", +"ROLENAME": "Time Series Studio: Administrator", +"ROLEDESC": "Enables administrator access to the product and features, including access to all product content regardless of ownership." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001K", +"ROLENAME": "Forecast Server: Forecaster", +"ROLEDESC": "Provides capabilities for a Forecaster." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000011", +"ROLENAME": "Home: Administration", +"ROLEDESC": "Provides all capabilities for the home page (hub)." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001B", +"ROLENAME": "Web Report Studio: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Web Report Studio except the manage report distribution capability." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000D", +"ROLENAME": "Enterprise Guide: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500001L", +"ROLENAME": "Forecast Server: Administrator", +"ROLEDESC": "Provides capabilities for a Forecasting Administrator." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000Z", +"ROLENAME": "Lineage: Administration", +"ROLEDESC": "Provides all functionality related to administrative activities for the SAS Lineage application." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000017", +"ROLENAME": "Visual Analytics: Administration", +"ROLEDESC": "Provides administrative capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000019", +"ROLENAME": "Web Report Studio: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000F", +"ROLENAME": "Enterprise Guide: Programming", +"ROLEDESC": "Provides SAS programming, stored process authoring, and other capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000018", +"ROLENAME": "Visual Analytics: Basic", +"ROLEDESC": "Provides functionality for guest access (if applicable) and entry-level users." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000010", +"ROLENAME": "Data Management: Lineage", +"ROLEDESC": "Provides default access to the SAS Lineage application." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A500000A", +"ROLENAME": "Add-In for Microsoft Office: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "OMSOBJ:IdentityGroup\A59LNVZG.A5000015", +"ROLENAME": "Visual Analytics: Analysis", +"ROLEDESC": "If SAS Visual Statistics is licensed, provides the Build Analytical Model capability." +} +] +, "logins": +[ +{ +"DOMAIN": "DefaultAuth", +"USERID": "SAS\sasdemo" +} +] +, "info": +[ +{ +"NAME": "sasdemo", +"DISPLAYNAME": "SAS Demo User", +"METADATACREATED": "19Aug2020:06:22:00", +"METADATAUPDATED": "19Aug2020:06:22:00" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usergroupsbymember" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E09DF3B640C28A0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:15.304000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/usernav/usermembers.js b/sas/mocks/sas9/sasjs/services/usernav/usermembers.js new file mode 100644 index 0000000..4abcd2b --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/usernav/usermembers.js @@ -0,0 +1,125 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "users": +[ +{ +"URI": "A59LNVZG.AP000006", +"NAME": "fsmeta" +}, +{ +"URI": "A59LNVZG.AP000001", +"NAME": "sasadm" +}, +{ +"URI": "A59LNVZG.AP000003", +"NAME": "sasdemo" +}, +{ +"URI": "A59LNVZG.AP000007", +"NAME": "sasevs" +}, +{ +"URI": "A59LNVZG.AP000009", +"NAME": "sasfcmr" +}, +{ +"URI": "A59LNVZG.AP000005", +"NAME": "sassearch" +},{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "users": +[ +{ +"URI": "A59LNVZG.AP000006", +"NAME": "fsmeta" +}, +{ +"URI": "A59LNVZG.AP000001", +"NAME": "sasadm" +}, +{ +"URI": "A59LNVZG.AP000003", +"NAME": "sasdemo" +}, +{ +"URI": "A59LNVZG.AP000007", +"NAME": "sasevs" +}, +{ +"URI": "A59LNVZG.AP000009", +"NAME": "sasfcmr" +}, +{ +"URI": "A59LNVZG.AP000005", +"NAME": "sassearch" +}, +{ +"URI": "A59LNVZG.AP000002", +"NAME": "sastrust" +}, +{ +"URI": "A59LNVZG.AP000008", +"NAME": "tssmeta" +}, +{ +"URI": "A59LNVZG.AP000004", +"NAME": "webanon" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usermembers" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E02428F640C25D0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:12.995000" +,"MEMSIZE" : "46GB" +} +{ +"URI": "A59LNVZG.AP000002", +"NAME": "sastrust" +}, +{ +"URI": "A59LNVZG.AP000008", +"NAME": "tssmeta" +}, +{ +"URI": "A59LNVZG.AP000004", +"NAME": "webanon" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usermembers" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E02428F640C25D0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:12.995000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/usernav/usermembersbygroup.js b/sas/mocks/sas9/sasjs/services/usernav/usermembersbygroup.js new file mode 100644 index 0000000..5cb0dd3 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/usernav/usermembersbygroup.js @@ -0,0 +1,55 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "sasmembers": +[ +{ +"URIMEM": "OMSOBJ:Person\A59LNVZG.AP000002", +"GROUPID": "A59LNVZG.A500001C", +"GROUPNAME": "BI Dashboard Administrators", +"GROUP_OR_ROLE": "UserGroup", +"MEMBERNAME": "sastrust", +"MEMBERTYPE": "User", +"MEMBERUPDATED": "19Aug2020:06:21:44", +"MEMBERCREATED": "19Aug2020:06:21:44", +"EMAILURI": "", +"GROUPDESC": "The members of this group are allowed to administer content for the SAS BI Dashboard product. The SAS Trusted User is made a member during initial deployment.", +"EMAIL": "", +"EMAILRC": -4 +}, +{ +"URIMEM": "OMSOBJ:Person\A59LNVZG.AP000003", +"GROUPID": "A59LNVZG.A500001C", +"GROUPNAME": "BI Dashboard Administrators", +"GROUP_OR_ROLE": "UserGroup", +"MEMBERNAME": "sasdemo", +"MEMBERTYPE": "User", +"MEMBERUPDATED": "19Aug2020:06:22:00", +"MEMBERCREATED": "19Aug2020:06:22:00", +"EMAILURI": "", +"GROUPDESC": "The members of this group are allowed to administer content for the SAS BI Dashboard product. The SAS Trusted User is made a member during initial deployment.", +"EMAIL": "", +"EMAILRC": -4 +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usermembersbygroup" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E17EB85240C2E28000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:18.468000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/usernav/usermembersbyrole.js b/sas/mocks/sas9/sasjs/services/usernav/usermembersbyrole.js new file mode 100644 index 0000000..2608043 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/usernav/usermembersbyrole.js @@ -0,0 +1,46 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "sasgroups": +[ +{ +"URIMEM": "OMSOBJ:IdentityGroup\A59LNVZG.A5000002", +"MEMBERNAME": "PUBLIC", +"MEMBERTYPE": "UserGroup", +"MEMBERUPDATED": "19Aug2020:06:21:05", +"MEMBERCREATED": "19Aug2020:06:21:05", +"EMAIL": "" +} +] +, "sasmembers": +[ +{ +"URIMEM": "OMSOBJ:Person\A59LNVZG.AP000003", +"MEMBERNAME": "sasdemo", +"MEMBERTYPE": "User", +"MEMBERUPDATED": "19Aug2020:06:22:00", +"MEMBERCREATED": "19Aug2020:06:22:00", +"EMAIL": "" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usermembersbyrole" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E21AB02140C3090000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:20.946000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sas9/sasjs/services/usernav/userroles.js b/sas/mocks/sas9/sasjs/services/usernav/userroles.js new file mode 100644 index 0000000..6719725 --- /dev/null +++ b/sas/mocks/sas9/sasjs/services/usernav/userroles.js @@ -0,0 +1,257 @@ +_webout=`{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "roles": +[ +{ +"ROLEURI": "A59LNVZG.A5000009", +"ROLENAME": "Add-In for Microsoft Office: Advanced", +"ROLEDESC": "Provides all capabilities in the SAS Add-In for Microsoft Office." +}, +{ +"ROLEURI": "A59LNVZG.A500000A", +"ROLENAME": "Add-In for Microsoft Office: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000B", +"ROLENAME": "Add-In for Microsoft Office: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in PivotTables and provides other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001E", +"ROLENAME": "BI Dashboard: Administration", +"ROLEDESC": "Provides SAS BI Dashboard administration capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000K", +"ROLENAME": "Comments: Administrator", +"ROLEDESC": "" +}, +{ +"ROLEURI": "A59LNVZG.A5000010", +"ROLENAME": "Data Management: Lineage", +"ROLEDESC": "Provides default access to the SAS Lineage application." +}, +{ +"ROLEURI": "A59LNVZG.A500001H", +"ROLENAME": "Decision Manager Common: Administration", +"ROLEDESC": "Decision Manager Common Administrative role" +}, +{ +"ROLEURI": "A59LNVZG.A500000C", +"ROLENAME": "Enterprise Guide: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Enterprise Guide." +}, +{ +"ROLEURI": "A59LNVZG.A500000D", +"ROLENAME": "Enterprise Guide: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000E", +"ROLENAME": "Enterprise Guide: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in the OLAP Analyzer and provides other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000F", +"ROLENAME": "Enterprise Guide: Programming", +"ROLEDESC": "Provides SAS programming, stored process authoring, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A5000020", +"ROLENAME": "Factory Miner: Admin", +"ROLEDESC": "Provides Factory Miner Admin capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001Z", +"ROLENAME": "Factory Miner: User", +"ROLEDESC": "Provides Factory Miner User capabilities to create projects and run models." +}, +{ +"ROLEURI": "A59LNVZG.A500000S", +"ROLENAME": "Fonts Administrator", +"ROLEDESC": "Font Administrator can reload fonts to update the fonts metadata." +}, +{ +"ROLEURI": "A59LNVZG.A500001L", +"ROLENAME": "Forecast Server: Administrator", +"ROLEDESC": "Provides capabilities for a Forecasting Administrator." +}, +{ +"ROLEURI": "A59LNVZG.A500001J", +"ROLENAME": "Forecast Server: Analyst", +"ROLEDESC": "Provides capabiliites for a Forecasting Analyst." +}, +{ +"ROLEURI": "A59LNVZG.A500001I", +"ROLENAME": "Forecast Server: Browser", +"ROLEDESC": "Provides basic forecasting viewing and reporting capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001K", +"ROLENAME": "Forecast Server: Forecaster", +"ROLEDESC": "Provides capabilities for a Forecaster." +}, +{ +"ROLEURI": "A59LNVZG.A5000011", +"ROLENAME": "Home: Administration", +"ROLEDESC": "Provides all capabilities for the home page (hub)." +}, +{ +"ROLEURI": "A59LNVZG.A5000012", +"ROLENAME": "Home: Usage", +"ROLEDESC": "Provides all non-administrative capabilities for the home page (hub)." +}, +{ +"ROLEURI": "A59LNVZG.A500000L", +"ROLENAME": "Job Execution: Job Administrator", +"ROLEDESC": "Provides all capabilities for the Job Execution Service, a component of the Web Infra Platform Services." +}, +{ +"ROLEURI": "A59LNVZG.A500000N", +"ROLENAME": "Job Execution: Job Designer", +"ROLEDESC": "Provides job and task definition capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000O", +"ROLENAME": "Job Execution: Job Scheduler", +"ROLEDESC": "Provides job scheduling capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000M", +"ROLENAME": "Job Execution: Job Submitter", +"ROLEDESC": "Provides normal job submission capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000Z", +"ROLENAME": "Lineage: Administration", +"ROLEDESC": "Provides all functionality related to administrative activities for the SAS Lineage application." +}, +{ +"ROLEURI": "A59LNVZG.A5000006", +"ROLENAME": "META: Operators Role", +"ROLEDESC": "Supports adding repositories and operating the metadata server [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A5000004", +"ROLENAME": "META: Unrestricted Users Role", +"ROLEDESC": "Provides all capabilities in SAS Management Console and provides access to all metadata [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A5000005", +"ROLENAME": "META: User and Group Administrators Role", +"ROLEDESC": "Supports management of users, groups, and roles other than the unrestricted role [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A500000G", +"ROLENAME": "Management Console: Advanced", +"ROLEDESC": "Provides access to all plug-ins in SAS Management Console." +}, +{ +"ROLEURI": "A59LNVZG.A500000H", +"ROLENAME": "Management Console: Content Management", +"ROLEDESC": "Provides access to the Folders tab, User Manager, Library Manager, and Authorization Manager." +}, +{ +"ROLEURI": "A59LNVZG.A500001N", +"ROLENAME": "SAS Studio: Report Consumer", +"ROLEDESC": "Provides access to view or run existing SAS Studio reports without general access to SAS programming environment." +}, +{ +"ROLEURI": "A59LNVZG.A500001M", +"ROLENAME": "SAS Studio: Usage", +"ROLEDESC": "Provides access to the SAS programming environment." +}, +{ +"ROLEURI": "A59LNVZG.A500000R", +"ROLENAME": "Theme Designer: Administration", +"ROLEDESC": "Provides Theme Designer administration capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001X", +"ROLENAME": "Time Series Studio: Administrator", +"ROLEDESC": "Enables administrator access to the product and features, including access to all product content regardless of ownership." +}, +{ +"ROLEURI": "A59LNVZG.A500001Y", +"ROLENAME": "Time Series Studio: User", +"ROLEDESC": "Enables normal user access to the product and features." +}, +{ +"ROLEURI": "A59LNVZG.A5000017", +"ROLENAME": "Visual Analytics: Administration", +"ROLEDESC": "Provides administrative capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A5000015", +"ROLENAME": "Visual Analytics: Analysis", +"ROLEDESC": "If SAS Visual Statistics is licensed, provides the Build Analytical Model capability." +}, +{ +"ROLEURI": "A59LNVZG.A5000018", +"ROLENAME": "Visual Analytics: Basic", +"ROLEDESC": "Provides functionality for guest access (if applicable) and entry-level users." +}, +{ +"ROLEURI": "A59LNVZG.A5000016", +"ROLENAME": "Visual Analytics: Data Building", +"ROLEDESC": "Provides data preparation capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A5000014", +"ROLENAME": "Visual Analytics: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A500001B", +"ROLENAME": "Web Report Studio: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Web Report Studio except the manage report distribution capability." +}, +{ +"ROLEURI": "A59LNVZG.A500001A", +"ROLENAME": "Web Report Studio: Report Creation", +"ROLEDESC": "Provides report creation capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A5000019", +"ROLENAME": "Web Report Studio: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001R", +"ROLENAME": "mdlmgradminusage", +"ROLEDESC": "Provides ability to perform all Model Manager tasks" +}, +{ +"ROLEURI": "A59LNVZG.A500001S", +"ROLENAME": "mdlmgradvusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for administrative tasks" +}, +{ +"ROLEURI": "A59LNVZG.A500001T", +"ROLENAME": "mdlmgrusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for advanced or administrative tasks" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/userroles" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057DF99CAC140C2300000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "X64_DSRV16" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:10.892000" +,"MEMSIZE" : "46GB" +}` diff --git a/sas/mocks/sasjs/.sasjslint b/sas/mocks/sasjs/.sasjslint new file mode 100644 index 0000000..15a6260 --- /dev/null +++ b/sas/mocks/sasjs/.sasjslint @@ -0,0 +1,13 @@ +{ + "noEncodedPasswords": true, + "hasDoxygenHeader": true, + "hasMacroNameInMend": true, + "hasMacroParentheses": true, + "indentationMultiple": 2, + "lowerCaseFileNames": true, + "maxLineLength": 107, + "noNestedMacros": true, + "noSpacesInFileNames": true, + "noTabIndentation": true, + "noTrailingSpaces": true +} \ No newline at end of file diff --git a/sas/mocks/sasjs/mock-storage/licence.json b/sas/mocks/sasjs/mock-storage/licence.json new file mode 100644 index 0000000..2973720 --- /dev/null +++ b/sas/mocks/sasjs/mock-storage/licence.json @@ -0,0 +1,4 @@ +{ + "licenceKey": "CFG2LNF1SYGgRPTwegsgRolmXw0xQmDpbagjRTniIarWXFE+/eClT4m+64U2kL5BBj0p3UwS80+wEer+jaw5w4OX27mDfXAUvkv90k54ER6GP5C5Z/t4VYucQo3Kn8wfhfFOymjRVtKZaHyavl9hBaWGwohX7W+97gsj5pnI9a/63w55OKNJvgeZrCxR04qhRiuf9K1J5EQtKP+wfW/ERoX3R4dPWKANjyFZkURs2GL/UDCGS6nPWTS8grlcinFUhh4V3hIZmzlWc5FG97lrbxnmq4FsdEaey4z4l70H4Yf/52ZZqJzaOyRGeQXmUtpS", + "activationKey": "MIIEbQIBADANBgkqhkiG9w0BAQEFAASCBFcwggRTAgEAAoHxAM0ayGUZgn7ZBBoEDwGYbTaKf85WIGInISinE2WisHZv6AaivG/tNo/K+Ms7b2EnwvIg4vUKKbKtoD9E3Fk1B0LV2qmKlv+TcZQ0YXXhRguaHcewGcwof7aJr+iTrD4CoL/H7gs3JvVshCRq7bfX59dXDlVdm8TkDglQMTyxX+L3JirAII4xbbJ7cTNoBnzgyi4n2Aa0+zFlq2WDzRjECxdcAm79lipQRW/AOjPFxEYIjOl+Uzv9yxOGdrFLAJkCznhnWC+D28qCaM+vCEDDW9tvmSdf7nsnlY46xud6sNnVgO/1LvC3VGkZ5zNZCx9XRwIDAQABAoHwT0qjXjJWeKN9KnGXO46p6gPxFNvG+SsXbpfor8oNXjw0/xu6raqPBVf6htcbX/v3KZP9Ka4cIK9u3AbLCNGvVO9H8XNanMNrjVgStXe5lJKoIKK71mlxtifUkZ1FYVOywXGRXVSdAxRIoauU6xXU0zMcn3Po3F0tPpi/C5xCcz0eOjLCx+eJc3U2IZKsQ7lHO7azCT9woguj09/xVW0481T6zuF6e0Oq4MWlt0qJPkkuLcMF6ps+ObHUB3044VDcm6X7kZjtcwnj886Y6n9llTNzHiui4R5eMSzm1w57jwR5m/Q1AOTGCyiW1KLI1eIBAnkA8Ma4zvkn44w0E1Dlrq/97vdJsUiE7Ifs5DknRU81imm0+LP2yyX7tBRpVcvrVkH2x/qW3bHLHFdV5o9A262Wcqdk2ZkMHp+gD59OsrcbRBokiwqU6nagLbYbC7RA2PZRMR48s8bWAnzFae0P8FFJlmKUHggarUDnAnkA2hKrOplw1C0X2QVeVQOlU36PjayVJEwkxq30k0wg+q9F464TrraRr5uFqMrAmwGN5ziZQ1Jzx3R2uBHft67FwXJfGy21Hor47sb+f5VkAuXPurbp6K+sMWRfIehK9/G9Iju90Iv6Oto4uv/yfdWadxCLc8tYy4qhAngUA/EJA51VRSpvEKKHSwoI+3WczzJ9ly8SKc4h7Nu+jdsFcbBqYtXxumCnSTRfD0y8gxBXjZgc2wXBDNePa3a+QTwY+qgPQ6XCprOcF6yklKfFBzQp6YKXSjQlXO6nGpLVSnYxW64ettCSZaqVh6xeXAOEG5hcHrECeFTYEpqX/Ffwu2iKOCtnYblcckmyrcwTe/N41sFAS0x9SPnOToYZLhFett/3Eny8XBNr5+VTfQxK+a2f9qSmcPZUo0AVxnP9qeBst7O30dN2yh1g8RzAzIPjA0hT8mcJPIbHK5CqBU9Ee/H1hskChDhyzW7d3MxEQQJ4QB6FIMNVQQh05iIB64SzxVvpI/ggOKDGO2/b2zILsKWiw4NhppEphmhXvuJy5TGFYERoGydaW6dKfau6rDSWGNbjPuFwmkUTUjzh2gR5rCp0Ifapd6D5sWDFaI+F4gEUaxmC9yJL8i6/JpMx3LRut1g5dsH6chhT" +} \ No newline at end of file diff --git a/sas/mocks/sasjs/sasjsconfig.json b/sas/mocks/sasjs/sasjsconfig.json new file mode 100644 index 0000000..8124a60 --- /dev/null +++ b/sas/mocks/sasjs/sasjsconfig.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://raw.githubusercontent.com/sasjs/utils/main/src/types/sasjsconfig-schema.json", + "defaultTarget": "server-mihajlo", + "syncFolder": "sasjs", + "targets": [ + { + "name": "server-ci", + "serverUrl": "http://localhost:5000", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": true + }, + "appLoc": "/Public/app/devtest" + }, + { + "name": "server-mihajlo", + "serverUrl": "https://sas.4gl.io:5002", + "serverType": "SASJS", + "httpsAgentOptions": { + "rejectUnauthorized": false, + "allowInsecureRequests": true + }, + "appLoc": "/Public/app/dc" + }, + { + "name": "dcdemo", + "serverUrl": "https://sas.4gl.io:5006", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/Public/app/dc" + } + ] +} \ No newline at end of file diff --git a/sas/mocks/sasjs/services/admin/dummy.js b/sas/mocks/sasjs/services/admin/dummy.js new file mode 100644 index 0000000..a1c2098 --- /dev/null +++ b/sas/mocks/sasjs/services/admin/dummy.js @@ -0,0 +1 @@ +// this file is just here to force the creation of the admin folder diff --git a/sas/mocks/sasjs/services/admin/registerkey.js b/sas/mocks/sasjs/services/admin/registerkey.js new file mode 100644 index 0000000..ae979df --- /dev/null +++ b/sas/mocks/sasjs/services/admin/registerkey.js @@ -0,0 +1,39 @@ +const path = require('path') + +let appLoc = path.join(..._program.split('services')[0].split('/')) +let licenceKey = '' +let activationKey = '' + +let writeError = 0 + +if (_WEBIN_FILEREF1) { + const fileText = _WEBIN_FILEREF1.toString() + const split = fileText.split('\n')[1].split(',') + activationKey = split[0] + licenceKey = split[1] +} + +const sessionStoragePath = path.resolve(__dirname, '..', '..', 'drive', 'files', appLoc, 'mock-storage') + +if (!fs.existsSync(sessionStoragePath)){ + fs.mkdirSync(sessionStoragePath); +} + +const licenceStore = path.resolve(sessionStoragePath, 'licence.json') + +const json = { + licenceKey: licenceKey, + activationKey: activationKey +} + +try { + fs.writeFileSync(licenceStore, JSON.stringify(json)) +} catch (err) { + writeError = 1 +} + +if (writeError) { + _webout = `{ "return": [{ "MSG": "Error writing licence file" }] }` +} else { + _webout = `{ "return": [{ "MSG": "SUCCESS" }] }` +} \ No newline at end of file diff --git a/sas/mocks/sasjs/services/approvers/getapprovals.js b/sas/mocks/sasjs/services/approvers/getapprovals.js new file mode 100644 index 0000000..820b43d --- /dev/null +++ b/sas/mocks/sasjs/services/approvers/getapprovals.js @@ -0,0 +1,29 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:27" +, "fromsas": +[ +{"TABLE_ID":"DC20221006T142649516_059582_7169" ,"REVIEW_STATUS_ID":"SUBMITTED" ,"SUBMITTED_BY_NM":"mihajlo" ,"BASE_TABLE":"DC988196.MPE_X_TEST" ,"SUBMITTED_ON_DTTM":"2022-10-06 14:26:49" ,"SUBMITTED_ON_DTTM2":1980685609.6 ,"SUBMITTED_REASON_TXT":"" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"NUM_OF_APPROVALS_REMAINING":1 ,"LIBREF":"DC988196" ,"DSN":"MPE_X_TEST" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/mihajlo/services/approvers/getapprovals" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221006142704-37564-1665066424699%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B74E36BAC30000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717200" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:27:25.363516" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/approvers/gethistory.js b/sas/mocks/sasjs/services/approvers/gethistory.js new file mode 100644 index 0000000..2f0ca73 --- /dev/null +++ b/sas/mocks/sasjs/services/approvers/gethistory.js @@ -0,0 +1,39 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "fromsas": +[ +{ +"TABLE_ID": "DC20220926T084322234_729360_2744", +"BASE_TABLE": "DC996664.MPE_X_TEST", +"SUBMITTED": " 2022-09-26 08:43:22", +"SUBMITTED_REASON_TXT": "", +"SUBMITTER": "sasdemo", +"REVIEWED": " 2022-09-26 08:43:52", +"STATUS": "APPROVED", +"REVIEWED_ON_DTTM": 1979801032.54, +"APPROVER": "sasdemo" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/approvers/gethistory" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD805772B147AE40AB1E0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:55.321000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/approvers/rejection.js b/sas/mocks/sasjs/services/approvers/rejection.js new file mode 100644 index 0000000..539765a --- /dev/null +++ b/sas/mocks/sasjs/services/approvers/rejection.js @@ -0,0 +1,38 @@ +_webout = `{"SYSDATE" : "27SEP22" +,"SYSTIME" : "07:56" +, "fromsas": +[ + { + "RESPONSE": "SUCCESS!", + "TABLE_ID": "DC20220927T075630819_560700_2598", + "REVIEWED_BY_NM": "sasdemo", + "BASE_TABLE": "DC996664.MPE_X_TEST", + "REVIEW_STATUS_ID": "REJECTED", + "REVIEWED_ON_DTTM": "27SEP22:07:56:53.47", + "REVIEW_REASON_TXT": "Test" + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/approvers/rejection" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80A91145F3B64092AC0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25980" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-27T07:56:53.688000" +,"MEMSIZE" : "82GB" +} + +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/auditors/getstagetable.js b/sas/mocks/sasjs/services/auditors/getstagetable.js new file mode 100644 index 0000000..2592ea4 --- /dev/null +++ b/sas/mocks/sasjs/services/auditors/getstagetable.js @@ -0,0 +1,29 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "stagetable": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_BESTNUM":44 ,"SOME_CHAR":"this is changed data" ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_SHORTNUM":3 ,"SOME_TIME":42 ,"_____DELETE__THIS__RECORD_____":"No" } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/auditors/getstagetable" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576B5820C540A6200000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-09-26T08:43:25.714000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/auditors/postdata.js b/sas/mocks/sasjs/services/auditors/postdata.js new file mode 100644 index 0000000..c54f7a2 --- /dev/null +++ b/sas/mocks/sasjs/services/auditors/postdata.js @@ -0,0 +1,110 @@ +_webout = `{"SYSDATE" : "07OCT22" +,"SYSTIME" : "12:25" +, "params": +[ +{"TABLE_ID":"DC20221007T122326121_612316_7259" ,"SUBMIT_STATUS_CD":"SUBMITTED" ,"BASE_LIB":"DC988196" ,"BASE_DS":"MPE_X_TEST" ,"SUBMITTED_BY_NM":"mihajlo" ,"SUBMITTED_ON_DTTM":1980764606.22 ,"SUBMITTED_REASON_TXT":"" ,"INPUT_OBS":15 ,"INPUT_VARS":10 ,"NUM_OF_APPROVALS_REQUIRED":1 ,"NUM_OF_APPROVALS_REMAINING":1 ,"REVIEWED_BY_NM":"" ,"REVIEWED_ON_DTTM":null ,"LIBDS":"DC988196.MPE_X_TEST" ,"REVIEWED_ON":"." ,"DIFFTIME":"07OCT22:12:25:57.40" ,"DIFFS_CSV":"tempDiffs_20221007_122559.csv" ,"FILESIZE":"684.0KB" ,"FILESIZE_RAW":700416 ,"TRUNCATED":"NO" ,"NUM_ADDED":6 ,"NUM_DELETED":4 ,"NUM_UPDATED":5 ,"SUBMITTED_ON":"07OCT2022:12:23:26" ,"ISAPPROVER":"YES" } +] +, "cols": +[ +{"NAME":"PRIMARY_KEY_FIELD" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"" } +,{"NAME":"SOME_CHAR" ,"TYPE":2 ,"LENGTH":32767 ,"FORMAT":"" } +,{"NAME":"SOME_DROPDOWN" ,"TYPE":2 ,"LENGTH":128 ,"FORMAT":"" } +,{"NAME":"SOME_NUM" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"" } +,{"NAME":"SOME_DATE" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"DATE" } +,{"NAME":"SOME_DATETIME" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"DATETIME" } +,{"NAME":"SOME_TIME" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"TIME" } +,{"NAME":"SOME_SHORTNUM" ,"TYPE":1 ,"LENGTH":4 ,"FORMAT":"" } +,{"NAME":"SOME_BESTNUM" ,"TYPE":1 ,"LENGTH":8 ,"FORMAT":"BEST" } +] +, "submits": +[ +{"TABLE_ID":"DC20221007T122119628_344949_7254" ,"SUBMIT_STATUS_CD":"SUBMITTED" ,"BASE_LIB":"DC988196" ,"BASE_DS":"MPE_X_TEST" ,"SUBMITTED_BY_NM":"mihajlo" ,"SUBMITTED_ON_DTTM":1980764479.74 ,"SUBMITTED_REASON_TXT":"" ,"INPUT_OBS":15 ,"INPUT_VARS":10 ,"NUM_OF_APPROVALS_REQUIRED":1 ,"NUM_OF_APPROVALS_REMAINING":1 ,"REVIEWED_BY_NM":"" ,"REVIEWED_ON_DTTM":null } +,{"TABLE_ID":"DC20221006T142649516_059582_7169" ,"SUBMIT_STATUS_CD":"SUBMITTED" ,"BASE_LIB":"DC988196" ,"BASE_DS":"MPE_X_TEST" ,"SUBMITTED_BY_NM":"mihajlo" ,"SUBMITTED_ON_DTTM":1980685609.6 ,"SUBMITTED_REASON_TXT":"" ,"INPUT_OBS":1 ,"INPUT_VARS":10 ,"NUM_OF_APPROVALS_REQUIRED":1 ,"NUM_OF_APPROVALS_REMAINING":1 ,"REVIEWED_BY_NM":"" ,"REVIEWED_ON_DTTM":null } +] +, "deleted": +[ +{"PRIMARY_KEY_FIELD":1016 ,"SOME_CHAR":"16 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6963824517 ,"SOME_DATE":790 ,"SOME_DATETIME":null ,"SOME_TIME":60 ,"SOME_SHORTNUM":27 ,"SOME_BESTNUM":84 } +,{"PRIMARY_KEY_FIELD":1017 ,"SOME_CHAR":"17 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.476432963 ,"SOME_DATE":432 ,"SOME_DATETIME":null ,"SOME_TIME":60 ,"SOME_SHORTNUM":6 ,"SOME_BESTNUM":93 } +,{"PRIMARY_KEY_FIELD":1018 ,"SOME_CHAR":"18 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.498669565 ,"SOME_DATE":754 ,"SOME_DATETIME":null ,"SOME_TIME":0 ,"SOME_SHORTNUM":87 ,"SOME_BESTNUM":29 } +,{"PRIMARY_KEY_FIELD":1019 ,"SOME_CHAR":"19 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7999903256 ,"SOME_DATE":492 ,"SOME_DATETIME":null ,"SOME_TIME":60 ,"SOME_SHORTNUM":4 ,"SOME_BESTNUM":15 } +] +, "new": +[ +{"PRIMARY_KEY_FIELD":10101234 ,"SOME_CHAR":"10 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3297298762 ,"SOME_DATE":728 ,"SOME_DATETIME":null ,"SOME_TIME":60 ,"SOME_SHORTNUM":52 ,"SOME_BESTNUM":23 } +,{"PRIMARY_KEY_FIELD":10101235 ,"SOME_CHAR":"11 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4249602912 ,"SOME_DATE":456 ,"SOME_DATETIME":null ,"SOME_TIME":60 ,"SOME_SHORTNUM":37 ,"SOME_BESTNUM":91 } +,{"PRIMARY_KEY_FIELD":10101236 ,"SOME_CHAR":"12 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5175091785 ,"SOME_DATE":383 ,"SOME_DATETIME":null ,"SOME_TIME":0 ,"SOME_SHORTNUM":53 ,"SOME_BESTNUM":5 } +,{"PRIMARY_KEY_FIELD":10101237 ,"SOME_CHAR":"13 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1282490171 ,"SOME_DATE":650 ,"SOME_DATETIME":20160 ,"SOME_TIME":0 ,"SOME_SHORTNUM":74 ,"SOME_BESTNUM":88 } +,{"PRIMARY_KEY_FIELD":10101238 ,"SOME_CHAR":"14 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9579004319 ,"SOME_DATE":203 ,"SOME_DATETIME":20160 ,"SOME_TIME":0 ,"SOME_SHORTNUM":51 ,"SOME_BESTNUM":65 } +,{"PRIMARY_KEY_FIELD":10101239 ,"SOME_CHAR":"15 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4804529285 ,"SOME_DATE":155 ,"SOME_DATETIME":23820 ,"SOME_TIME":0 ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":88 } +] +, "updates": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":null ,"SOME_TIME":0 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":1 ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":null ,"SOME_TIME":420 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":2 ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":null ,"SOME_TIME":120 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":3 ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":1613.001 ,"SOME_DATE":423 ,"SOME_DATETIME":null ,"SOME_TIME":0 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":4 ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":1613.0011235 ,"SOME_DATE":4231 ,"SOME_DATETIME":null ,"SOME_TIME":360 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +] +, "originals": +[ +{"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_TIME":42 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":1 ,"SOME_CHAR":"more dummy data" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_TIME":422 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":2 ,"SOME_CHAR":"even more dummy data" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":42 ,"SOME_DATE":42 ,"SOME_DATETIME":42 ,"SOME_TIME":142 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":3 ,"SOME_CHAR":"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":1613.001 ,"SOME_DATE":423 ,"SOME_DATETIME":423 ,"SOME_TIME":44 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"PRIMARY_KEY_FIELD":4 ,"SOME_CHAR":"if you can fill the unforgiving minute" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":1613.001123456 ,"SOME_DATE":4231 ,"SOME_DATETIME":423123123 ,"SOME_TIME":412 ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +] +, "fmt_deleted": +[ +{"PRIMARY_KEY_FIELD":"1016" ,"SOME_CHAR":"16 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.6963824517" ,"SOME_DATE":"01MAR1962" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:01:00" ,"SOME_SHORTNUM":"27" ,"SOME_BESTNUM":"84" } +,{"PRIMARY_KEY_FIELD":"1017" ,"SOME_CHAR":"17 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.476432963" ,"SOME_DATE":"08MAR1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:01:00" ,"SOME_SHORTNUM":"6" ,"SOME_BESTNUM":"93" } +,{"PRIMARY_KEY_FIELD":"1018" ,"SOME_CHAR":"18 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.498669565" ,"SOME_DATE":"24JAN1962" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"87" ,"SOME_BESTNUM":"29" } +,{"PRIMARY_KEY_FIELD":"1019" ,"SOME_CHAR":"19 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.7999903256" ,"SOME_DATE":"07MAY1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:01:00" ,"SOME_SHORTNUM":"4" ,"SOME_BESTNUM":"15" } +] +, "fmt_new": +[ +{"PRIMARY_KEY_FIELD":"10101234" ,"SOME_CHAR":"10 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.3297298762" ,"SOME_DATE":"29DEC1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:01:00" ,"SOME_SHORTNUM":"52" ,"SOME_BESTNUM":"23" } +,{"PRIMARY_KEY_FIELD":"10101235" ,"SOME_CHAR":"11 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.4249602912" ,"SOME_DATE":"01APR1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:01:00" ,"SOME_SHORTNUM":"37" ,"SOME_BESTNUM":"91" } +,{"PRIMARY_KEY_FIELD":"10101236" ,"SOME_CHAR":"12 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.5175091785" ,"SOME_DATE":"18JAN1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"53" ,"SOME_BESTNUM":"5" } +,{"PRIMARY_KEY_FIELD":"10101237" ,"SOME_CHAR":"13 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.1282490171" ,"SOME_DATE":"12OCT1961" ,"SOME_DATETIME":"01JAN1960:05:36:00" ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"74" ,"SOME_BESTNUM":"88" } +,{"PRIMARY_KEY_FIELD":"10101238" ,"SOME_CHAR":"14 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.9579004319" ,"SOME_DATE":"22JUL1960" ,"SOME_DATETIME":"01JAN1960:05:36:00" ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"51" ,"SOME_BESTNUM":"65" } +,{"PRIMARY_KEY_FIELD":"10101239" ,"SOME_CHAR":"15 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"0.4804529285" ,"SOME_DATE":"04JUN1960" ,"SOME_DATETIME":"01JAN1960:06:37:00" ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"28" ,"SOME_BESTNUM":"88" } +] +, "fmt_updates": +[ +{"PRIMARY_KEY_FIELD":"0" ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"1" ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:07:00" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"2" ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:02:00" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"3" ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":"1613.001" ,"SOME_DATE":"27FEB1961" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:00:00" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"4" ,"SOME_CHAR":"updated row" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"1613.0011235" ,"SOME_DATE":"02AUG1971" ,"SOME_DATETIME":"." ,"SOME_TIME":"0:06:00" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +] +, "fmt_originals": +[ +{"PRIMARY_KEY_FIELD":"0" ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"01JAN1960:00:00:42" ,"SOME_TIME":"0:00:42" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"1" ,"SOME_CHAR":"more dummy data" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"01JAN1960:00:00:42" ,"SOME_TIME":"0:07:02" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"2" ,"SOME_CHAR":"even more dummy data" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":"42" ,"SOME_DATE":"12FEB1960" ,"SOME_DATETIME":"01JAN1960:00:00:42" ,"SOME_TIME":"0:02:22" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"3" ,"SOME_CHAR":"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":"1613.001" ,"SOME_DATE":"27FEB1961" ,"SOME_DATETIME":"01JAN1960:00:07:03" ,"SOME_TIME":"0:00:44" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +,{"PRIMARY_KEY_FIELD":"4" ,"SOME_CHAR":"if you can fill the unforgiving minute" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":"1613.0011235" ,"SOME_DATE":"02AUG1971" ,"SOME_DATETIME":"29MAY1973:06:12:03" ,"SOME_TIME":"0:06:52" ,"SOME_SHORTNUM":"3" ,"SOME_BESTNUM":"44" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/mihajlo/services/auditors/postdata" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221007122541-37053-1665145541605%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD84049178EB530000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "726676" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-07T12:26:00.209420" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/editors/getdata.js b/sas/mocks/sasjs/services/editors/getdata.js new file mode 100644 index 0000000..623813f --- /dev/null +++ b/sas/mocks/sasjs/services/editors/getdata.js @@ -0,0 +1,982 @@ +const path = require('path') + +let FILTER_TEXT = '' + +let appLoc = path.join(..._program.split('services')[0].split('/')) +const sessionStoragePath = path.resolve(__dirname, '..', '..', 'drive', 'files', appLoc, 'mock-storage') +const filterStore = path.resolve(sessionStoragePath, 'filter.txt') + +let sasControlTableFileText = '' + +if (_WEBIN_FILENAME1.includes('SASControlTable')) sasControlTableFileText = _WEBIN_FILEREF1.toString() + +if (sasControlTableFileText.includes('1,WEB')) { //it is filter_pk = 1 + try { + FILTER_TEXT = fs.readFileSync(filterStore, {encoding:'utf8'}).toString() + } catch (err) { + + } +} + +FILTER_TEXT = FILTER_TEXT.replace(/\"/gmi, '\\"') + +let webouts = { + MPE_X_TEST: `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:30" +, "approvers": +[ +{ +"PERSONNAME": "sasdemo", +"EMAIL": "sasdemo", +"USERID": "sasdemo" +} +] +, "cols": +[ +{ +"NAME": "PRIMARY_KEY_FIELD", +"VARNUM": 1, +"LABEL": "PRIMARY_KEY_FIELD", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_BESTNUM", +"VARNUM": 9, +"LABEL": "SOME_BESTNUM", +"FMTNAME": "BEST", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_CHAR", +"VARNUM": 2, +"LABEL": "SOME_CHAR", +"FMTNAME": "", +"DDTYPE": "CHARACTER", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DATE", +"VARNUM": 5, +"LABEL": "SOME_DATE", +"FMTNAME": "DATE", +"DDTYPE": "DATE", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DATETIME", +"VARNUM": 6, +"LABEL": "SOME_DATETIME", +"FMTNAME": "DATETIME", +"DDTYPE": "DATETIME", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_DROPDOWN", +"VARNUM": 3, +"LABEL": "SOME_DROPDOWN", +"FMTNAME": "", +"DDTYPE": "CHARACTER", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_NUM", +"VARNUM": 4, +"LABEL": "SOME_NUM", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_SHORTNUM", +"VARNUM": 8, +"LABEL": "SOME_SHORTNUM", +"FMTNAME": "", +"DDTYPE": "NUMERIC", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +}, +{ +"NAME": "SOME_TIME", +"VARNUM": 7, +"LABEL": "SOME_TIME", +"FMTNAME": "TIME", +"DDTYPE": "TIME", +"CLS_RULE": "READ", +"MEMLABEL": "", +"DESC": "", +"LONGDESC": "" +} +] +, "dqdata": +[ +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 1", +"SELECTBOX_ORDER": 1 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 2", +"SELECTBOX_ORDER": 2 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "Option 3", +"SELECTBOX_ORDER": 2 +}, +{ +"BASE_COL": "SOME_DROPDOWN", +"RULE_VALUE": "SOME_DROPDOWN", +"RULE_DATA": "This is a long option. This option is very long. It is optional, though.", +"SELECTBOX_ORDER": 3 +} +] +, "dqrules": +[ +{ +"BASE_COL": "PRIMARY_KEY_FIELD", +"RULE_TYPE": "NOTNULL", +"RULE_VALUE": "", +"X": 0 +}, +{ +"BASE_COL": "SOME_NUM", +"RULE_TYPE": "HARDSELECT_HOOK", +"RULE_VALUE": "services/validations/mpe_x_test.some_num", +"X": 0 +} +] +, "dsmeta": +[ +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Name", +"VALUE": "DC996664.MPE_X_TEST" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observations", +"VALUE": "496" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Member Type", +"VALUE": "DATA" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Variables", +"VALUE": "9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Engine", +"VALUE": "V9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Indexes", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Created", +"VALUE": "09/26/2022 08:24:39" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Integrity Constraints", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Last Modified", +"VALUE": "09/26/2022 08:24:45" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observation Length", +"VALUE": "32947" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Protection", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Deleted Observations", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Type", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Compressed", +"VALUE": "CHAR" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Label", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Reuse Space", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Representation", +"VALUE": "WINDOWS_64" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Point to Observations", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Encoding", +"VALUE": "wlatin1 Western (Windows)" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Sorted", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Data Set Page Size", +"VALUE": "262144" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Pages", +"VALUE": "3" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Index File Page Size", +"VALUE": "4096" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Index File Pages", +"VALUE": "4" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Repairs", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "ExtendObsCounter", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Filename", +"VALUE": "C:\DataController\DC996664\mpe_x_test.sas7bdat" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Release Created", +"VALUE": "9.0401M7" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Host Created", +"VALUE": "Linunx" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Owner Name", +"VALUE": "BUILTIN\Administrators" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size", +"VALUE": " 1MB" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size (bytes)", +"VALUE": "1048576" +} +] +, "maxvarlengths": +[ +{ +"NAME": "_____DELETE__THIS__RECORD_____", +"MAXLEN": 3 +}, +{ +"NAME": "PRIMARY_KEY_FIELD", +"MAXLEN": 4 +}, +{ +"NAME": "some_char", +"MAXLEN": 591 +}, +{ +"NAME": "some_dropdown", +"MAXLEN": 8 +}, +{ +"NAME": "some_num", +"MAXLEN": 8 +}, +{ +"NAME": "some_date", +"MAXLEN": 10 +}, +{ +"NAME": "some_datetime", +"MAXLEN": 19 +}, +{ +"NAME": "some_time", +"MAXLEN": 8 +}, +{ +"NAME": "some_shortnum", +"MAXLEN": 3 +}, +{ +"NAME": "some_bestnum", +"MAXLEN": 3 +} +] +, "query": +[ + +] +, "sasdata": +[ +{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":0 ,"SOME_CHAR":"this is dummy data" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:00:42" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1 ,"SOME_CHAR":"more dummy data" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:07:02" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":2 ,"SOME_CHAR":"even more dummy data" ,"SOME_DROPDOWN":"Option 3" ,"SOME_NUM":42 ,"SOME_DATE":"1960-02-12" ,"SOME_DATETIME":"1960-01-01 00:00:42" ,"SOME_TIME":"00:02:22" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":3 ,"SOME_CHAR":"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:" ,"SOME_DROPDOWN":"Option 2" ,"SOME_NUM":1613.001 ,"SOME_DATE":"1961-02-27" ,"SOME_DATETIME":"1960-01-01 00:07:03" ,"SOME_TIME":"00:00:44" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":4 ,"SOME_CHAR":"if you can fill the unforgiving minute" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":1613.0011235 ,"SOME_DATE":"1971-08-02" ,"SOME_DATETIME":"1973-05-29 06:12:03" ,"SOME_TIME":"00:06:52" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1010 ,"SOME_CHAR":"10 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3677867113 ,"SOME_DATE":"1961-03-05" ,"SOME_DATETIME":"1960-01-01 08:16:44" ,"SOME_TIME":"00:00:35" ,"SOME_SHORTNUM":1 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1011 ,"SOME_CHAR":"11 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8693330497 ,"SOME_DATE":"1961-01-20" ,"SOME_DATETIME":"1960-01-01 01:25:19" ,"SOME_TIME":"00:00:01" ,"SOME_SHORTNUM":6 ,"SOME_BESTNUM":54 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1012 ,"SOME_CHAR":"12 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5432779065 ,"SOME_DATE":"1961-10-06" ,"SOME_DATETIME":"1960-01-01 02:57:35" ,"SOME_TIME":"00:00:35" ,"SOME_SHORTNUM":54 ,"SOME_BESTNUM":62 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1013 ,"SOME_CHAR":"13 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5051939867 ,"SOME_DATE":"1962-02-20" ,"SOME_DATETIME":"1960-01-01 06:47:55" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":38 ,"SOME_BESTNUM":4 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1014 ,"SOME_CHAR":"14 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0130502507 ,"SOME_DATE":"1960-01-13" ,"SOME_DATETIME":"1960-01-01 03:48:13" ,"SOME_TIME":"00:00:14" ,"SOME_SHORTNUM":92 ,"SOME_BESTNUM":57 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1015 ,"SOME_CHAR":"15 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5822708009 ,"SOME_DATE":"1962-07-12" ,"SOME_DATETIME":"1960-01-01 12:05:18" ,"SOME_TIME":"00:00:54" ,"SOME_SHORTNUM":92 ,"SOME_BESTNUM":80 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1016 ,"SOME_CHAR":"16 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1382724979 ,"SOME_DATE":"1960-08-29" ,"SOME_DATETIME":"1960-01-01 02:48:01" ,"SOME_TIME":"00:00:01" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":91 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1017 ,"SOME_CHAR":"17 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.892701324 ,"SOME_DATE":"1961-09-14" ,"SOME_DATETIME":"1960-01-01 07:03:58" ,"SOME_TIME":"00:01:37" ,"SOME_SHORTNUM":91 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1018 ,"SOME_CHAR":"18 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1852788567 ,"SOME_DATE":"1961-03-08" ,"SOME_DATETIME":"1960-01-01 00:22:48" ,"SOME_TIME":"00:00:32" ,"SOME_SHORTNUM":93 ,"SOME_BESTNUM":79 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1019 ,"SOME_CHAR":"19 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0737551018 ,"SOME_DATE":"1961-01-24" ,"SOME_DATETIME":"1960-01-01 03:14:33" ,"SOME_TIME":"00:00:21" ,"SOME_SHORTNUM":22 ,"SOME_BESTNUM":90 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1020 ,"SOME_CHAR":"20 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7128569939 ,"SOME_DATE":"1961-02-08" ,"SOME_DATETIME":"1960-01-01 01:50:23" ,"SOME_TIME":"00:01:40" ,"SOME_SHORTNUM":65 ,"SOME_BESTNUM":34 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1021 ,"SOME_CHAR":"21 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6706138443 ,"SOME_DATE":"1961-03-09" ,"SOME_DATETIME":"1960-01-01 04:52:55" ,"SOME_TIME":"00:00:13" ,"SOME_SHORTNUM":44 ,"SOME_BESTNUM":97 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1022 ,"SOME_CHAR":"22 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1423215792 ,"SOME_DATE":"1962-07-22" ,"SOME_DATETIME":"1960-01-01 07:25:01" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":66 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1023 ,"SOME_CHAR":"23 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1259848066 ,"SOME_DATE":"1962-09-01" ,"SOME_DATETIME":"1960-01-01 09:32:34" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":44 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1024 ,"SOME_CHAR":"24 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3899468637 ,"SOME_DATE":"1961-12-06" ,"SOME_DATETIME":"1960-01-01 06:53:51" ,"SOME_TIME":"00:00:33" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":90 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1025 ,"SOME_CHAR":"25 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0310356193 ,"SOME_DATE":"1960-03-01" ,"SOME_DATETIME":"1960-01-01 02:58:07" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":73 ,"SOME_BESTNUM":59 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1026 ,"SOME_CHAR":"26 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9057884239 ,"SOME_DATE":"1960-10-04" ,"SOME_DATETIME":"1960-01-01 11:17:28" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":82 ,"SOME_BESTNUM":46 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1027 ,"SOME_CHAR":"27 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5920675856 ,"SOME_DATE":"1962-07-15" ,"SOME_DATETIME":"1960-01-01 03:35:41" ,"SOME_TIME":"00:00:22" ,"SOME_SHORTNUM":46 ,"SOME_BESTNUM":73 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1028 ,"SOME_CHAR":"28 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6580030046 ,"SOME_DATE":"1960-10-08" ,"SOME_DATETIME":"1960-01-01 13:13:30" ,"SOME_TIME":"00:00:40" ,"SOME_SHORTNUM":35 ,"SOME_BESTNUM":40 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1029 ,"SOME_CHAR":"29 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.807042594 ,"SOME_DATE":"1960-12-26" ,"SOME_DATETIME":"1960-01-01 11:57:14" ,"SOME_TIME":"00:00:19" ,"SOME_SHORTNUM":80 ,"SOME_BESTNUM":12 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1030 ,"SOME_CHAR":"30 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8801450408 ,"SOME_DATE":"1961-05-15" ,"SOME_DATETIME":"1960-01-01 10:11:05" ,"SOME_TIME":"00:00:25" ,"SOME_SHORTNUM":70 ,"SOME_BESTNUM":19 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1031 ,"SOME_CHAR":"31 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4150194705 ,"SOME_DATE":"1962-01-27" ,"SOME_DATETIME":"1960-01-01 11:27:09" ,"SOME_TIME":"00:01:04" ,"SOME_SHORTNUM":94 ,"SOME_BESTNUM":48 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1032 ,"SOME_CHAR":"32 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9743401203 ,"SOME_DATE":"1962-01-09" ,"SOME_DATETIME":"1960-01-01 07:44:35" ,"SOME_TIME":"00:01:07" ,"SOME_SHORTNUM":43 ,"SOME_BESTNUM":3 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1033 ,"SOME_CHAR":"33 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2035595692 ,"SOME_DATE":"1960-09-07" ,"SOME_DATETIME":"1960-01-01 11:52:19" ,"SOME_TIME":"00:00:42" ,"SOME_SHORTNUM":29 ,"SOME_BESTNUM":56 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1034 ,"SOME_CHAR":"34 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6792435556 ,"SOME_DATE":"1960-04-21" ,"SOME_DATETIME":"1960-01-01 07:17:04" ,"SOME_TIME":"00:01:14" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":9 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1035 ,"SOME_CHAR":"35 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9494116972 ,"SOME_DATE":"1960-01-19" ,"SOME_DATETIME":"1960-01-01 10:15:38" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":91 ,"SOME_BESTNUM":10 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1036 ,"SOME_CHAR":"36 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5446134911 ,"SOME_DATE":"1960-10-26" ,"SOME_DATETIME":"1960-01-01 03:55:27" ,"SOME_TIME":"00:01:24" ,"SOME_SHORTNUM":72 ,"SOME_BESTNUM":36 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1037 ,"SOME_CHAR":"37 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.458775894 ,"SOME_DATE":"1960-11-21" ,"SOME_DATETIME":"1960-01-01 13:34:37" ,"SOME_TIME":"00:01:35" ,"SOME_SHORTNUM":97 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1038 ,"SOME_CHAR":"38 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1537194239 ,"SOME_DATE":"1961-05-06" ,"SOME_DATETIME":"1960-01-01 06:14:13" ,"SOME_TIME":"00:00:29" ,"SOME_SHORTNUM":60 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1039 ,"SOME_CHAR":"39 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4935002562 ,"SOME_DATE":"1960-06-05" ,"SOME_DATETIME":"1960-01-01 06:59:42" ,"SOME_TIME":"00:00:45" ,"SOME_SHORTNUM":95 ,"SOME_BESTNUM":55 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1040 ,"SOME_CHAR":"40 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.124728859 ,"SOME_DATE":"1961-03-09" ,"SOME_DATETIME":"1960-01-01 03:03:06" ,"SOME_TIME":"00:01:23" ,"SOME_SHORTNUM":35 ,"SOME_BESTNUM":79 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1041 ,"SOME_CHAR":"41 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2794422001 ,"SOME_DATE":"1962-07-06" ,"SOME_DATETIME":"1960-01-01 05:29:26" ,"SOME_TIME":"00:00:51" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1042 ,"SOME_CHAR":"42 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7030775499 ,"SOME_DATE":"1960-08-11" ,"SOME_DATETIME":"1960-01-01 12:11:24" ,"SOME_TIME":"00:00:38" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":97 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1043 ,"SOME_CHAR":"43 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0701107537 ,"SOME_DATE":"1961-01-29" ,"SOME_DATETIME":"1960-01-01 03:44:09" ,"SOME_TIME":"00:00:03" ,"SOME_SHORTNUM":25 ,"SOME_BESTNUM":8 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1044 ,"SOME_CHAR":"44 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6423292927 ,"SOME_DATE":"1962-01-15" ,"SOME_DATETIME":"1960-01-01 00:57:07" ,"SOME_TIME":"00:00:09" ,"SOME_SHORTNUM":97 ,"SOME_BESTNUM":37 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1045 ,"SOME_CHAR":"45 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7206447743 ,"SOME_DATE":"1961-10-14" ,"SOME_DATETIME":"1960-01-01 12:25:32" ,"SOME_TIME":"00:00:07" ,"SOME_SHORTNUM":58 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1046 ,"SOME_CHAR":"46 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0431997366 ,"SOME_DATE":"1960-09-12" ,"SOME_DATETIME":"1960-01-01 05:12:57" ,"SOME_TIME":"00:01:35" ,"SOME_SHORTNUM":17 ,"SOME_BESTNUM":8 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1047 ,"SOME_CHAR":"47 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3704071368 ,"SOME_DATE":"1960-07-01" ,"SOME_DATETIME":"1960-01-01 02:44:37" ,"SOME_TIME":"00:00:06" ,"SOME_SHORTNUM":45 ,"SOME_BESTNUM":26 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1048 ,"SOME_CHAR":"48 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.654417035 ,"SOME_DATE":"1961-05-04" ,"SOME_DATETIME":"1960-01-01 01:23:07" ,"SOME_TIME":"00:01:38" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":13 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1049 ,"SOME_CHAR":"49 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1300212565 ,"SOME_DATE":"1961-01-06" ,"SOME_DATETIME":"1960-01-01 05:27:29" ,"SOME_TIME":"00:01:21" ,"SOME_SHORTNUM":37 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1050 ,"SOME_CHAR":"50 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0058409725 ,"SOME_DATE":"1960-07-23" ,"SOME_DATETIME":"1960-01-01 00:04:24" ,"SOME_TIME":"00:00:40" ,"SOME_SHORTNUM":15 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1051 ,"SOME_CHAR":"51 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7239382587 ,"SOME_DATE":"1960-06-09" ,"SOME_DATETIME":"1960-01-01 03:15:09" ,"SOME_TIME":"00:00:04" ,"SOME_SHORTNUM":42 ,"SOME_BESTNUM":82 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1052 ,"SOME_CHAR":"52 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8319003712 ,"SOME_DATE":"1960-08-13" ,"SOME_DATETIME":"1960-01-01 07:38:35" ,"SOME_TIME":"00:00:36" ,"SOME_SHORTNUM":69 ,"SOME_BESTNUM":81 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1053 ,"SOME_CHAR":"53 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5030828875 ,"SOME_DATE":"1961-06-22" ,"SOME_DATETIME":"1960-01-01 11:25:29" ,"SOME_TIME":"00:00:53" ,"SOME_SHORTNUM":39 ,"SOME_BESTNUM":75 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1054 ,"SOME_CHAR":"54 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7148045514 ,"SOME_DATE":"1960-08-26" ,"SOME_DATETIME":"1960-01-01 10:10:09" ,"SOME_TIME":"00:00:39" ,"SOME_SHORTNUM":6 ,"SOME_BESTNUM":4 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1055 ,"SOME_CHAR":"55 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8557945787 ,"SOME_DATE":"1960-10-19" ,"SOME_DATETIME":"1960-01-01 02:17:32" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":93 ,"SOME_BESTNUM":36 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1056 ,"SOME_CHAR":"56 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9700463307 ,"SOME_DATE":"1962-07-11" ,"SOME_DATETIME":"1960-01-01 11:18:41" ,"SOME_TIME":"00:00:51" ,"SOME_SHORTNUM":25 ,"SOME_BESTNUM":35 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1057 ,"SOME_CHAR":"57 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9380399426 ,"SOME_DATE":"1961-06-26" ,"SOME_DATETIME":"1960-01-01 13:15:13" ,"SOME_TIME":"00:00:52" ,"SOME_SHORTNUM":57 ,"SOME_BESTNUM":66 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1058 ,"SOME_CHAR":"58 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8484499486 ,"SOME_DATE":"1960-06-02" ,"SOME_DATETIME":"1960-01-01 01:14:51" ,"SOME_TIME":"00:00:00" ,"SOME_SHORTNUM":80 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1059 ,"SOME_CHAR":"59 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1415707628 ,"SOME_DATE":"1961-07-28" ,"SOME_DATETIME":"1960-01-01 06:33:16" ,"SOME_TIME":"00:00:58" ,"SOME_SHORTNUM":11 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1060 ,"SOME_CHAR":"60 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.282674513 ,"SOME_DATE":"1962-03-27" ,"SOME_DATETIME":"1960-01-01 00:25:37" ,"SOME_TIME":"00:00:56" ,"SOME_SHORTNUM":79 ,"SOME_BESTNUM":58 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1061 ,"SOME_CHAR":"61 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.372728008 ,"SOME_DATE":"1962-01-04" ,"SOME_DATETIME":"1960-01-01 05:07:43" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":86 ,"SOME_BESTNUM":92 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1062 ,"SOME_CHAR":"62 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9517337316 ,"SOME_DATE":"1961-08-29" ,"SOME_DATETIME":"1960-01-01 02:40:05" ,"SOME_TIME":"00:00:05" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":93 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1063 ,"SOME_CHAR":"63 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0967498683 ,"SOME_DATE":"1962-02-17" ,"SOME_DATETIME":"1960-01-01 07:30:41" ,"SOME_TIME":"00:00:29" ,"SOME_SHORTNUM":90 ,"SOME_BESTNUM":82 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1064 ,"SOME_CHAR":"64 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0540671353 ,"SOME_DATE":"1961-05-26" ,"SOME_DATETIME":"1960-01-01 13:13:43" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":45 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1065 ,"SOME_CHAR":"65 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6461636464 ,"SOME_DATE":"1962-01-27" ,"SOME_DATETIME":"1960-01-01 02:56:41" ,"SOME_TIME":"00:00:19" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":38 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1066 ,"SOME_CHAR":"66 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9053011983 ,"SOME_DATE":"1960-10-02" ,"SOME_DATETIME":"1960-01-01 03:35:49" ,"SOME_TIME":"00:01:04" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":39 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1067 ,"SOME_CHAR":"67 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.977525881 ,"SOME_DATE":"1962-07-19" ,"SOME_DATETIME":"1960-01-01 05:53:20" ,"SOME_TIME":"00:00:28" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":34 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1068 ,"SOME_CHAR":"68 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2165553161 ,"SOME_DATE":"1960-05-13" ,"SOME_DATETIME":"1960-01-01 01:44:02" ,"SOME_TIME":"00:01:12" ,"SOME_SHORTNUM":63 ,"SOME_BESTNUM":23 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1069 ,"SOME_CHAR":"69 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2248352795 ,"SOME_DATE":"1961-05-09" ,"SOME_DATETIME":"1960-01-01 00:04:33" ,"SOME_TIME":"00:00:09" ,"SOME_SHORTNUM":26 ,"SOME_BESTNUM":93 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1070 ,"SOME_CHAR":"70 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1386283367 ,"SOME_DATE":"1962-05-18" ,"SOME_DATETIME":"1960-01-01 03:32:00" ,"SOME_TIME":"00:01:36" ,"SOME_SHORTNUM":83 ,"SOME_BESTNUM":89 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1071 ,"SOME_CHAR":"71 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9337331415 ,"SOME_DATE":"1961-05-16" ,"SOME_DATETIME":"1960-01-01 13:46:54" ,"SOME_TIME":"00:00:47" ,"SOME_SHORTNUM":27 ,"SOME_BESTNUM":56 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1072 ,"SOME_CHAR":"72 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0352235506 ,"SOME_DATE":"1961-06-06" ,"SOME_DATETIME":"1960-01-01 09:09:20" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":7 ,"SOME_BESTNUM":27 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1073 ,"SOME_CHAR":"73 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3206662695 ,"SOME_DATE":"1960-03-13" ,"SOME_DATETIME":"1960-01-01 10:38:11" ,"SOME_TIME":"00:01:08" ,"SOME_SHORTNUM":3 ,"SOME_BESTNUM":50 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1074 ,"SOME_CHAR":"74 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4610861705 ,"SOME_DATE":"1961-08-31" ,"SOME_DATETIME":"1960-01-01 09:35:41" ,"SOME_TIME":"00:01:08" ,"SOME_SHORTNUM":54 ,"SOME_BESTNUM":68 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1075 ,"SOME_CHAR":"75 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4527745622 ,"SOME_DATE":"1962-01-16" ,"SOME_DATETIME":"1960-01-01 06:49:27" ,"SOME_TIME":"00:00:45" ,"SOME_SHORTNUM":96 ,"SOME_BESTNUM":63 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1076 ,"SOME_CHAR":"76 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.3581244058 ,"SOME_DATE":"1960-05-16" ,"SOME_DATETIME":"1960-01-01 00:56:40" ,"SOME_TIME":"00:01:13" ,"SOME_SHORTNUM":72 ,"SOME_BESTNUM":24 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1077 ,"SOME_CHAR":"77 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8939921334 ,"SOME_DATE":"1961-01-21" ,"SOME_DATETIME":"1960-01-01 09:16:31" ,"SOME_TIME":"00:01:15" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":69 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1078 ,"SOME_CHAR":"78 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2445727066 ,"SOME_DATE":"1960-12-22" ,"SOME_DATETIME":"1960-01-01 03:11:14" ,"SOME_TIME":"00:01:37" ,"SOME_SHORTNUM":88 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1079 ,"SOME_CHAR":"79 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9683029465 ,"SOME_DATE":"1961-08-14" ,"SOME_DATETIME":"1960-01-01 04:45:43" ,"SOME_TIME":"00:01:09" ,"SOME_SHORTNUM":51 ,"SOME_BESTNUM":60 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1080 ,"SOME_CHAR":"80 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1303541368 ,"SOME_DATE":"1962-02-28" ,"SOME_DATETIME":"1960-01-01 02:14:50" ,"SOME_TIME":"00:00:21" ,"SOME_SHORTNUM":79 ,"SOME_BESTNUM":87 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1081 ,"SOME_CHAR":"81 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7656979653 ,"SOME_DATE":"1961-08-03" ,"SOME_DATETIME":"1960-01-01 06:49:50" ,"SOME_TIME":"00:01:31" ,"SOME_SHORTNUM":58 ,"SOME_BESTNUM":30 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1082 ,"SOME_CHAR":"82 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1855629674 ,"SOME_DATE":"1960-12-16" ,"SOME_DATETIME":"1960-01-01 06:27:21" ,"SOME_TIME":"00:00:33" ,"SOME_SHORTNUM":1 ,"SOME_BESTNUM":72 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1083 ,"SOME_CHAR":"83 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4782178642 ,"SOME_DATE":"1961-04-16" ,"SOME_DATETIME":"1960-01-01 08:05:23" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":0 ,"SOME_BESTNUM":1 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1084 ,"SOME_CHAR":"84 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1670272132 ,"SOME_DATE":"1962-06-21" ,"SOME_DATETIME":"1960-01-01 13:43:20" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":53 ,"SOME_BESTNUM":6 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1085 ,"SOME_CHAR":"85 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6068249189 ,"SOME_DATE":"1960-05-21" ,"SOME_DATETIME":"1960-01-01 11:05:11" ,"SOME_TIME":"00:00:08" ,"SOME_SHORTNUM":17 ,"SOME_BESTNUM":68 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1086 ,"SOME_CHAR":"86 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0936049917 ,"SOME_DATE":"1962-07-20" ,"SOME_DATETIME":"1960-01-01 07:16:09" ,"SOME_TIME":"00:00:46" ,"SOME_SHORTNUM":73 ,"SOME_BESTNUM":37 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1087 ,"SOME_CHAR":"87 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6538249178 ,"SOME_DATE":"1960-04-24" ,"SOME_DATETIME":"1960-01-01 02:06:54" ,"SOME_TIME":"00:00:59" ,"SOME_SHORTNUM":95 ,"SOME_BESTNUM":32 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1088 ,"SOME_CHAR":"88 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8846158562 ,"SOME_DATE":"1961-11-19" ,"SOME_DATETIME":"1960-01-01 05:35:27" ,"SOME_TIME":"00:01:01" ,"SOME_SHORTNUM":87 ,"SOME_BESTNUM":30 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1089 ,"SOME_CHAR":"89 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.1578208316 ,"SOME_DATE":"1961-03-03" ,"SOME_DATETIME":"1960-01-01 09:02:02" ,"SOME_TIME":"00:00:23" ,"SOME_SHORTNUM":60 ,"SOME_BESTNUM":53 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1090 ,"SOME_CHAR":"90 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4225753753 ,"SOME_DATE":"1960-03-19" ,"SOME_DATETIME":"1960-01-01 12:14:04" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":57 ,"SOME_BESTNUM":64 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1091 ,"SOME_CHAR":"91 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6598943354 ,"SOME_DATE":"1961-09-17" ,"SOME_DATETIME":"1960-01-01 03:03:13" ,"SOME_TIME":"00:01:00" ,"SOME_SHORTNUM":41 ,"SOME_BESTNUM":28 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1092 ,"SOME_CHAR":"92 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.6293501689 ,"SOME_DATE":"1961-10-18" ,"SOME_DATETIME":"1960-01-01 00:21:13" ,"SOME_TIME":"00:01:11" ,"SOME_SHORTNUM":64 ,"SOME_BESTNUM":7 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1093 ,"SOME_CHAR":"93 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4378844986 ,"SOME_DATE":"1961-06-24" ,"SOME_DATETIME":"1960-01-01 10:20:39" ,"SOME_TIME":"00:00:27" ,"SOME_SHORTNUM":30 ,"SOME_BESTNUM":78 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1094 ,"SOME_CHAR":"94 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9838584969 ,"SOME_DATE":"1962-05-25" ,"SOME_DATETIME":"1960-01-01 02:59:06" ,"SOME_TIME":"00:00:59" ,"SOME_SHORTNUM":48 ,"SOME_BESTNUM":98 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1095 ,"SOME_CHAR":"95 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.089252377 ,"SOME_DATE":"1961-06-16" ,"SOME_DATETIME":"1960-01-01 04:54:20" ,"SOME_TIME":"00:00:10" ,"SOME_SHORTNUM":75 ,"SOME_BESTNUM":33 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1096 ,"SOME_CHAR":"96 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4578205154 ,"SOME_DATE":"1960-01-20" ,"SOME_DATETIME":"1960-01-01 10:36:00" ,"SOME_TIME":"00:00:41" ,"SOME_SHORTNUM":14 ,"SOME_BESTNUM":17 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1097 ,"SOME_CHAR":"97 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5863271587 ,"SOME_DATE":"1962-04-20" ,"SOME_DATETIME":"1960-01-01 11:14:11" ,"SOME_TIME":"00:01:28" ,"SOME_SHORTNUM":66 ,"SOME_BESTNUM":84 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1098 ,"SOME_CHAR":"98 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.2994232058 ,"SOME_DATE":"1960-07-04" ,"SOME_DATETIME":"1960-01-01 08:15:41" ,"SOME_TIME":"00:01:28" ,"SOME_SHORTNUM":99 ,"SOME_BESTNUM":85 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":1099 ,"SOME_CHAR":"99 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.0981378053 ,"SOME_DATE":"1960-02-05" ,"SOME_DATETIME":"1960-01-01 11:10:11" ,"SOME_TIME":"00:00:43" ,"SOME_SHORTNUM":23 ,"SOME_BESTNUM":65 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10100 ,"SOME_CHAR":"100 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.9829722652 ,"SOME_DATE":"1960-02-01" ,"SOME_DATETIME":"1960-01-01 05:45:06" ,"SOME_TIME":"00:01:16" ,"SOME_SHORTNUM":28 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10101 ,"SOME_CHAR":"101 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.4540794913 ,"SOME_DATE":"1962-08-03" ,"SOME_DATETIME":"1960-01-01 09:27:03" ,"SOME_TIME":"00:01:10" ,"SOME_SHORTNUM":42 ,"SOME_BESTNUM":44 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10102 ,"SOME_CHAR":"102 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.8452174369 ,"SOME_DATE":"1960-10-02" ,"SOME_DATETIME":"1960-01-01 03:08:47" ,"SOME_TIME":"00:00:23" ,"SOME_SHORTNUM":10 ,"SOME_BESTNUM":14 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10103 ,"SOME_CHAR":"103 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.5904919606 ,"SOME_DATE":"1960-07-30" ,"SOME_DATETIME":"1960-01-01 13:09:58" ,"SOME_TIME":"00:00:10" ,"SOME_SHORTNUM":68 ,"SOME_BESTNUM":53 } +,{"_____DELETE__THIS__RECORD_____":"No" ,"PRIMARY_KEY_FIELD":10104 ,"SOME_CHAR":"104 bottles of beer on the wall" ,"SOME_DROPDOWN":"Option 1" ,"SOME_NUM":0.7083388677 ,"SOME_DATE":"1960-07-24" ,"SOME_DATETIME":"1960-01-01 05:49:50" ,"SOME_TIME":"00:01:29" ,"SOME_SHORTNUM":84 ,"SOME_BESTNUM":33 } +] +, "$sasdata":{"vars":{ +"_____DELETE__THIS__RECORD_____" :{"format":"$3." ,"label":"_____DELETE__THIS__RECORD_____" ,"length":"3" ,"type":"char" } +,"PRIMARY_KEY_FIELD" :{"format":"best." ,"label":"PRIMARY_KEY_FIELD" ,"length":"8" ,"type":"num" } +,"SOME_CHAR" :{"format":"$32767." ,"label":"SOME_CHAR" ,"length":"32767" ,"type":"char" } +,"SOME_DROPDOWN" :{"format":"$128." ,"label":"SOME_DROPDOWN" ,"length":"128" ,"type":"char" } +,"SOME_NUM" :{"format":"best." ,"label":"SOME_NUM" ,"length":"8" ,"type":"num" } +,"SOME_DATE" :{"format":"$200." ,"label":"SOME_DATE" ,"length":"200" ,"type":"char" } +,"SOME_DATETIME" :{"format":"$200." ,"label":"SOME_DATETIME" ,"length":"200" ,"type":"char" } +,"SOME_TIME" :{"format":"$200." ,"label":"SOME_TIME" ,"length":"200" ,"type":"char" } +,"SOME_SHORTNUM" :{"format":"best." ,"label":"SOME_SHORTNUM" ,"length":"4" ,"type":"num" } +,"SOME_BESTNUM" :{"format":"BEST." ,"label":"SOME_BESTNUM" ,"length":"8" ,"type":"num" } +}} +, "sasparams": +[ +{ +"COLHEADERS": "_____DELETE__THIS__RECORD_____,PRIMARY_KEY_FIELD,SOME_CHAR,SOME_DROPDOWN,SOME_NUM,SOME_DATE,SOME_DATETIME,SOME_TIME,SOME_SHORTNUM,SOME_BESTNUM", +"FILTER_TEXT": "${FILTER_TEXT}", +"PKCNT": 1, +"PK": "PRIMARY_KEY_FIELD", +"DTVARS": " SOME_DATE", +"DTTMVARS": " SOME_DATETIME", +"TMVARS": " SOME_TIME", +"COLTYPE": "{\\\"data\\\":\\\"_____DELETE__THIS__RECORD_____\\\",\\\"type\\\":\\\"dropdown\\\",\\\"source\\\":[\\\"No\\\",\\\"Yes\\\"]},{\\\"data\\\":\\\"PRIMARY_KEY_FIELD\\\",\\\"type\\\":\\\"numeric\\\",\\\"format\\\":\\\"0\\\"},{\\\"data\\\":\\\"SOME_CHAR\\\"},{\\\"data\\\":\\\"SOME_DROPDOWN\\\"},{\\\"data\\\":\\\"SOME_NUM\\\",\\\"type\\\":\\\"numeric\\\",\\\"format\\\":\\\"0\\\"},{\\\"data\\\":\\\"SOME_DATE\\\",\\\"type\\\":\\\"date\\\",\\\"dateFormat\\\":\\\"YYYY-MM-DD\\\",\\\"correctFormat\\\":\\\"true\\\"},{\\\"data\\\":\\\"SOME_DATETIME\\\",\\\"type\\\":\\\"date\\\",\\\"dateFormat\\\":\\\"YYYY-MM-DD HH:mm:ss\\\",\\\"correctFormat\\\":\\\"true\\\"},{\\\"data\\\":\\\"SOME_TIME\\\",\\\"type\\\":\\\"time\\\",\\\"timeFormat\\\":\\\"HH:mm:ss\\\",\\\"correctFormat\\\":\\\"true\\\"},{\\\"data\\\":\\\"SOME_SHORTNUM\\\",\\\"type\\\":\\\"numeric\\\",\\\"format\\\":\\\"0\\\"},{\\\"data\\\":\\\"SOME_BESTNUM\\\",\\\"type\\\":\\\"numeric\\\",\\\"format\\\":\\\"0\\\"}", +"LOADTYPE": "UPDATE", +"RK_FLAG": 0, +"CLS_FLAG": 0 +} +] +, "xl_rules": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/getdata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8056A491DB23409E940000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:30:13.853000" +,"MEMSIZE" : "46GB" +}`, + MPE_DATADICTIONARY: `{"SYSDATE" : "25NOV22" +,"SYSTIME" : "12:48" +, "approvers": +[ +] +, "cols": +[ +{"NAME":"DD_LONGDESC" ,"VARNUM":6 ,"LABEL":"DD_LONGDESC" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_OWNER" ,"VARNUM":7 ,"LABEL":"DD_OWNER" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_RESPONSIBLE" ,"VARNUM":8 ,"LABEL":"DD_RESPONSIBLE" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_SENSITIVITY" ,"VARNUM":9 ,"LABEL":"DD_SENSITIVITY" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_SHORTDESC" ,"VARNUM":5 ,"LABEL":"DD_SHORTDESC" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_SOURCE" ,"VARNUM":4 ,"LABEL":"DD_SOURCE" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DD_TYPE" ,"VARNUM":3 ,"LABEL":"DD_TYPE" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"TX_FROM" ,"VARNUM":1 ,"LABEL":"TX_FROM" ,"FMTNAME":"datetime" ,"DDTYPE":"NUMERIC" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"TX_TO" ,"VARNUM":2 ,"LABEL":"TX_TO" ,"FMTNAME":"datetime" ,"DDTYPE":"NUMERIC" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +] +, "dqdata": +[ +{"BASE_COL":"DD_TYPE" ,"RULE_VALUE":"DD_TYPE" ,"RULE_DATA":"COLUMN" ,"SELECTBOX_ORDER":1 } +,{"BASE_COL":"DD_TYPE" ,"RULE_VALUE":"DD_TYPE" ,"RULE_DATA":"TABLE" ,"SELECTBOX_ORDER":2 } +,{"BASE_COL":"DD_TYPE" ,"RULE_VALUE":"DD_TYPE" ,"RULE_DATA":"CATALOG" ,"SELECTBOX_ORDER":3 } +,{"BASE_COL":"DD_TYPE" ,"RULE_VALUE":"DD_TYPE" ,"RULE_DATA":"FORMAT" ,"SELECTBOX_ORDER":3 } +,{"BASE_COL":"DD_TYPE" ,"RULE_VALUE":"DD_TYPE" ,"RULE_DATA":"LIBRARY" ,"SELECTBOX_ORDER":3 } +] +, "dqrules": +[ +] +, "dsmeta": +[ +{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Name" ,"VALUE":"MPE_DATADICTIONARY" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Member Type" ,"VALUE":"DATA" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Engine" ,"VALUE":"WPD" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Created" ,"VALUE":"25NOV2022:12:48:00" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Last Modified" ,"VALUE":"25NOV2022:12:48:01" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observations" ,"VALUE":"6" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Variables" ,"VALUE":"9" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Indexes" ,"VALUE":"1" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observation Length" ,"VALUE":"34399" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Deleted Observations" ,"VALUE":"0" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Type" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Label" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Compressed" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Sorted" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Representation" ,"VALUE":"Little endian, IEEE Unix" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Encoding" ,"VALUE":"utf-8 UTF-8 Unicode" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Data Set Page Size" ,"VALUE":"36864" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Data Set Pages" ,"VALUE":"7" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"First Data Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Max Obs Per Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Obs In First Data Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Data Set Diagnostic Code" ,"VALUE":"0009" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Index File Page Size" ,"VALUE":"4096" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Index File Pages" ,"VALUE":"11" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Index Diagnostic Code" ,"VALUE":"0003" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Name" ,"VALUE":"/tmp/mihajlo/DC083327/MPE_DATADICTIONARY.wpd" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"WPD Engine Version" ,"VALUE":"3" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Large Data Set Support" ,"VALUE":"no" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Inode Number" ,"VALUE":"1040506" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Access Permission" ,"VALUE":"rw-rw-r--" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Owner Name" ,"VALUE":"mihajlo" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Size (bytes)" ,"VALUE":"225280" } +] +, "maxvarlengths": +[ +{"NAME":"_____DELETE__THIS__RECORD_____" ,"MAXLEN":3 } +,{"NAME":"DD_TYPE" ,"MAXLEN":9 } +,{"NAME":"DD_SOURCE" ,"MAXLEN":30 } +,{"NAME":"DD_SHORTDESC" ,"MAXLEN":53 } +,{"NAME":"DD_LONGDESC" ,"MAXLEN":90 } +,{"NAME":"DD_OWNER" ,"MAXLEN":7 } +,{"NAME":"DD_RESPONSIBLE" ,"MAXLEN":7 } +,{"NAME":"DD_SENSITIVITY" ,"MAXLEN":3 } +] +, "query": +[ +] +, "sasdata": +[ +{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"COLUMN" ,"DD_SOURCE":"DC083327.MPE_CONFIG.VAR_ACTIVE" ,"DD_SHORTDESC":"Set to 1 to make an option active" ,"DD_LONGDESC":"This value is used as a filter by data controller whenever querying for option settings." ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"COLUMN" ,"DD_SOURCE":"DC083327.MPE_TABLES.DSN" ,"DD_SHORTDESC":"Dataset Name to be edited" ,"DD_LONGDESC":"_DSN_ - must be UPCASE" ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"DIRECTORY" ,"DD_SOURCE":"/some/directory" ,"DD_SHORTDESC":"Directory for some purpose" ,"DD_LONGDESC":"This directory is great. It's great directory. It trumps all other directories." ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"LIBRARY" ,"DD_SOURCE":"DC083327" ,"DD_SHORTDESC":"Data Controller Control Tables" ,"DD_LONGDESC":"# The Data Controller Library" ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"TABLE" ,"DD_SOURCE":"DC083327" ,"DD_SHORTDESC":"Transaction table for capturing Data Controller users" ,"DD_LONGDESC":"After a user accepts the Data Controller EULA they are registered as a user in this table." ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"DD_TYPE":"TABLE" ,"DD_SOURCE":"DC083327.MPE_TABLES" ,"DD_SHORTDESC":"Configuration of new tables for Data Controller" ,"DD_LONGDESC":"# MPE_TABLES - adding new tabels to Data Controller" ,"DD_OWNER":"mihajlo" ,"DD_RESPONSIBLE":"mihajlo" ,"DD_SENSITIVITY":"Low" } +] +, "$sasdata":{"vars":{ +"_____DELETE__THIS__RECORD_____" :{"format":"$3." ,"label":"_____DELETE__THIS__RECORD_____" ,"length":"3" ,"type":"char" } +,"DD_TYPE" :{"format":"$16." ,"label":"DD_TYPE" ,"length":"16" ,"type":"char" } +,"DD_SOURCE" :{"format":"$1024." ,"label":"DD_SOURCE" ,"length":"1024" ,"type":"char" } +,"DD_SHORTDESC" :{"format":"$256." ,"label":"DD_SHORTDESC" ,"length":"256" ,"type":"char" } +,"DD_LONGDESC" :{"format":"$32767." ,"label":"DD_LONGDESC" ,"length":"32767" ,"type":"char" } +,"DD_OWNER" :{"format":"$128." ,"label":"DD_OWNER" ,"length":"128" ,"type":"char" } +,"DD_RESPONSIBLE" :{"format":"$128." ,"label":"DD_RESPONSIBLE" ,"length":"128" ,"type":"char" } +,"DD_SENSITIVITY" :{"format":"$64." ,"label":"DD_SENSITIVITY" ,"length":"64" ,"type":"char" } +}} +, "sasparams": +[ +{"COLHEADERS":"_____DELETE__THIS__RECORD_____,DD_TYPE,DD_SOURCE,DD_SHORTDESC,DD_LONGDESC,DD_OWNER,DD_RESPONSIBLE,DD_SENSITIVITY" ,"FILTER_TEXT":"(\\\"%sysfunc(datetime(), DATETIME19.3 )\\\"dt < TX_TO )" ,"PKCNT":2 ,"PK":"DD_TYPE DD_SOURCE" ,"DTVARS":"" ,"DTTMVARS":"" ,"TMVARS":"" ,"COLTYPE":"{\\\"data\\\":\\\"_____DELETE__THIS__RECORD_____\\\",\\\"type\\\":\\\"dropdown\\\",\\\"source\\\":[\\\"No\\\",\\\"Yes\\\"]},{\\\"data\\\":\\\"DD_TYPE\\\"},{\\\"data\\\":\\\"DD_SOURCE\\\"},{\\\"data\\\":\\\"DD_SHORTDESC\\\"},{\\\"data\\\":\\\"DD_LONGDESC\\\"},{\\\"data\\\":\\\"DD_OWNER\\\"},{\\\"data\\\":\\\"DD_RESPONSIBLE\\\"},{\\\"data\\\":\\\"DD_SENSITIVITY\\\"}" ,"LOADTYPE":"TXTEMPORAL" ,"RK_FLAG":0 ,"CLS_FLAG":0 } +] +, "xl_rules": +[ +{"XL_COLUMN":"DD_LONGDESC" ,"XL_RULE":"FORMULA" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/dc/services/editors/getdata" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221125124822-23413-1669380502499%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "" +,"SYSPROCESSID" : "1" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "1084774" +,"SYSSCPL" : "LINUX" +,"SYSSITE" : "123" +,"SYSTCPIPHOSTNAME" : "" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.03.002208" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-11-25T12:49:06.877398" +,"MEMSIZE" : "0KB" +} +`, +MPE_USERS: `{"SYSDATE" : "01DEC22" +,"SYSTIME" : "12:40" +, "approvers": +[ +] +, "cols": +[ +{"NAME":"LAST_SEEN_DT" ,"VARNUM":2 ,"LABEL":"LAST_SEEN_DT" ,"FMTNAME":"date" ,"DDTYPE":"NUMERIC" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"REGISTERED_DT" ,"VARNUM":3 ,"LABEL":"REGISTERED_DT" ,"FMTNAME":"date" ,"DDTYPE":"NUMERIC" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"USER_ID" ,"VARNUM":1 ,"LABEL":"USER_ID" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +] +, "dqdata": +[ +] +, "dqrules": +[ +] +, "dsmeta": +[ +{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Name" ,"VALUE":"MPE_USERS" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Member Type" ,"VALUE":"DATA" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Engine" ,"VALUE":"WPD" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Created" ,"VALUE":"25NOV2022:12:48:00" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Last Modified" ,"VALUE":"01DEC2022:12:41:16" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observations" ,"VALUE":"1" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Variables" ,"VALUE":"3" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Indexes" ,"VALUE":"1" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observation Length" ,"VALUE":"66" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Deleted Observations" ,"VALUE":"0" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Type" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Label" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Compressed" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Sorted" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Representation" ,"VALUE":"Little endian, IEEE Unix" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Encoding" ,"VALUE":"utf-8 UTF-8 Unicode" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Data Set Page Size" ,"VALUE":"4096" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Data Set Pages" ,"VALUE":"2" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"First Data Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Max Obs Per Page" ,"VALUE":"61" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Obs In First Data Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Data Set Diagnostic Code" ,"VALUE":"0009" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Index File Page Size" ,"VALUE":"4096" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Index File Pages" ,"VALUE":"3" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Index Diagnostic Code" ,"VALUE":"0003" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Name" ,"VALUE":"/tmp/mihajlo/DC083327/MPE_USERS.wpd" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"WPD Engine Version" ,"VALUE":"3" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Large Data Set Support" ,"VALUE":"no" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Inode Number" ,"VALUE":"1040545" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Access Permission" ,"VALUE":"rw-rw-r--" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Owner Name" ,"VALUE":"mihajlo" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Size (bytes)" ,"VALUE":"8192" } +] +, "maxvarlengths": +[ +{"NAME":"_____DELETE__THIS__RECORD_____" ,"MAXLEN":3 } +,{"NAME":"USER_ID" ,"MAXLEN":0 } +] +, "query": +[ +] +, "sasdata": +[ +{"_____DELETE__THIS__RECORD_____":"No" ,"USER_ID":"" } +] +, "$sasdata":{"vars":{ +"_____DELETE__THIS__RECORD_____" :{"format":"$3." ,"label":"_____DELETE__THIS__RECORD_____" ,"length":"3" ,"type":"char" } +,"USER_ID" :{"format":"$50." ,"label":"USER_ID" ,"length":"50" ,"type":"char" } +}} +, "sasparams": +[ +{"COLHEADERS":"_____DELETE__THIS__RECORD_____,USER_ID" ,"FILTER_TEXT":"(\\"%sysfunc(datetime(), DATETIME19.3 )\\"dt < REGISTERED_DT )" ,"PKCNT":1 ,"PK":"USER_ID" ,"DTVARS":"" ,"DTTMVARS":"" ,"TMVARS":"" ,"COLTYPE":"{\\"data\\":\\"_____DELETE__THIS__RECORD_____\\",\\"type\\":\\"dropdown\\",\\"source\\":[\\"No\\",\\"Yes\\"]},{\\"data\\":\\"USER_ID\\"}" ,"LOADTYPE":"UPDATE" ,"RK_FLAG":0 ,"CLS_FLAG":0 } +] +, "xl_rules": +[ +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/dc/services/editors/getdata" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221201124053-21286-1669898453493%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD9626156A45BB0000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "1146134" +,"SYSSCPL" : "LINUX" +,"SYSSITE" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.03.002208" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-12-01T12:41:23.940217" +,"MEMSIZE" : "0KB" +} +`, +MPE_TABLES: `{"SYSDATE" : "10MAR23" +,"SYSTIME" : "12:38" +, "approvers": +[ +] +, "cols": +[ +{"NAME":"AUDIT_LIBDS" ,"VARNUM":22 ,"LABEL":"AUDIT_LIBDS" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"BUSKEY" ,"VARNUM":7 ,"LABEL":"BUSKEY" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"CLOSE_VARS" ,"VARNUM":13 ,"LABEL":"CLOSE_VARS" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"DSN" ,"VARNUM":4 ,"LABEL":"DSN" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"LIBREF" ,"VARNUM":3 ,"LABEL":"LIBREF" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"LOADTYPE" ,"VARNUM":6 ,"LABEL":"LOADTYPE" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"NOTES" ,"VARNUM":20 ,"LABEL":"NOTES" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"NUM_OF_APPROVALS_REQUIRED" ,"VARNUM":5 ,"LABEL":"NUM_OF_APPROVALS_REQUIRED" ,"FMTNAME":"" ,"DDTYPE":"NUMERIC" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"POST_APPROVE_HOOK" ,"VARNUM":17 ,"LABEL":"POST_APPROVE_HOOK" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"POST_EDIT_HOOK" ,"VARNUM":15 ,"LABEL":"POST_EDIT_HOOK" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"PRE_APPROVE_HOOK" ,"VARNUM":16 ,"LABEL":"PRE_APPROVE_HOOK" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"PRE_EDIT_HOOK" ,"VARNUM":14 ,"LABEL":"PRE_EDIT_HOOK" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"RK_UNDERLYING" ,"VARNUM":21 ,"LABEL":"RK_UNDERLYING" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"SIGNOFF_COLS" ,"VARNUM":18 ,"LABEL":"SIGNOFF_COLS" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"SIGNOFF_HOOK" ,"VARNUM":19 ,"LABEL":"SIGNOFF_HOOK" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"TX_FROM" ,"VARNUM":1 ,"LABEL":"TX_FROM" ,"FMTNAME":"DATETIME" ,"DDTYPE":"DATETIME" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"TX_TO" ,"VARNUM":2 ,"LABEL":"TX_TO" ,"FMTNAME":"DATETIME" ,"DDTYPE":"DATETIME" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"VAR_BUSFROM" ,"VARNUM":10 ,"LABEL":"VAR_BUSFROM" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"VAR_BUSTO" ,"VARNUM":11 ,"LABEL":"VAR_BUSTO" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"VAR_PROCESSED" ,"VARNUM":12 ,"LABEL":"VAR_PROCESSED" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"VAR_TXFROM" ,"VARNUM":8 ,"LABEL":"VAR_TXFROM" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +,{"NAME":"VAR_TXTO" ,"VARNUM":9 ,"LABEL":"VAR_TXTO" ,"FMTNAME":"" ,"DDTYPE":"CHARACTER" ,"CLS_RULE":"READ" ,"MEMLABEL":"" ,"DESC":"" ,"LONGDESC":"" } +] +, "dqdata": +[ +{"BASE_COL":"LOADTYPE" ,"RULE_VALUE":"LOADTYPE" ,"RULE_DATA":"UPDATE" ,"SELECTBOX_ORDER":1 } +,{"BASE_COL":"LOADTYPE" ,"RULE_VALUE":"LOADTYPE" ,"RULE_DATA":"REPLACE" ,"SELECTBOX_ORDER":2 } +,{"BASE_COL":"LOADTYPE" ,"RULE_VALUE":"LOADTYPE" ,"RULE_DATA":"TXTEMPORAL" ,"SELECTBOX_ORDER":3 } +,{"BASE_COL":"LOADTYPE" ,"RULE_VALUE":"LOADTYPE" ,"RULE_DATA":"BITEMPORAL" ,"SELECTBOX_ORDER":4 } +,{"BASE_COL":"LOADTYPE" ,"RULE_VALUE":"LOADTYPE" ,"RULE_DATA":"FORMAT_CAT" ,"SELECTBOX_ORDER":5 } +] +, "dqrules": +[ +{"BASE_COL":"BUSKEY" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"BUSKEY" ,"RULE_TYPE":"NOTNULL" ,"RULE_VALUE":"" ,"X":0 } +,{"BASE_COL":"DSN" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"DSN" ,"RULE_TYPE":"NOTNULL" ,"RULE_VALUE":"" ,"X":0 } +,{"BASE_COL":"DSN" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/mpe_tables.dsn" ,"X":0 } +,{"BASE_COL":"LIBREF" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"LIBREF" ,"RULE_TYPE":"NOTNULL" ,"RULE_VALUE":"" ,"X":0 } +,{"BASE_COL":"LIBREF" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/libraries_all" ,"X":0 } +,{"BASE_COL":"NUM_OF_APPROVALS_REQUIRED" ,"RULE_TYPE":"MINVAL" ,"RULE_VALUE":"1" ,"X":0 } +,{"BASE_COL":"VAR_BUSFROM" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"VAR_BUSFROM" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/columns_in_libds" ,"X":0 } +,{"BASE_COL":"VAR_BUSTO" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"VAR_BUSTO" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/columns_in_libds" ,"X":0 } +,{"BASE_COL":"VAR_PROCESSED" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"VAR_PROCESSED" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/columns_in_libds" ,"X":0 } +,{"BASE_COL":"VAR_TXFROM" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"VAR_TXFROM" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/columns_in_libds" ,"X":0 } +,{"BASE_COL":"VAR_TXTO" ,"RULE_TYPE":"CASE" ,"RULE_VALUE":"UPCASE" ,"X":0 } +,{"BASE_COL":"VAR_TXTO" ,"RULE_TYPE":"SOFTSELECT_HOOK" ,"RULE_VALUE":"services/validations/columns_in_libds" ,"X":0 } +] +, "dsmeta": +[ +{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Name" ,"VALUE":"DC200241.MPE_TABLES" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observations" ,"VALUE":"14" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Member Type" ,"VALUE":"DATA" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Variables" ,"VALUE":"22" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Engine" ,"VALUE":"V9" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Indexes" ,"VALUE":"1" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Created" ,"VALUE":"14/02/2023 17:21:19" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Integrity Constraints" ,"VALUE":"4" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Last Modified" ,"VALUE":"14/02/2023 17:21:19" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Observation Length" ,"VALUE":"5280" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Protection" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Deleted Observations" ,"VALUE":"0" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Set Type" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Compressed" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Label" ,"VALUE":"." } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Sorted" ,"VALUE":"NO" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Data Representation" ,"VALUE":"SOLARIS_X86_64, LINUX_X86_64, ALPHA_TRU64, LINUX_IA64" } +,{"ODS_TABLE":"ATTRIBUTES" ,"NAME":"Encoding" ,"VALUE":"utf-8 Unicode (UTF-8)" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Data Set Page Size" ,"VALUE":"131072" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Data Set Pages" ,"VALUE":"2" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"First Data Page" ,"VALUE":"1" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Max Obs per Page" ,"VALUE":"24" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Obs in First Data Page" ,"VALUE":"14" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Index File Page Size" ,"VALUE":"8192" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Index File Pages" ,"VALUE":"2" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Number of Data Set Repairs" ,"VALUE":"0" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Filename" ,"VALUE":"/tmp/DataController/DC200241/mpe_tables.sas7bdat" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Release Created" ,"VALUE":"9.0401M7" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Host Created" ,"VALUE":"Linux" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Inode Number" ,"VALUE":"20976367" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Access Permission" ,"VALUE":"rw-rw-r--" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"Owner Name" ,"VALUE":"sasjssrv" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Size" ,"VALUE":"384KB" } +,{"ODS_TABLE":"ENGINEHOST" ,"NAME":"File Size (bytes)" ,"VALUE":"393216" } +] +, "maxvarlengths": +[ +{"NAME":"_____DELETE__THIS__RECORD_____" ,"MAXLEN":3 } +,{"NAME":"LIBREF" ,"MAXLEN":8 } +,{"NAME":"DSN" ,"MAXLEN":25 } +,{"NAME":"num_of_approvals_required" ,"MAXLEN":3 } +,{"NAME":"loadtype" ,"MAXLEN":10 } +,{"NAME":"buskey" ,"MAXLEN":56 } +,{"NAME":"var_txfrom" ,"MAXLEN":13 } +,{"NAME":"var_txto" ,"MAXLEN":11 } +,{"NAME":"var_busfrom" ,"MAXLEN":0 } +,{"NAME":"var_busto" ,"MAXLEN":0 } +,{"NAME":"var_processed" ,"MAXLEN":0 } +,{"NAME":"close_vars" ,"MAXLEN":0 } +,{"NAME":"pre_edit_hook" ,"MAXLEN":0 } +,{"NAME":"post_edit_hook" ,"MAXLEN":49 } +,{"NAME":"pre_approve_hook" ,"MAXLEN":0 } +,{"NAME":"post_approve_hook" ,"MAXLEN":0 } +,{"NAME":"signoff_cols" ,"MAXLEN":0 } +,{"NAME":"signoff_hook" ,"MAXLEN":0 } +,{"NAME":"notes" ,"MAXLEN":62 } +,{"NAME":"rk_underlying" ,"MAXLEN":137 } +,{"NAME":"audit_libds" ,"MAXLEN":0 } +] +, "query": +[ +] +, "sasdata": +[ +{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_ALERTS" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"ALERT_EVENT ALERT_LIB ALERT_DS ALERT_USER" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration for alert email events" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_COLUMN_LEVEL_SECURITY" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"CLS_SCOPE CLS_GROUP CLS_LIBREF CLS_TABLE CLS_VARIABLE_NM" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"services/hooks/mpe_column_level_security_postedit" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Docs: https://docs.datacontroller.io/column-level-security" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_CONFIG" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"VAR_SCOPE VAR_NAME" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration variables for Data Controller" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_DATADICTIONARY" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"DD_TYPE DD_SOURCE" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration of data dictionary" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_EMAILS" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"USER_NAME" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Primary Emails Table (backup is metadata)" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_EXCEL_CONFIG" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"XL_LIBREF XL_TABLE XL_COLUMN" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration of the excel import rules" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_GROUPS" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"GROUP_NAME USER_NAME" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration for additional groups within Data Controller" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_LOCKANYTABLE" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"UPDATE" ,"BUSKEY":"LOCK_LIB LOCK_DS" ,"VAR_TXFROM":"" ,"VAR_TXTO":"" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"This table may be edited when a process failed and left a lock" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_ROW_LEVEL_SECURITY" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"RLS_RK" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"services/hooks/mpe_row_level_security_postedit" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration of Row Level Security" ,"RK_UNDERLYING":"RLS_SCOPE RLS_GROUP RLS_LIBREF RLS_TABLE RLS_GROUP_LOGIC RLS_SUBGROUP_LOGIC RLS_SUBGROUP_ID RLS_VARIABLE_NM RLS_OPERATOR_NM RLS_RAW_VALUE" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_SECURITY" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"LIBREF DSN ACCESS_LEVEL SAS_GROUP" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Shows which metadata groups can edit which tables" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_SELECTBOX" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"SELECTBOX_RK" ,"VAR_TXFROM":"VER_FROM_DTTM" ,"VAR_TXTO":"VER_TO_DTTM" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Can configure dropdowns for the front end" ,"RK_UNDERLYING":"SELECT_LIB SELECT_DS BASE_COLUMN SELECTBOX_VALUE" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_TABLES" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"LIBREF DSN" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"services/hooks/mpe_tables_postedit" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"This entry allows the MP Editor to edit itself!" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_VALIDATIONS" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"TXTEMPORAL" ,"BUSKEY":"BASE_LIB BASE_DS BASE_COL RULE_TYPE" ,"VAR_TXFROM":"TX_FROM" ,"VAR_TXTO":"TX_TO" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"services/hooks/mpe_validations_postedit" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Configuration of data quality rules in Editor component" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +,{"_____DELETE__THIS__RECORD_____":"No" ,"LIBREF":"DC200241" ,"DSN":"MPE_X_TEST" ,"NUM_OF_APPROVALS_REQUIRED":1 ,"LOADTYPE":"UPDATE" ,"BUSKEY":"PRIMARY_KEY_FIELD" ,"VAR_TXFROM":"" ,"VAR_TXTO":"" ,"VAR_BUSFROM":"" ,"VAR_BUSTO":"" ,"VAR_PROCESSED":"" ,"CLOSE_VARS":"" ,"PRE_EDIT_HOOK":"" ,"POST_EDIT_HOOK":"" ,"PRE_APPROVE_HOOK":"" ,"POST_APPROVE_HOOK":"" ,"SIGNOFF_COLS":"" ,"SIGNOFF_HOOK":"" ,"NOTES":"Test table for controller" ,"RK_UNDERLYING":"" ,"AUDIT_LIBDS":"" } +] +, "$sasdata":{"vars":{ +"_____DELETE__THIS__RECORD_____" :{"format":"$3." ,"label":"_____DELETE__THIS__RECORD_____" ,"length":"3" ,"type":"char" } +,"LIBREF" :{"format":"$8." ,"label":"LIBREF" ,"length":"8" ,"type":"char" } +,"DSN" :{"format":"$32." ,"label":"DSN" ,"length":"32" ,"type":"char" } +,"NUM_OF_APPROVALS_REQUIRED" :{"format":"best." ,"label":"NUM_OF_APPROVALS_REQUIRED" ,"length":"8" ,"type":"num" } +,"LOADTYPE" :{"format":"$12." ,"label":"LOADTYPE" ,"length":"12" ,"type":"char" } +,"BUSKEY" :{"format":"$1000." ,"label":"BUSKEY" ,"length":"1000" ,"type":"char" } +,"VAR_TXFROM" :{"format":"$32." ,"label":"VAR_TXFROM" ,"length":"32" ,"type":"char" } +,"VAR_TXTO" :{"format":"$32." ,"label":"VAR_TXTO" ,"length":"32" ,"type":"char" } +,"VAR_BUSFROM" :{"format":"$32." ,"label":"VAR_BUSFROM" ,"length":"32" ,"type":"char" } +,"VAR_BUSTO" :{"format":"$32." ,"label":"VAR_BUSTO" ,"length":"32" ,"type":"char" } +,"VAR_PROCESSED" :{"format":"$32." ,"label":"VAR_PROCESSED" ,"length":"32" ,"type":"char" } +,"CLOSE_VARS" :{"format":"$500." ,"label":"CLOSE_VARS" ,"length":"500" ,"type":"char" } +,"PRE_EDIT_HOOK" :{"format":"$200." ,"label":"PRE_EDIT_HOOK" ,"length":"200" ,"type":"char" } +,"POST_EDIT_HOOK" :{"format":"$200." ,"label":"POST_EDIT_HOOK" ,"length":"200" ,"type":"char" } +,"PRE_APPROVE_HOOK" :{"format":"$200." ,"label":"PRE_APPROVE_HOOK" ,"length":"200" ,"type":"char" } +,"POST_APPROVE_HOOK" :{"format":"$200." ,"label":"POST_APPROVE_HOOK" ,"length":"200" ,"type":"char" } +,"SIGNOFF_COLS" :{"format":"$500." ,"label":"SIGNOFF_COLS" ,"length":"500" ,"type":"char" } +,"SIGNOFF_HOOK" :{"format":"$200." ,"label":"SIGNOFF_HOOK" ,"length":"200" ,"type":"char" } +,"NOTES" :{"format":"$1000." ,"label":"NOTES" ,"length":"1000" ,"type":"char" } +,"RK_UNDERLYING" :{"format":"$1000." ,"label":"RK_UNDERLYING" ,"length":"1000" ,"type":"char" } +,"AUDIT_LIBDS" :{"format":"$41." ,"label":"AUDIT_LIBDS" ,"length":"41" ,"type":"char" } +}} +, "sasparams": +[ +{"COLHEADERS":"_____DELETE__THIS__RECORD_____,LIBREF,DSN,NUM_OF_APPROVALS_REQUIRED,LOADTYPE,BUSKEY,VAR_TXFROM,VAR_TXTO,VAR_BUSFROM,VAR_BUSTO,VAR_PROCESSED,CLOSE_VARS,PRE_EDIT_HOOK,POST_EDIT_HOOK,PRE_APPROVE_HOOK,POST_APPROVE_HOOK,SIGNOFF_COLS,SIGNOFF_HOOK,NOTES,RK_UNDERLYING,AUDIT_LIBDS" ,"FILTER_TEXT":"(\\"%sysfunc(datetime(), E8601DT26.6 )\\"dt < TX_TO )" ,"PKCNT":2 ,"PK":"LIBREF DSN" ,"DTVARS":"" ,"DTTMVARS":"" ,"TMVARS":"" ,"COLTYPE":"{\\"data\\":\\"_____DELETE__THIS__RECORD_____\\",\\"type\\":\\"dropdown\\",\\"source\\":[\\"No\\",\\"Yes\\"]},{\\"data\\":\\"LIBREF\\"},{\\"data\\":\\"DSN\\"},{\\"data\\":\\"NUM_OF_APPROVALS_REQUIRED\\",\\"type\\":\\"numeric\\",\\"format\\":\\"0\\"},{\\"data\\":\\"LOADTYPE\\"},{\\"data\\":\\"BUSKEY\\"},{\\"data\\":\\"VAR_TXFROM\\"},{\\"data\\":\\"VAR_TXTO\\"},{\\"data\\":\\"VAR_BUSFROM\\"},{\\"data\\":\\"VAR_BUSTO\\"},{\\"data\\":\\"VAR_PROCESSED\\"},{\\"data\\":\\"CLOSE_VARS\\"},{\\"data\\":\\"PRE_EDIT_HOOK\\"},{\\"data\\":\\"POST_EDIT_HOOK\\"},{\\"data\\":\\"PRE_APPROVE_HOOK\\"},{\\"data\\":\\"POST_APPROVE_HOOK\\"},{\\"data\\":\\"SIGNOFF_COLS\\"},{\\"data\\":\\"SIGNOFF_HOOK\\"},{\\"data\\":\\"NOTES\\"},{\\"data\\":\\"RK_UNDERLYING\\"},{\\"data\\":\\"AUDIT_LIBDS\\"}" ,"LOADTYPE":"TXTEMPORAL" ,"RK_FLAG":0 ,"CLS_FLAG":0 } +] +, "xl_rules": +[ +] +,"_DEBUG" : "" +,"_PROGRAM" : "/Public/app/dc/services/editors/getdata" +,"AUTOEXEC" : "%2Fhome%2Fsasjssrv%2Fsasjs_root%2Fsessions%2F20230310113844-59661-1678448324767%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "Linux LIN X64 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64 CentOS Linux release 7.9.2009 (Core)" +,"SYSHOSTNAME" : "CentOS-79-64-minimal" +,"SYSPROCESSID" : "41DDB6C7153602864018000000000000" +,"SYSPROCESSMODE" : "SAS Batch Mode" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "24007" +,"SYSSCPL" : "Linux" +,"SYSSITE" : "123" +,"SYSTCPIPHOSTNAME" : "CentOS-79-64-minimal" +,"SYSUSERID" : "sasjssrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2023-03-10T12:39:16.070656" +,"MEMSIZE" : "2GB" +} +` +} + +let table = 'MPE_X_TEST' + +if (_WEBIN_FILEREF1) { + const file1 = _WEBIN_FILEREF1.toString() + + if (file1.includes('MPE_X_TEST')) { + table = 'MPE_X_TEST' + } else if (file1.includes('MPE_DATADICTIONARY')) { + table = "MPE_DATADICTIONARY" + } else if (file1.includes('MPE_USERS')) { + table = "MPE_USERS" + } else if (file1.includes('MPE_TABLES')) { + table = "MPE_TABLES" + } +} + +_webout = webouts[table] \ No newline at end of file diff --git a/sas/mocks/sasjs/services/editors/getdynamiccolvals.js b/sas/mocks/sasjs/services/editors/getdynamiccolvals.js new file mode 100644 index 0000000..db7fffd --- /dev/null +++ b/sas/mocks/sasjs/services/editors/getdynamiccolvals.js @@ -0,0 +1,3092 @@ +let mpe_tables = `{"SYSDATE" : "10MAR23" +,"SYSTIME" : "12:56" +, "dynamic_values": +[ +[1 ,"MPE_ALERTS" ,"MPE_ALERTS" ] +,[2 ,"MPE_AUDIT" ,"MPE_AUDIT" ] +,[3 ,"MPE_COLUMN_LEVEL_SECURITY" ,"MPE_COLUMN_LEVEL_SECURITY" ] +,[4 ,"MPE_CONFIG" ,"MPE_CONFIG" ] +,[5 ,"MPE_DATACATALOG_LIBS" ,"MPE_DATACATALOG_LIBS" ] +,[6 ,"MPE_DATACATALOG_TABS" ,"MPE_DATACATALOG_TABS" ] +,[7 ,"MPE_DATACATALOG_VARS" ,"MPE_DATACATALOG_VARS" ] +,[8 ,"MPE_DATADICTIONARY" ,"MPE_DATADICTIONARY" ] +,[9 ,"MPE_DATALOADS" ,"MPE_DATALOADS" ] +,[10 ,"MPE_DATASTATUS_LIBS" ,"MPE_DATASTATUS_LIBS" ] +,[11 ,"MPE_DATASTATUS_TABS" ,"MPE_DATASTATUS_TABS" ] +,[12 ,"MPE_EMAILS" ,"MPE_EMAILS" ] +,[13 ,"MPE_EXCEL_CONFIG" ,"MPE_EXCEL_CONFIG" ] +,[14 ,"MPE_FILTERANYTABLE" ,"MPE_FILTERANYTABLE" ] +,[15 ,"MPE_FILTERSOURCE" ,"MPE_FILTERSOURCE" ] +,[16 ,"MPE_GROUPS" ,"MPE_GROUPS" ] +,[17 ,"MPE_LINEAGE_COLS" ,"MPE_LINEAGE_COLS" ] +,[18 ,"MPE_LINEAGE_TABS" ,"MPE_LINEAGE_TABS" ] +,[19 ,"MPE_LOADS" ,"MPE_LOADS" ] +,[20 ,"MPE_LOCKANYTABLE" ,"MPE_LOCKANYTABLE" ] +,[21 ,"MPE_MAXKEYVALUES" ,"MPE_MAXKEYVALUES" ] +,[22 ,"MPE_REQUESTS" ,"MPE_REQUESTS" ] +,[23 ,"MPE_REVIEW" ,"MPE_REVIEW" ] +,[24 ,"MPE_ROW_LEVEL_SECURITY" ,"MPE_ROW_LEVEL_SECURITY" ] +,[25 ,"MPE_SECURITY" ,"MPE_SECURITY" ] +,[26 ,"MPE_SELECTBOX" ,"MPE_SELECTBOX" ] +,[27 ,"MPE_SIGNOFFS" ,"MPE_SIGNOFFS" ] +,[28 ,"MPE_SUBMIT" ,"MPE_SUBMIT" ] +,[29 ,"MPE_TABLES" ,"MPE_TABLES" ] +,[30 ,"MPE_USERS" ,"MPE_USERS" ] +,[31 ,"MPE_VALIDATIONS" ,"MPE_VALIDATIONS" ] +,[32 ,"MPE_X_TEST" ,"MPE_X_TEST" ] +] +, "dynamic_extended_values": +[ +[1 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[1 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[2 ,"VAR_BUSFROM" ,"IS_DIFF" ,"C" ,null ,"IS_DIFF" ,0 ] +,[2 ,"VAR_BUSFROM" ,"IS_PK" ,"C" ,null ,"IS_PK" ,0 ] +,[2 ,"VAR_BUSFROM" ,"NEWVAL_NUM" ,"C" ,null ,"NEWVAL_NUM" ,0 ] +,[2 ,"VAR_BUSFROM" ,"OLDVAL_NUM" ,"C" ,null ,"OLDVAL_NUM" ,0 ] +,[2 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[3 ,"VAR_BUSFROM" ,"CLS_ACTIVE" ,"C" ,null ,"CLS_ACTIVE" ,0 ] +,[3 ,"VAR_BUSFROM" ,"CLS_HIDE" ,"C" ,null ,"CLS_HIDE" ,0 ] +,[3 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[3 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[4 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_BUSFROM" ,"VAR_ACTIVE" ,"C" ,null ,"VAR_ACTIVE" ,0 ] +,[5 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[5 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[6 ,"VAR_BUSFROM" ,"NVAR" ,"C" ,null ,"NVAR" ,0 ] +,[6 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[6 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[7 ,"VAR_BUSFROM" ,"PK_IND" ,"C" ,null ,"PK_IND" ,0 ] +,[7 ,"VAR_BUSFROM" ,"VARNUM" ,"C" ,null ,"VARNUM" ,0 ] +,[7 ,"VAR_BUSFROM" ,"LENGTH" ,"C" ,null ,"LENGTH" ,0 ] +,[8 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[8 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[9 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[9 ,"VAR_BUSFROM" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[9 ,"VAR_BUSFROM" ,"DELETED_RECORDS" ,"C" ,null ,"DELETED_RECORDS" ,0 ] +,[9 ,"VAR_BUSFROM" ,"NEW_RECORDS" ,"C" ,null ,"NEW_RECORDS" ,0 ] +,[9 ,"VAR_BUSFROM" ,"CHANGED_RECORDS" ,"C" ,null ,"CHANGED_RECORDS" ,0 ] +,[10 ,"VAR_BUSFROM" ,"TABLE_CNT" ,"C" ,null ,"TABLE_CNT" ,0 ] +,[10 ,"VAR_BUSFROM" ,"LIBSIZE" ,"C" ,null ,"LIBSIZE" ,0 ] +,[10 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[10 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[11 ,"VAR_BUSFROM" ,"NOBS" ,"C" ,null ,"NOBS" ,0 ] +,[11 ,"VAR_BUSFROM" ,"MODATE" ,"C" ,null ,"MODATE" ,0 ] +,[11 ,"VAR_BUSFROM" ,"CRDATE" ,"C" ,null ,"CRDATE" ,0 ] +,[11 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[11 ,"VAR_BUSFROM" ,"FILESIZE" ,"C" ,null ,"FILESIZE" ,0 ] +,[11 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[12 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[12 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[13 ,"VAR_BUSFROM" ,"XL_ACTIVE" ,"C" ,null ,"XL_ACTIVE" ,0 ] +,[13 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[13 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[14 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[14 ,"VAR_BUSFROM" ,"FILTER_RK" ,"C" ,null ,"FILTER_RK" ,0 ] +,[15 ,"VAR_BUSFROM" ,"SUBGROUP_ID" ,"C" ,null ,"SUBGROUP_ID" ,0 ] +,[15 ,"VAR_BUSFROM" ,"FILTER_LINE" ,"C" ,null ,"FILTER_LINE" ,0 ] +,[15 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[16 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[16 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[17 ,"VAR_BUSFROM" ,"MODIFIED_DTTM" ,"C" ,null ,"MODIFIED_DTTM" ,0 ] +,[17 ,"VAR_BUSFROM" ,"LEVEL" ,"C" ,null ,"LEVEL" ,0 ] +,[18 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[18 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[19 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[19 ,"VAR_BUSFROM" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[20 ,"VAR_BUSFROM" ,"LOCK_END_DTTM" ,"C" ,null ,"LOCK_END_DTTM" ,0 ] +,[20 ,"VAR_BUSFROM" ,"LOCK_START_DTTM" ,"C" ,null ,"LOCK_START_DTTM" ,0 ] +,[21 ,"VAR_BUSFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[21 ,"VAR_BUSFROM" ,"MAX_KEY" ,"C" ,null ,"MAX_KEY" ,0 ] +,[22 ,"VAR_BUSFROM" ,"REQUEST_DTTM" ,"C" ,null ,"REQUEST_DTTM" ,0 ] +,[23 ,"VAR_BUSFROM" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[24 ,"VAR_BUSFROM" ,"RLS_ACTIVE" ,"C" ,null ,"RLS_ACTIVE" ,0 ] +,[24 ,"VAR_BUSFROM" ,"RLS_SUBGROUP_ID" ,"C" ,null ,"RLS_SUBGROUP_ID" ,0 ] +,[24 ,"VAR_BUSFROM" ,"RLS_RK" ,"C" ,null ,"RLS_RK" ,0 ] +,[24 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[24 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[25 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[25 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[26 ,"VAR_BUSFROM" ,"SELECTBOX_ORDER" ,"C" ,null ,"SELECTBOX_ORDER" ,0 ] +,[26 ,"VAR_BUSFROM" ,"SELECTBOX_RK" ,"C" ,null ,"SELECTBOX_RK" ,0 ] +,[26 ,"VAR_BUSFROM" ,"VER_TO_DTTM" ,"C" ,null ,"VER_TO_DTTM" ,0 ] +,[26 ,"VAR_BUSFROM" ,"VER_FROM_DTTM" ,"C" ,null ,"VER_FROM_DTTM" ,0 ] +,[27 ,"VAR_BUSFROM" ,"SIGNOFF_VERSION_RK" ,"C" ,null ,"SIGNOFF_VERSION_RK" ,0 ] +,[27 ,"VAR_BUSFROM" ,"SIGNOFF_SECTION_RK" ,"C" ,null ,"SIGNOFF_SECTION_RK" ,0 ] +,[27 ,"VAR_BUSFROM" ,"TECH_TO_DTTM" ,"C" ,null ,"TECH_TO_DTTM" ,0 ] +,[27 ,"VAR_BUSFROM" ,"TECH_FROM_DTTM" ,"C" ,null ,"TECH_FROM_DTTM" ,0 ] +,[28 ,"VAR_BUSFROM" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[28 ,"VAR_BUSFROM" ,"NUM_OF_APPROVALS_REMAINING" ,"C" ,null ,"NUM_OF_APPROVALS_REMAINING" ,0 ] +,[28 ,"VAR_BUSFROM" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[28 ,"VAR_BUSFROM" ,"INPUT_VARS" ,"C" ,null ,"INPUT_VARS" ,0 ] +,[28 ,"VAR_BUSFROM" ,"INPUT_OBS" ,"C" ,null ,"INPUT_OBS" ,0 ] +,[28 ,"VAR_BUSFROM" ,"SUBMITTED_ON_DTTM" ,"C" ,null ,"SUBMITTED_ON_DTTM" ,0 ] +,[29 ,"VAR_BUSFROM" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[29 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[29 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[30 ,"VAR_BUSFROM" ,"REGISTERED_DT" ,"C" ,null ,"REGISTERED_DT" ,0 ] +,[30 ,"VAR_BUSFROM" ,"LAST_SEEN_DT" ,"C" ,null ,"LAST_SEEN_DT" ,0 ] +,[31 ,"VAR_BUSFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[31 ,"VAR_BUSFROM" ,"RULE_ACTIVE" ,"C" ,null ,"RULE_ACTIVE" ,0 ] +,[31 ,"VAR_BUSFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_BESTNUM" ,"C" ,null ,"SOME_BESTNUM" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_SHORTNUM" ,"C" ,null ,"SOME_SHORTNUM" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_TIME" ,"C" ,null ,"SOME_TIME" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_DATETIME" ,"C" ,null ,"SOME_DATETIME" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_DATE" ,"C" ,null ,"SOME_DATE" ,0 ] +,[32 ,"VAR_BUSFROM" ,"SOME_NUM" ,"C" ,null ,"SOME_NUM" ,0 ] +,[32 ,"VAR_BUSFROM" ,"PRIMARY_KEY_FIELD" ,"C" ,null ,"PRIMARY_KEY_FIELD" ,0 ] +,[1 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[1 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[2 ,"VAR_BUSTO" ,"IS_DIFF" ,"C" ,null ,"IS_DIFF" ,0 ] +,[2 ,"VAR_BUSTO" ,"IS_PK" ,"C" ,null ,"IS_PK" ,0 ] +,[2 ,"VAR_BUSTO" ,"NEWVAL_NUM" ,"C" ,null ,"NEWVAL_NUM" ,0 ] +,[2 ,"VAR_BUSTO" ,"OLDVAL_NUM" ,"C" ,null ,"OLDVAL_NUM" ,0 ] +,[2 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[3 ,"VAR_BUSTO" ,"CLS_ACTIVE" ,"C" ,null ,"CLS_ACTIVE" ,0 ] +,[3 ,"VAR_BUSTO" ,"CLS_HIDE" ,"C" ,null ,"CLS_HIDE" ,0 ] +,[3 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[3 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[4 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_BUSTO" ,"VAR_ACTIVE" ,"C" ,null ,"VAR_ACTIVE" ,0 ] +,[5 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[5 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[6 ,"VAR_BUSTO" ,"NVAR" ,"C" ,null ,"NVAR" ,0 ] +,[6 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[6 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[7 ,"VAR_BUSTO" ,"PK_IND" ,"C" ,null ,"PK_IND" ,0 ] +,[7 ,"VAR_BUSTO" ,"VARNUM" ,"C" ,null ,"VARNUM" ,0 ] +,[7 ,"VAR_BUSTO" ,"LENGTH" ,"C" ,null ,"LENGTH" ,0 ] +,[8 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[8 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[9 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[9 ,"VAR_BUSTO" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[9 ,"VAR_BUSTO" ,"DELETED_RECORDS" ,"C" ,null ,"DELETED_RECORDS" ,0 ] +,[9 ,"VAR_BUSTO" ,"NEW_RECORDS" ,"C" ,null ,"NEW_RECORDS" ,0 ] +,[9 ,"VAR_BUSTO" ,"CHANGED_RECORDS" ,"C" ,null ,"CHANGED_RECORDS" ,0 ] +,[10 ,"VAR_BUSTO" ,"TABLE_CNT" ,"C" ,null ,"TABLE_CNT" ,0 ] +,[10 ,"VAR_BUSTO" ,"LIBSIZE" ,"C" ,null ,"LIBSIZE" ,0 ] +,[10 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[10 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[11 ,"VAR_BUSTO" ,"NOBS" ,"C" ,null ,"NOBS" ,0 ] +,[11 ,"VAR_BUSTO" ,"MODATE" ,"C" ,null ,"MODATE" ,0 ] +,[11 ,"VAR_BUSTO" ,"CRDATE" ,"C" ,null ,"CRDATE" ,0 ] +,[11 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[11 ,"VAR_BUSTO" ,"FILESIZE" ,"C" ,null ,"FILESIZE" ,0 ] +,[11 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[12 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[12 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[13 ,"VAR_BUSTO" ,"XL_ACTIVE" ,"C" ,null ,"XL_ACTIVE" ,0 ] +,[13 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[13 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[14 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[14 ,"VAR_BUSTO" ,"FILTER_RK" ,"C" ,null ,"FILTER_RK" ,0 ] +,[15 ,"VAR_BUSTO" ,"SUBGROUP_ID" ,"C" ,null ,"SUBGROUP_ID" ,0 ] +,[15 ,"VAR_BUSTO" ,"FILTER_LINE" ,"C" ,null ,"FILTER_LINE" ,0 ] +,[15 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[16 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[16 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[17 ,"VAR_BUSTO" ,"MODIFIED_DTTM" ,"C" ,null ,"MODIFIED_DTTM" ,0 ] +,[17 ,"VAR_BUSTO" ,"LEVEL" ,"C" ,null ,"LEVEL" ,0 ] +,[18 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[18 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[19 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[19 ,"VAR_BUSTO" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[20 ,"VAR_BUSTO" ,"LOCK_END_DTTM" ,"C" ,null ,"LOCK_END_DTTM" ,0 ] +,[20 ,"VAR_BUSTO" ,"LOCK_START_DTTM" ,"C" ,null ,"LOCK_START_DTTM" ,0 ] +,[21 ,"VAR_BUSTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[21 ,"VAR_BUSTO" ,"MAX_KEY" ,"C" ,null ,"MAX_KEY" ,0 ] +,[22 ,"VAR_BUSTO" ,"REQUEST_DTTM" ,"C" ,null ,"REQUEST_DTTM" ,0 ] +,[23 ,"VAR_BUSTO" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[24 ,"VAR_BUSTO" ,"RLS_ACTIVE" ,"C" ,null ,"RLS_ACTIVE" ,0 ] +,[24 ,"VAR_BUSTO" ,"RLS_SUBGROUP_ID" ,"C" ,null ,"RLS_SUBGROUP_ID" ,0 ] +,[24 ,"VAR_BUSTO" ,"RLS_RK" ,"C" ,null ,"RLS_RK" ,0 ] +,[24 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[24 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[25 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[25 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[26 ,"VAR_BUSTO" ,"SELECTBOX_ORDER" ,"C" ,null ,"SELECTBOX_ORDER" ,0 ] +,[26 ,"VAR_BUSTO" ,"SELECTBOX_RK" ,"C" ,null ,"SELECTBOX_RK" ,0 ] +,[26 ,"VAR_BUSTO" ,"VER_TO_DTTM" ,"C" ,null ,"VER_TO_DTTM" ,0 ] +,[26 ,"VAR_BUSTO" ,"VER_FROM_DTTM" ,"C" ,null ,"VER_FROM_DTTM" ,0 ] +,[27 ,"VAR_BUSTO" ,"SIGNOFF_VERSION_RK" ,"C" ,null ,"SIGNOFF_VERSION_RK" ,0 ] +,[27 ,"VAR_BUSTO" ,"SIGNOFF_SECTION_RK" ,"C" ,null ,"SIGNOFF_SECTION_RK" ,0 ] +,[27 ,"VAR_BUSTO" ,"TECH_TO_DTTM" ,"C" ,null ,"TECH_TO_DTTM" ,0 ] +,[27 ,"VAR_BUSTO" ,"TECH_FROM_DTTM" ,"C" ,null ,"TECH_FROM_DTTM" ,0 ] +,[28 ,"VAR_BUSTO" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[28 ,"VAR_BUSTO" ,"NUM_OF_APPROVALS_REMAINING" ,"C" ,null ,"NUM_OF_APPROVALS_REMAINING" ,0 ] +,[28 ,"VAR_BUSTO" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[28 ,"VAR_BUSTO" ,"INPUT_VARS" ,"C" ,null ,"INPUT_VARS" ,0 ] +,[28 ,"VAR_BUSTO" ,"INPUT_OBS" ,"C" ,null ,"INPUT_OBS" ,0 ] +,[28 ,"VAR_BUSTO" ,"SUBMITTED_ON_DTTM" ,"C" ,null ,"SUBMITTED_ON_DTTM" ,0 ] +,[29 ,"VAR_BUSTO" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[29 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[29 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[30 ,"VAR_BUSTO" ,"REGISTERED_DT" ,"C" ,null ,"REGISTERED_DT" ,0 ] +,[30 ,"VAR_BUSTO" ,"LAST_SEEN_DT" ,"C" ,null ,"LAST_SEEN_DT" ,0 ] +,[31 ,"VAR_BUSTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[31 ,"VAR_BUSTO" ,"RULE_ACTIVE" ,"C" ,null ,"RULE_ACTIVE" ,0 ] +,[31 ,"VAR_BUSTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_BESTNUM" ,"C" ,null ,"SOME_BESTNUM" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_SHORTNUM" ,"C" ,null ,"SOME_SHORTNUM" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_TIME" ,"C" ,null ,"SOME_TIME" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_DATETIME" ,"C" ,null ,"SOME_DATETIME" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_DATE" ,"C" ,null ,"SOME_DATE" ,0 ] +,[32 ,"VAR_BUSTO" ,"SOME_NUM" ,"C" ,null ,"SOME_NUM" ,0 ] +,[32 ,"VAR_BUSTO" ,"PRIMARY_KEY_FIELD" ,"C" ,null ,"PRIMARY_KEY_FIELD" ,0 ] +,[1 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[1 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[2 ,"VAR_PROCESSED" ,"IS_DIFF" ,"C" ,null ,"IS_DIFF" ,0 ] +,[2 ,"VAR_PROCESSED" ,"IS_PK" ,"C" ,null ,"IS_PK" ,0 ] +,[2 ,"VAR_PROCESSED" ,"NEWVAL_NUM" ,"C" ,null ,"NEWVAL_NUM" ,0 ] +,[2 ,"VAR_PROCESSED" ,"OLDVAL_NUM" ,"C" ,null ,"OLDVAL_NUM" ,0 ] +,[2 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[3 ,"VAR_PROCESSED" ,"CLS_ACTIVE" ,"C" ,null ,"CLS_ACTIVE" ,0 ] +,[3 ,"VAR_PROCESSED" ,"CLS_HIDE" ,"C" ,null ,"CLS_HIDE" ,0 ] +,[3 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[3 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[4 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_PROCESSED" ,"VAR_ACTIVE" ,"C" ,null ,"VAR_ACTIVE" ,0 ] +,[5 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[5 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[6 ,"VAR_PROCESSED" ,"NVAR" ,"C" ,null ,"NVAR" ,0 ] +,[6 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[6 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[7 ,"VAR_PROCESSED" ,"PK_IND" ,"C" ,null ,"PK_IND" ,0 ] +,[7 ,"VAR_PROCESSED" ,"VARNUM" ,"C" ,null ,"VARNUM" ,0 ] +,[7 ,"VAR_PROCESSED" ,"LENGTH" ,"C" ,null ,"LENGTH" ,0 ] +,[8 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[8 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[9 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[9 ,"VAR_PROCESSED" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[9 ,"VAR_PROCESSED" ,"DELETED_RECORDS" ,"C" ,null ,"DELETED_RECORDS" ,0 ] +,[9 ,"VAR_PROCESSED" ,"NEW_RECORDS" ,"C" ,null ,"NEW_RECORDS" ,0 ] +,[9 ,"VAR_PROCESSED" ,"CHANGED_RECORDS" ,"C" ,null ,"CHANGED_RECORDS" ,0 ] +,[10 ,"VAR_PROCESSED" ,"TABLE_CNT" ,"C" ,null ,"TABLE_CNT" ,0 ] +,[10 ,"VAR_PROCESSED" ,"LIBSIZE" ,"C" ,null ,"LIBSIZE" ,0 ] +,[10 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[10 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[11 ,"VAR_PROCESSED" ,"NOBS" ,"C" ,null ,"NOBS" ,0 ] +,[11 ,"VAR_PROCESSED" ,"MODATE" ,"C" ,null ,"MODATE" ,0 ] +,[11 ,"VAR_PROCESSED" ,"CRDATE" ,"C" ,null ,"CRDATE" ,0 ] +,[11 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[11 ,"VAR_PROCESSED" ,"FILESIZE" ,"C" ,null ,"FILESIZE" ,0 ] +,[11 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[12 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[12 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[13 ,"VAR_PROCESSED" ,"XL_ACTIVE" ,"C" ,null ,"XL_ACTIVE" ,0 ] +,[13 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[13 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[14 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[14 ,"VAR_PROCESSED" ,"FILTER_RK" ,"C" ,null ,"FILTER_RK" ,0 ] +,[15 ,"VAR_PROCESSED" ,"SUBGROUP_ID" ,"C" ,null ,"SUBGROUP_ID" ,0 ] +,[15 ,"VAR_PROCESSED" ,"FILTER_LINE" ,"C" ,null ,"FILTER_LINE" ,0 ] +,[15 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[16 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[16 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[17 ,"VAR_PROCESSED" ,"MODIFIED_DTTM" ,"C" ,null ,"MODIFIED_DTTM" ,0 ] +,[17 ,"VAR_PROCESSED" ,"LEVEL" ,"C" ,null ,"LEVEL" ,0 ] +,[18 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[18 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[19 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[19 ,"VAR_PROCESSED" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[20 ,"VAR_PROCESSED" ,"LOCK_END_DTTM" ,"C" ,null ,"LOCK_END_DTTM" ,0 ] +,[20 ,"VAR_PROCESSED" ,"LOCK_START_DTTM" ,"C" ,null ,"LOCK_START_DTTM" ,0 ] +,[21 ,"VAR_PROCESSED" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[21 ,"VAR_PROCESSED" ,"MAX_KEY" ,"C" ,null ,"MAX_KEY" ,0 ] +,[22 ,"VAR_PROCESSED" ,"REQUEST_DTTM" ,"C" ,null ,"REQUEST_DTTM" ,0 ] +,[23 ,"VAR_PROCESSED" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[24 ,"VAR_PROCESSED" ,"RLS_ACTIVE" ,"C" ,null ,"RLS_ACTIVE" ,0 ] +,[24 ,"VAR_PROCESSED" ,"RLS_SUBGROUP_ID" ,"C" ,null ,"RLS_SUBGROUP_ID" ,0 ] +,[24 ,"VAR_PROCESSED" ,"RLS_RK" ,"C" ,null ,"RLS_RK" ,0 ] +,[24 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[24 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[25 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[25 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[26 ,"VAR_PROCESSED" ,"SELECTBOX_ORDER" ,"C" ,null ,"SELECTBOX_ORDER" ,0 ] +,[26 ,"VAR_PROCESSED" ,"SELECTBOX_RK" ,"C" ,null ,"SELECTBOX_RK" ,0 ] +,[26 ,"VAR_PROCESSED" ,"VER_TO_DTTM" ,"C" ,null ,"VER_TO_DTTM" ,0 ] +,[26 ,"VAR_PROCESSED" ,"VER_FROM_DTTM" ,"C" ,null ,"VER_FROM_DTTM" ,0 ] +,[27 ,"VAR_PROCESSED" ,"SIGNOFF_VERSION_RK" ,"C" ,null ,"SIGNOFF_VERSION_RK" ,0 ] +,[27 ,"VAR_PROCESSED" ,"SIGNOFF_SECTION_RK" ,"C" ,null ,"SIGNOFF_SECTION_RK" ,0 ] +,[27 ,"VAR_PROCESSED" ,"TECH_TO_DTTM" ,"C" ,null ,"TECH_TO_DTTM" ,0 ] +,[27 ,"VAR_PROCESSED" ,"TECH_FROM_DTTM" ,"C" ,null ,"TECH_FROM_DTTM" ,0 ] +,[28 ,"VAR_PROCESSED" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[28 ,"VAR_PROCESSED" ,"NUM_OF_APPROVALS_REMAINING" ,"C" ,null ,"NUM_OF_APPROVALS_REMAINING" ,0 ] +,[28 ,"VAR_PROCESSED" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[28 ,"VAR_PROCESSED" ,"INPUT_VARS" ,"C" ,null ,"INPUT_VARS" ,0 ] +,[28 ,"VAR_PROCESSED" ,"INPUT_OBS" ,"C" ,null ,"INPUT_OBS" ,0 ] +,[28 ,"VAR_PROCESSED" ,"SUBMITTED_ON_DTTM" ,"C" ,null ,"SUBMITTED_ON_DTTM" ,0 ] +,[29 ,"VAR_PROCESSED" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[29 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[29 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[30 ,"VAR_PROCESSED" ,"REGISTERED_DT" ,"C" ,null ,"REGISTERED_DT" ,0 ] +,[30 ,"VAR_PROCESSED" ,"LAST_SEEN_DT" ,"C" ,null ,"LAST_SEEN_DT" ,0 ] +,[31 ,"VAR_PROCESSED" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[31 ,"VAR_PROCESSED" ,"RULE_ACTIVE" ,"C" ,null ,"RULE_ACTIVE" ,0 ] +,[31 ,"VAR_PROCESSED" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_BESTNUM" ,"C" ,null ,"SOME_BESTNUM" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_SHORTNUM" ,"C" ,null ,"SOME_SHORTNUM" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_TIME" ,"C" ,null ,"SOME_TIME" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_DATETIME" ,"C" ,null ,"SOME_DATETIME" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_DATE" ,"C" ,null ,"SOME_DATE" ,0 ] +,[32 ,"VAR_PROCESSED" ,"SOME_NUM" ,"C" ,null ,"SOME_NUM" ,0 ] +,[32 ,"VAR_PROCESSED" ,"PRIMARY_KEY_FIELD" ,"C" ,null ,"PRIMARY_KEY_FIELD" ,0 ] +,[1 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[1 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[2 ,"VAR_TXFROM" ,"IS_DIFF" ,"C" ,null ,"IS_DIFF" ,0 ] +,[2 ,"VAR_TXFROM" ,"IS_PK" ,"C" ,null ,"IS_PK" ,0 ] +,[2 ,"VAR_TXFROM" ,"NEWVAL_NUM" ,"C" ,null ,"NEWVAL_NUM" ,0 ] +,[2 ,"VAR_TXFROM" ,"OLDVAL_NUM" ,"C" ,null ,"OLDVAL_NUM" ,0 ] +,[2 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[3 ,"VAR_TXFROM" ,"CLS_ACTIVE" ,"C" ,null ,"CLS_ACTIVE" ,0 ] +,[3 ,"VAR_TXFROM" ,"CLS_HIDE" ,"C" ,null ,"CLS_HIDE" ,0 ] +,[3 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[3 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[4 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[4 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[4 ,"VAR_TXFROM" ,"VAR_ACTIVE" ,"C" ,null ,"VAR_ACTIVE" ,0 ] +,[5 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[5 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[6 ,"VAR_TXFROM" ,"NVAR" ,"C" ,null ,"NVAR" ,0 ] +,[6 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[6 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[7 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[7 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[7 ,"VAR_TXFROM" ,"PK_IND" ,"C" ,null ,"PK_IND" ,0 ] +,[7 ,"VAR_TXFROM" ,"VARNUM" ,"C" ,null ,"VARNUM" ,0 ] +,[7 ,"VAR_TXFROM" ,"LENGTH" ,"C" ,null ,"LENGTH" ,0 ] +,[8 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[8 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[9 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[9 ,"VAR_TXFROM" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[9 ,"VAR_TXFROM" ,"DELETED_RECORDS" ,"C" ,null ,"DELETED_RECORDS" ,0 ] +,[9 ,"VAR_TXFROM" ,"NEW_RECORDS" ,"C" ,null ,"NEW_RECORDS" ,0 ] +,[9 ,"VAR_TXFROM" ,"CHANGED_RECORDS" ,"C" ,null ,"CHANGED_RECORDS" ,0 ] +,[10 ,"VAR_TXFROM" ,"TABLE_CNT" ,"C" ,null ,"TABLE_CNT" ,0 ] +,[10 ,"VAR_TXFROM" ,"LIBSIZE" ,"C" ,null ,"LIBSIZE" ,0 ] +,[10 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[10 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[11 ,"VAR_TXFROM" ,"NOBS" ,"C" ,null ,"NOBS" ,0 ] +,[11 ,"VAR_TXFROM" ,"MODATE" ,"C" ,null ,"MODATE" ,0 ] +,[11 ,"VAR_TXFROM" ,"CRDATE" ,"C" ,null ,"CRDATE" ,0 ] +,[11 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[11 ,"VAR_TXFROM" ,"FILESIZE" ,"C" ,null ,"FILESIZE" ,0 ] +,[11 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[12 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[12 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[13 ,"VAR_TXFROM" ,"XL_ACTIVE" ,"C" ,null ,"XL_ACTIVE" ,0 ] +,[13 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[13 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[14 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[14 ,"VAR_TXFROM" ,"FILTER_RK" ,"C" ,null ,"FILTER_RK" ,0 ] +,[15 ,"VAR_TXFROM" ,"SUBGROUP_ID" ,"C" ,null ,"SUBGROUP_ID" ,0 ] +,[15 ,"VAR_TXFROM" ,"FILTER_LINE" ,"C" ,null ,"FILTER_LINE" ,0 ] +,[15 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[16 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[16 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[17 ,"VAR_TXFROM" ,"MODIFIED_DTTM" ,"C" ,null ,"MODIFIED_DTTM" ,0 ] +,[17 ,"VAR_TXFROM" ,"LEVEL" ,"C" ,null ,"LEVEL" ,0 ] +,[18 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[18 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[19 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[19 ,"VAR_TXFROM" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[20 ,"VAR_TXFROM" ,"LOCK_END_DTTM" ,"C" ,null ,"LOCK_END_DTTM" ,0 ] +,[20 ,"VAR_TXFROM" ,"LOCK_START_DTTM" ,"C" ,null ,"LOCK_START_DTTM" ,0 ] +,[21 ,"VAR_TXFROM" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[21 ,"VAR_TXFROM" ,"MAX_KEY" ,"C" ,null ,"MAX_KEY" ,0 ] +,[22 ,"VAR_TXFROM" ,"REQUEST_DTTM" ,"C" ,null ,"REQUEST_DTTM" ,0 ] +,[23 ,"VAR_TXFROM" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[24 ,"VAR_TXFROM" ,"RLS_ACTIVE" ,"C" ,null ,"RLS_ACTIVE" ,0 ] +,[24 ,"VAR_TXFROM" ,"RLS_SUBGROUP_ID" ,"C" ,null ,"RLS_SUBGROUP_ID" ,0 ] +,[24 ,"VAR_TXFROM" ,"RLS_RK" ,"C" ,null ,"RLS_RK" ,0 ] +,[24 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[24 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[25 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[25 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[26 ,"VAR_TXFROM" ,"SELECTBOX_ORDER" ,"C" ,null ,"SELECTBOX_ORDER" ,0 ] +,[26 ,"VAR_TXFROM" ,"SELECTBOX_RK" ,"C" ,null ,"SELECTBOX_RK" ,0 ] +,[26 ,"VAR_TXFROM" ,"VER_TO_DTTM" ,"C" ,null ,"VER_TO_DTTM" ,0 ] +,[26 ,"VAR_TXFROM" ,"VER_FROM_DTTM" ,"C" ,null ,"VER_FROM_DTTM" ,0 ] +,[27 ,"VAR_TXFROM" ,"SIGNOFF_VERSION_RK" ,"C" ,null ,"SIGNOFF_VERSION_RK" ,0 ] +,[27 ,"VAR_TXFROM" ,"SIGNOFF_SECTION_RK" ,"C" ,null ,"SIGNOFF_SECTION_RK" ,0 ] +,[27 ,"VAR_TXFROM" ,"TECH_TO_DTTM" ,"C" ,null ,"TECH_TO_DTTM" ,0 ] +,[27 ,"VAR_TXFROM" ,"TECH_FROM_DTTM" ,"C" ,null ,"TECH_FROM_DTTM" ,0 ] +,[28 ,"VAR_TXFROM" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[28 ,"VAR_TXFROM" ,"NUM_OF_APPROVALS_REMAINING" ,"C" ,null ,"NUM_OF_APPROVALS_REMAINING" ,0 ] +,[28 ,"VAR_TXFROM" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[28 ,"VAR_TXFROM" ,"INPUT_VARS" ,"C" ,null ,"INPUT_VARS" ,0 ] +,[28 ,"VAR_TXFROM" ,"INPUT_OBS" ,"C" ,null ,"INPUT_OBS" ,0 ] +,[28 ,"VAR_TXFROM" ,"SUBMITTED_ON_DTTM" ,"C" ,null ,"SUBMITTED_ON_DTTM" ,0 ] +,[29 ,"VAR_TXFROM" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[29 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[29 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[30 ,"VAR_TXFROM" ,"REGISTERED_DT" ,"C" ,null ,"REGISTERED_DT" ,0 ] +,[30 ,"VAR_TXFROM" ,"LAST_SEEN_DT" ,"C" ,null ,"LAST_SEEN_DT" ,0 ] +,[31 ,"VAR_TXFROM" ,"TX_TO" ,"C" ,null ,"TX_TO" ,0 ] +,[31 ,"VAR_TXFROM" ,"RULE_ACTIVE" ,"C" ,null ,"RULE_ACTIVE" ,0 ] +,[31 ,"VAR_TXFROM" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,1 ] +,[32 ,"VAR_TXFROM" ,"SOME_BESTNUM" ,"C" ,null ,"SOME_BESTNUM" ,0 ] +,[32 ,"VAR_TXFROM" ,"SOME_SHORTNUM" ,"C" ,null ,"SOME_SHORTNUM" ,0 ] +,[32 ,"VAR_TXFROM" ,"SOME_TIME" ,"C" ,null ,"SOME_TIME" ,0 ] +,[32 ,"VAR_TXFROM" ,"SOME_DATETIME" ,"C" ,null ,"SOME_DATETIME" ,0 ] +,[32 ,"VAR_TXFROM" ,"SOME_DATE" ,"C" ,null ,"SOME_DATE" ,0 ] +,[32 ,"VAR_TXFROM" ,"SOME_NUM" ,"C" ,null ,"SOME_NUM" ,0 ] +,[32 ,"VAR_TXFROM" ,"PRIMARY_KEY_FIELD" ,"C" ,null ,"PRIMARY_KEY_FIELD" ,0 ] +,[1 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[1 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[2 ,"VAR_TXTO" ,"IS_DIFF" ,"C" ,null ,"IS_DIFF" ,0 ] +,[2 ,"VAR_TXTO" ,"IS_PK" ,"C" ,null ,"IS_PK" ,0 ] +,[2 ,"VAR_TXTO" ,"NEWVAL_NUM" ,"C" ,null ,"NEWVAL_NUM" ,0 ] +,[2 ,"VAR_TXTO" ,"OLDVAL_NUM" ,"C" ,null ,"OLDVAL_NUM" ,0 ] +,[2 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[3 ,"VAR_TXTO" ,"CLS_ACTIVE" ,"C" ,null ,"CLS_ACTIVE" ,0 ] +,[3 ,"VAR_TXTO" ,"CLS_HIDE" ,"C" ,null ,"CLS_HIDE" ,0 ] +,[3 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[3 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[4 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[4 ,"VAR_TXTO" ,"VAR_ACTIVE" ,"C" ,null ,"VAR_ACTIVE" ,0 ] +,[5 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[5 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[6 ,"VAR_TXTO" ,"NVAR" ,"C" ,null ,"NVAR" ,0 ] +,[6 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[6 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[7 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[7 ,"VAR_TXTO" ,"PK_IND" ,"C" ,null ,"PK_IND" ,0 ] +,[7 ,"VAR_TXTO" ,"VARNUM" ,"C" ,null ,"VARNUM" ,0 ] +,[7 ,"VAR_TXTO" ,"LENGTH" ,"C" ,null ,"LENGTH" ,0 ] +,[8 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[8 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[9 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[9 ,"VAR_TXTO" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[9 ,"VAR_TXTO" ,"DELETED_RECORDS" ,"C" ,null ,"DELETED_RECORDS" ,0 ] +,[9 ,"VAR_TXTO" ,"NEW_RECORDS" ,"C" ,null ,"NEW_RECORDS" ,0 ] +,[9 ,"VAR_TXTO" ,"CHANGED_RECORDS" ,"C" ,null ,"CHANGED_RECORDS" ,0 ] +,[10 ,"VAR_TXTO" ,"TABLE_CNT" ,"C" ,null ,"TABLE_CNT" ,0 ] +,[10 ,"VAR_TXTO" ,"LIBSIZE" ,"C" ,null ,"LIBSIZE" ,0 ] +,[10 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[10 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[11 ,"VAR_TXTO" ,"NOBS" ,"C" ,null ,"NOBS" ,0 ] +,[11 ,"VAR_TXTO" ,"MODATE" ,"C" ,null ,"MODATE" ,0 ] +,[11 ,"VAR_TXTO" ,"CRDATE" ,"C" ,null ,"CRDATE" ,0 ] +,[11 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[11 ,"VAR_TXTO" ,"FILESIZE" ,"C" ,null ,"FILESIZE" ,0 ] +,[11 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[12 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[12 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[13 ,"VAR_TXTO" ,"XL_ACTIVE" ,"C" ,null ,"XL_ACTIVE" ,0 ] +,[13 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[13 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[14 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[14 ,"VAR_TXTO" ,"FILTER_RK" ,"C" ,null ,"FILTER_RK" ,0 ] +,[15 ,"VAR_TXTO" ,"SUBGROUP_ID" ,"C" ,null ,"SUBGROUP_ID" ,0 ] +,[15 ,"VAR_TXTO" ,"FILTER_LINE" ,"C" ,null ,"FILTER_LINE" ,0 ] +,[15 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[16 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[16 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[17 ,"VAR_TXTO" ,"MODIFIED_DTTM" ,"C" ,null ,"MODIFIED_DTTM" ,0 ] +,[17 ,"VAR_TXTO" ,"LEVEL" ,"C" ,null ,"LEVEL" ,0 ] +,[18 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[18 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[19 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[19 ,"VAR_TXTO" ,"DURATION" ,"C" ,null ,"DURATION" ,0 ] +,[20 ,"VAR_TXTO" ,"LOCK_END_DTTM" ,"C" ,null ,"LOCK_END_DTTM" ,0 ] +,[20 ,"VAR_TXTO" ,"LOCK_START_DTTM" ,"C" ,null ,"LOCK_START_DTTM" ,0 ] +,[21 ,"VAR_TXTO" ,"PROCESSED_DTTM" ,"C" ,null ,"PROCESSED_DTTM" ,0 ] +,[21 ,"VAR_TXTO" ,"MAX_KEY" ,"C" ,null ,"MAX_KEY" ,0 ] +,[22 ,"VAR_TXTO" ,"REQUEST_DTTM" ,"C" ,null ,"REQUEST_DTTM" ,0 ] +,[23 ,"VAR_TXTO" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[24 ,"VAR_TXTO" ,"RLS_ACTIVE" ,"C" ,null ,"RLS_ACTIVE" ,0 ] +,[24 ,"VAR_TXTO" ,"RLS_SUBGROUP_ID" ,"C" ,null ,"RLS_SUBGROUP_ID" ,0 ] +,[24 ,"VAR_TXTO" ,"RLS_RK" ,"C" ,null ,"RLS_RK" ,0 ] +,[24 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[24 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[25 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[25 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[26 ,"VAR_TXTO" ,"SELECTBOX_ORDER" ,"C" ,null ,"SELECTBOX_ORDER" ,0 ] +,[26 ,"VAR_TXTO" ,"SELECTBOX_RK" ,"C" ,null ,"SELECTBOX_RK" ,0 ] +,[26 ,"VAR_TXTO" ,"VER_TO_DTTM" ,"C" ,null ,"VER_TO_DTTM" ,0 ] +,[26 ,"VAR_TXTO" ,"VER_FROM_DTTM" ,"C" ,null ,"VER_FROM_DTTM" ,0 ] +,[27 ,"VAR_TXTO" ,"SIGNOFF_VERSION_RK" ,"C" ,null ,"SIGNOFF_VERSION_RK" ,0 ] +,[27 ,"VAR_TXTO" ,"SIGNOFF_SECTION_RK" ,"C" ,null ,"SIGNOFF_SECTION_RK" ,0 ] +,[27 ,"VAR_TXTO" ,"TECH_TO_DTTM" ,"C" ,null ,"TECH_TO_DTTM" ,0 ] +,[27 ,"VAR_TXTO" ,"TECH_FROM_DTTM" ,"C" ,null ,"TECH_FROM_DTTM" ,0 ] +,[28 ,"VAR_TXTO" ,"REVIEWED_ON_DTTM" ,"C" ,null ,"REVIEWED_ON_DTTM" ,0 ] +,[28 ,"VAR_TXTO" ,"NUM_OF_APPROVALS_REMAINING" ,"C" ,null ,"NUM_OF_APPROVALS_REMAINING" ,0 ] +,[28 ,"VAR_TXTO" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[28 ,"VAR_TXTO" ,"INPUT_VARS" ,"C" ,null ,"INPUT_VARS" ,0 ] +,[28 ,"VAR_TXTO" ,"INPUT_OBS" ,"C" ,null ,"INPUT_OBS" ,0 ] +,[28 ,"VAR_TXTO" ,"SUBMITTED_ON_DTTM" ,"C" ,null ,"SUBMITTED_ON_DTTM" ,0 ] +,[29 ,"VAR_TXTO" ,"NUM_OF_APPROVALS_REQUIRED" ,"C" ,null ,"NUM_OF_APPROVALS_REQUIRED" ,0 ] +,[29 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[29 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[30 ,"VAR_TXTO" ,"REGISTERED_DT" ,"C" ,null ,"REGISTERED_DT" ,0 ] +,[30 ,"VAR_TXTO" ,"LAST_SEEN_DT" ,"C" ,null ,"LAST_SEEN_DT" ,0 ] +,[31 ,"VAR_TXTO" ,"TX_TO" ,"C" ,null ,"TX_TO" ,1 ] +,[31 ,"VAR_TXTO" ,"RULE_ACTIVE" ,"C" ,null ,"RULE_ACTIVE" ,0 ] +,[31 ,"VAR_TXTO" ,"TX_FROM" ,"C" ,null ,"TX_FROM" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_BESTNUM" ,"C" ,null ,"SOME_BESTNUM" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_SHORTNUM" ,"C" ,null ,"SOME_SHORTNUM" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_TIME" ,"C" ,null ,"SOME_TIME" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_DATETIME" ,"C" ,null ,"SOME_DATETIME" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_DATE" ,"C" ,null ,"SOME_DATE" ,0 ] +,[32 ,"VAR_TXTO" ,"SOME_NUM" ,"C" ,null ,"SOME_NUM" ,0 ] +,[32 ,"VAR_TXTO" ,"PRIMARY_KEY_FIELD" ,"C" ,null ,"PRIMARY_KEY_FIELD" ,0 ] +] +,"_DEBUG" : "" +,"_PROGRAM" : "/Public/app/dc/services/editors/getdynamiccolvals" +,"AUTOEXEC" : "%2Fhome%2Fsasjssrv%2Fsasjs_root%2Fsessions%2F20230310115651-53694-1678449411618%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "Linux LIN X64 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64 CentOS Linux release 7.9.2009 (Core)" +,"SYSHOSTNAME" : "CentOS-79-64-minimal" +,"SYSPROCESSID" : "41DDB6C824EC04924018000000000000" +,"SYSPROCESSMODE" : "SAS Batch Mode" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "25810" +,"SYSSCPL" : "Linux" +,"SYSSITE" : "123" +,"SYSTCPIPHOSTNAME" : "CentOS-79-64-minimal" +,"SYSUSERID" : "sasjssrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2023-03-10T12:56:52.295466" +,"MEMSIZE" : "2GB" +} +` + +let other = `{"SYSDATE" : "29SEP22" +,"SYSTIME" : "11:51" +, "dynamic_values": +[ + [ + 1, + "0.0010556476", + 0.00105564761956 + ], + [ + 2, + "0.0052189599", + 0.00521895988156 + ], + [ + 3, + "0.0058409725", + 0.0058409725343 + ], + [ + 4, + "0.006130504", + 0.00613050395908 + ], + [ + 5, + "0.0130502507", + 0.01305025071513 + ], + [ + 6, + "0.0144214248", + 0.01442142483518 + ], + [ + 7, + "0.0242283885", + 0.02422838845487 + ], + [ + 8, + "0.0256445333", + 0.0256445333481 + ], + [ + 9, + "0.0262452592", + 0.02624525922641 + ], + [ + 10, + "0.0289132246", + 0.02891322459509 + ], + [ + 11, + "0.029728665", + 0.02972866503043 + ], + [ + 12, + "0.0310356193", + 0.03103561933666 + ], + [ + 13, + "0.0315013211", + 0.03150132113671 + ], + [ + 14, + "0.0352235506", + 0.03522355064527 + ], + [ + 15, + "0.0352940625", + 0.03529406247441 + ], + [ + 16, + "0.0397578571", + 0.03975785711768 + ], + [ + 17, + "0.0431997366", + 0.04319973664507 + ], + [ + 18, + "0.0452116919", + 0.04521169189606 + ], + [ + 19, + "0.0478734295", + 0.04787342951068 + ], + [ + 20, + "0.0494814422", + 0.04948144222119 + ], + [ + 21, + "0.0509991274", + 0.05099912735214 + ], + [ + 22, + "0.0511230966", + 0.05112309663143 + ], + [ + 23, + "0.0540671353", + 0.05406713534801 + ], + [ + 24, + "0.0545679247", + 0.05456792472608 + ], + [ + 25, + "0.0560880252", + 0.05608802524213 + ], + [ + 26, + "0.0564905135", + 0.0564905135224 + ], + [ + 27, + "0.0565994717", + 0.05659947174442 + ], + [ + 28, + "0.0627542204", + 0.06275422035844 + ], + [ + 29, + "0.0628753263", + 0.06287532628647 + ], + [ + 30, + "0.0667286301", + 0.06672863013424 + ], + [ + 31, + "0.0701107537", + 0.0701107536769 + ], + [ + 32, + "0.0711784712", + 0.07117847123703 + ], + [ + 33, + "0.0737551018", + 0.07375510180078 + ], + [ + 34, + "0.0766677759", + 0.07666777590134 + ], + [ + 35, + "0.0812941534", + 0.08129415338919 + ], + [ + 36, + "0.0816029059", + 0.08160290591493 + ], + [ + 37, + "0.0871032426", + 0.0871032425608 + ], + [ + 38, + "0.0887682015", + 0.08876820145583 + ], + [ + 39, + "0.089252377", + 0.08925237697048 + ], + [ + 40, + "0.0913677868", + 0.09136778679274 + ], + [ + 41, + "0.0925364206", + 0.09253642060446 + ], + [ + 42, + "0.0933360565", + 0.0933360564957 + ], + [ + 43, + "0.0936049917", + 0.09360499172173 + ], + [ + 44, + "0.0967498683", + 0.09674986828898 + ], + [ + 45, + "0.0981378053", + 0.09813780528406 + ], + [ + 46, + "0.104656633", + 0.10465663303837 + ], + [ + 47, + "0.1081672963", + 0.10816729632586 + ], + [ + 48, + "0.1096644709", + 0.10966447093974 + ], + [ + 49, + "0.1156573501", + 0.11565735010227 + ], + [ + 50, + "0.1175322771", + 0.11753227706883 + ], + [ + 51, + "0.1195091284", + 0.11950912844366 + ], + [ + 52, + "0.1197331572", + 0.11973315715777 + ], + [ + 53, + "0.120146513", + 0.12014651304117 + ], + [ + 54, + "0.1212504833", + 0.12125048326386 + ], + [ + 55, + "0.124728859", + 0.12472885899465 + ], + [ + 56, + "0.1259848066", + 0.12598480662609 + ], + [ + 57, + "0.1289282409", + 0.12892824091433 + ], + [ + 58, + "0.1300212565", + 0.13002125645523 + ], + [ + 59, + "0.1303541368", + 0.13035413675492 + ], + [ + 60, + "0.1319413279", + 0.13194132788662 + ], + [ + 61, + "0.1323780209", + 0.13237802085111 + ], + [ + 62, + "0.1379828803", + 0.13798288029524 + ], + [ + 63, + "0.1382724979", + 0.13827249786736 + ], + [ + 64, + "0.1386283367", + 0.13862833666551 + ], + [ + 65, + "0.1415707628", + 0.14157076279705 + ], + [ + 66, + "0.1420672057", + 0.14206720569267 + ], + [ + 67, + "0.1423215792", + 0.14232157922457 + ], + [ + 68, + "0.1439077361", + 0.14390773612256 + ], + [ + 69, + "0.144336483", + 0.14433648304284 + ], + [ + 70, + "0.1449067272", + 0.14490672719893 + ], + [ + 71, + "0.1462393632", + 0.14623936319082 + ], + [ + 72, + "0.1462428794", + 0.14624287939921 + ], + [ + 73, + "0.1529210709", + 0.15292107088161 + ], + [ + 74, + "0.152996922", + 0.15299692198308 + ], + [ + 75, + "0.1537194239", + 0.15371942387601 + ], + [ + 76, + "0.1569773956", + 0.15697739560016 + ], + [ + 77, + "0.1578208316", + 0.15782083159211 + ], + [ + 78, + "0.1670272132", + 0.16702721322282 + ], + [ + 79, + "0.1693538531", + 0.1693538530587 + ], + [ + 80, + "0.1744914386", + 0.17449143863026 + ], + [ + 81, + "0.177699349", + 0.17769934897203 + ], + [ + 82, + "0.1820049724", + 0.18200497244578 + ], + [ + 83, + "0.1826881851", + 0.1826881850989 + ], + [ + 84, + "0.18323942", + 0.18323942002991 + ], + [ + 85, + "0.1852788567", + 0.18527885674744 + ], + [ + 86, + "0.1855629674", + 0.18556296740917 + ], + [ + 87, + "0.1876353227", + 0.18763532265445 + ], + [ + 88, + "0.1892374359", + 0.18923743590211 + ], + [ + 89, + "0.1941492833", + 0.19414928331698 + ], + [ + 90, + "0.1951624854", + 0.19516248544452 + ], + [ + 91, + "0.1962652361", + 0.1962652361003 + ], + [ + 92, + "0.2007414457", + 0.20074144573916 + ], + [ + 93, + "0.2009625971", + 0.20096259713217 + ], + [ + 94, + "0.2012765562", + 0.20127655621677 + ], + [ + 95, + "0.2035595692", + 0.20355956917794 + ], + [ + 96, + "0.2047977723", + 0.20479777232035 + ], + [ + 97, + "0.2058004682", + 0.20580046819793 + ], + [ + 98, + "0.2135380591", + 0.21353805913288 + ], + [ + 99, + "0.2165553161", + 0.21655531610201 + ], + [ + 100, + "0.2211957947", + 0.22119579474497 + ], + [ + 101, + "0.2214682853", + 0.22146828529493 + ], + [ + 102, + "0.2243504483", + 0.22435044833661 + ], + [ + 103, + "0.2248352795", + 0.22483527950236 + ], + [ + 104, + "0.2339701779", + 0.23397017793449 + ], + [ + 105, + "0.2342108727", + 0.23421087266607 + ], + [ + 106, + "0.2345068465", + 0.23450684651476 + ], + [ + 107, + "0.2349950388", + 0.23499503882368 + ], + [ + 108, + "0.2363862056", + 0.23638620564545 + ], + [ + 109, + "0.2381973272", + 0.23819732723673 + ], + [ + 110, + "0.2445727066", + 0.24457270663444 + ], + [ + 111, + "0.2472797596", + 0.24727975961159 + ], + [ + 112, + "0.2474831744", + 0.24748317443182 + ], + [ + 113, + "0.2498985614", + 0.24989856139286 + ], + [ + 114, + "0.2507105862", + 0.25071058620266 + ], + [ + 115, + "0.2527495829", + 0.25274958287028 + ], + [ + 116, + "0.2531839876", + 0.2531839875752 + ], + [ + 117, + "0.2537911871", + 0.25379118707673 + ], + [ + 118, + "0.2559820187", + 0.25598201866074 + ], + [ + 119, + "0.2582184958", + 0.25821849576114 + ], + [ + 120, + "0.2594222428", + 0.25942224276225 + ], + [ + 121, + "0.2611002812", + 0.26110028115152 + ], + [ + 122, + "0.2611194152", + 0.26111941517382 + ], + [ + 123, + "0.2656607904", + 0.26566079038458 + ], + [ + 124, + "0.2672296191", + 0.26722961909474 + ], + [ + 125, + "0.2704750268", + 0.27047502681169 + ], + [ + 126, + "0.2776136004", + 0.2776136003796 + ], + [ + 127, + "0.2794422001", + 0.27944220010165 + ], + [ + 128, + "0.2815401746", + 0.28154017463398 + ], + [ + 129, + "0.282674513", + 0.28267451295753 + ], + [ + 130, + "0.2827376883", + 0.28273768829309 + ], + [ + 131, + "0.2835610128", + 0.28356101283969 + ], + [ + 132, + "0.2836767511", + 0.28367675109006 + ], + [ + 133, + "0.2862014506", + 0.28620145064136 + ], + [ + 134, + "0.2874902935", + 0.28749029351747 + ], + [ + 135, + "0.2921020027", + 0.29210200267476 + ], + [ + 136, + "0.2921788075", + 0.29217880745054 + ], + [ + 137, + "0.2922141674", + 0.2922141674404 + ], + [ + 138, + "0.2959326474", + 0.29593264744427 + ], + [ + 139, + "0.2994232058", + 0.29942320580567 + ], + [ + 140, + "0.3030040531", + 0.30300405309675 + ], + [ + 141, + "0.3072776535", + 0.30727765350941 + ], + [ + 142, + "0.3083657815", + 0.30836578146944 + ], + [ + 143, + "0.3091963638", + 0.30919636381286 + ], + [ + 144, + "0.3103368815", + 0.31033688146171 + ], + [ + 145, + "0.3116543509", + 0.31165435086547 + ], + [ + 146, + "0.3119503438", + 0.31195034380627 + ], + [ + 147, + "0.3125689832", + 0.31256898320865 + ], + [ + 148, + "0.3128095354", + 0.31280953544788 + ], + [ + 149, + "0.3137571762", + 0.31375717619143 + ], + [ + 150, + "0.3141113638", + 0.31411136375465 + ], + [ + 151, + "0.3155595764", + 0.31555957641245 + ], + [ + 152, + "0.3183550259", + 0.31835502587182 + ], + [ + 153, + "0.319197504", + 0.3191975039985 + ], + [ + 154, + "0.3198258208", + 0.31982582077375 + ], + [ + 155, + "0.3202724426", + 0.32027244256822 + ], + [ + 156, + "0.3206662695", + 0.32066626954854 + ], + [ + 157, + "0.3246063573", + 0.32460635729348 + ], + [ + 158, + "0.3265619778", + 0.32656197777323 + ], + [ + 159, + "0.3267726765", + 0.32677267646732 + ], + [ + 160, + "0.3281118005", + 0.32811180051793 + ], + [ + 161, + "0.3300200963", + 0.33002009630669 + ], + [ + 162, + "0.3325596104", + 0.33255961040619 + ], + [ + 163, + "0.3383520904", + 0.338352090371 + ], + [ + 164, + "0.3418517105", + 0.34185171050105 + ], + [ + 165, + "0.3420869644", + 0.34208696444616 + ], + [ + 166, + "0.3429290007", + 0.34292900066027 + ], + [ + 167, + "0.3493668583", + 0.34936685829859 + ], + [ + 168, + "0.3515388879", + 0.3515388878768 + ], + [ + 169, + "0.3564928693", + 0.35649286925629 + ], + [ + 170, + "0.356953426", + 0.35695342596478 + ], + [ + 171, + "0.3581244058", + 0.35812440577807 + ], + [ + 172, + "0.3597661026", + 0.35976610256348 + ], + [ + 173, + "0.35980724", + 0.35980724001294 + ], + [ + 174, + "0.3612681815", + 0.36126818152203 + ], + [ + 175, + "0.361830231", + 0.36183023097078 + ], + [ + 176, + "0.3618709479", + 0.3618709479281 + ], + [ + 177, + "0.3677867113", + 0.36778671125312 + ], + [ + 178, + "0.3682404889", + 0.36824048886459 + ], + [ + 179, + "0.3704071368", + 0.3704071367953 + ], + [ + 180, + "0.3713489284", + 0.37134892836741 + ], + [ + 181, + "0.372728008", + 0.37272800801914 + ], + [ + 182, + "0.3738538126", + 0.37385381263394 + ], + [ + 183, + "0.3744010908", + 0.37440109084099 + ], + [ + 184, + "0.3761253238", + 0.37612532376131 + ], + [ + 185, + "0.3781310042", + 0.37813100422645 + ], + [ + 186, + "0.378220983", + 0.37822098302572 + ], + [ + 187, + "0.3783546949", + 0.37835469487046 + ], + [ + 188, + "0.3805264069", + 0.38052640686767 + ], + [ + 189, + "0.3830738665", + 0.38307386654572 + ], + [ + 190, + "0.383970143", + 0.38397014298661 + ], + [ + 191, + "0.3880386531", + 0.38803865312972 + ], + [ + 192, + "0.3893924595", + 0.38939245948074 + ], + [ + 193, + "0.3899468637", + 0.38994686370247 + ], + [ + 194, + "0.3976062771", + 0.39760627709217 + ], + [ + 195, + "0.4007478316", + 0.4007478316318 + ], + [ + 196, + "0.4041808939", + 0.4041808938627 + ], + [ + 197, + "0.4048613139", + 0.40486131394508 + ], + [ + 198, + "0.4063810457", + 0.40638104565738 + ], + [ + 199, + "0.4085182563", + 0.40851825634414 + ], + [ + 200, + "0.4089814818", + 0.40898148175747 + ], + [ + 201, + "0.4150194705", + 0.41501947046025 + ], + [ + 202, + "0.4162862289", + 0.41628622888414 + ], + [ + 203, + "0.4176403854", + 0.41764038541244 + ], + [ + 204, + "0.4184582934", + 0.41845829338694 + ], + [ + 205, + "0.4225753753", + 0.42257537526198 + ], + [ + 206, + "0.4236965931", + 0.4236965931131 + ], + [ + 207, + "0.4242641187", + 0.42426411873859 + ], + [ + 208, + "0.4249742881", + 0.42497428805798 + ], + [ + 209, + "0.4285296958", + 0.42852969580727 + ], + [ + 210, + "0.4358694048", + 0.43586940478341 + ], + [ + 211, + "0.4378844986", + 0.43788449859148 + ], + [ + 212, + "0.4383217452", + 0.43832174522724 + ], + [ + 213, + "0.4434180783", + 0.443418078331 + ], + [ + 214, + "0.4487700213", + 0.44877002129739 + ], + [ + 215, + "0.4527745622", + 0.45277456215246 + ], + [ + 216, + "0.4540794913", + 0.45407949129775 + ], + [ + 217, + "0.4578205154", + 0.45782051536153 + ], + [ + 218, + "0.4586652529", + 0.45866525287677 + ], + [ + 219, + "0.458775894", + 0.45877589399869 + ], + [ + 220, + "0.4601080424", + 0.46010804244322 + ], + [ + 221, + "0.4610861705", + 0.46108617049692 + ], + [ + 222, + "0.4633602372", + 0.46336023717343 + ], + [ + 223, + "0.4651395569", + 0.46513955689274 + ], + [ + 224, + "0.469918695", + 0.46991869503162 + ], + [ + 225, + "0.4712498465", + 0.47124984649533 + ], + [ + 226, + "0.4743374281", + 0.47433742809777 + ], + [ + 227, + "0.4754464964", + 0.47544649638023 + ], + [ + 228, + "0.475602078", + 0.47560207800734 + ], + [ + 229, + "0.4782178642", + 0.47821786416611 + ], + [ + 230, + "0.479468757", + 0.47946875704427 + ], + [ + 231, + "0.4819296959", + 0.48192969592378 + ], + [ + 232, + "0.4857948518", + 0.48579485178263 + ], + [ + 233, + "0.4860294845", + 0.48602948453558 + ], + [ + 234, + "0.489890096", + 0.48989009600593 + ], + [ + 235, + "0.4920524813", + 0.49205248127321 + ], + [ + 236, + "0.4932398379", + 0.49323983792832 + ], + [ + 237, + "0.4935002562", + 0.4935002562094 + ], + [ + 238, + "0.4964019216", + 0.49640192161146 + ], + [ + 239, + "0.496795092", + 0.49679509200937 + ], + [ + 240, + "0.499331618", + 0.49933161796039 + ], + [ + 241, + "0.5030828875", + 0.50308288750382 + ], + [ + 242, + "0.5033447056", + 0.50334470556273 + ], + [ + 243, + "0.5051939867", + 0.50519398669954 + ], + [ + 244, + "0.5059393726", + 0.50593937258512 + ], + [ + 245, + "0.5070585681", + 0.50705856806927 + ], + [ + 246, + "0.5090773215", + 0.5090773215094 + ], + [ + 247, + "0.5164117192", + 0.51641171915289 + ], + [ + 248, + "0.5166014081", + 0.51660140814101 + ], + [ + 249, + "0.5171571814", + 0.51715718140693 + ], + [ + 250, + "0.5225919325", + 0.52259193245442 + ], + [ + 251, + "0.5261947948", + 0.52619479481419 + ], + [ + 252, + "0.5275636159", + 0.52756361594775 + ], + [ + 253, + "0.5330098092", + 0.5330098092244 + ], + [ + 254, + "0.5344165617", + 0.53441656172946 + ], + [ + 255, + "0.53766182", + 0.53766181996914 + ], + [ + 256, + "0.5385407007", + 0.53854070070131 + ], + [ + 257, + "0.5418435021", + 0.54184350210327 + ], + [ + 258, + "0.5432779065", + 0.54327790650691 + ], + [ + 259, + "0.5446134911", + 0.54461349106608 + ], + [ + 260, + "0.5462143787", + 0.54621437869324 + ], + [ + 261, + "0.5482190571", + 0.54821905705529 + ], + [ + 262, + "0.5503190246", + 0.55031902461793 + ], + [ + 263, + "0.5555936049", + 0.55559360494631 + ], + [ + 264, + "0.5594416352", + 0.55944163518 + ], + [ + 265, + "0.5611671268", + 0.56116712678278 + ], + [ + 266, + "0.5650453091", + 0.56504530905049 + ], + [ + 267, + "0.565516237", + 0.56551623696718 + ], + [ + 268, + "0.5676668196", + 0.56766681958346 + ], + [ + 269, + "0.5678722689", + 0.56787226887786 + ], + [ + 270, + "0.5678896818", + 0.56788968181604 + ], + [ + 271, + "0.5701570546", + 0.57015705461155 + ], + [ + 272, + "0.5702627821", + 0.57026278207556 + ], + [ + 273, + "0.5716964167", + 0.57169641674109 + ], + [ + 274, + "0.5762077442", + 0.57620774422595 + ], + [ + 275, + "0.5822708009", + 0.58227080087283 + ], + [ + 276, + "0.5825441305", + 0.58254413054443 + ], + [ + 277, + "0.5826698898", + 0.5826698898257 + ], + [ + 278, + "0.5848126917", + 0.58481269170754 + ], + [ + 279, + "0.5856470697", + 0.58564706965612 + ], + [ + 280, + "0.5862519981", + 0.58625199812755 + ], + [ + 281, + "0.5863271587", + 0.58632715865332 + ], + [ + 282, + "0.5904919606", + 0.59049196056578 + ], + [ + 283, + "0.5920675856", + 0.59206758560243 + ], + [ + 284, + "0.5937247666", + 0.59372476655697 + ], + [ + 285, + "0.5968111752", + 0.59681117515862 + ], + [ + 286, + "0.6001805093", + 0.60018050931402 + ], + [ + 287, + "0.6050176926", + 0.60501769259805 + ], + [ + 288, + "0.6058371373", + 0.60583713725481 + ], + [ + 289, + "0.6068249189", + 0.60682491893266 + ], + [ + 290, + "0.6099196866", + 0.60991968662008 + ], + [ + 291, + "0.6109455929", + 0.61094559291887 + ], + [ + 292, + "0.6118795865", + 0.61187958652706 + ], + [ + 293, + "0.6124320466", + 0.61243204661292 + ], + [ + 294, + "0.6152676272", + 0.61526762722771 + ], + [ + 295, + "0.6196319371", + 0.61963193706219 + ], + [ + 296, + "0.6207422123", + 0.62074221233871 + ], + [ + 297, + "0.625352654", + 0.62535265396598 + ], + [ + 298, + "0.6261752432", + 0.62617524323341 + ], + [ + 299, + "0.6271740052", + 0.62717400520442 + ], + [ + 300, + "0.6283833318", + 0.62838333175908 + ], + [ + 301, + "0.6293501689", + 0.62935016892354 + ], + [ + 302, + "0.6339364614", + 0.63393646135643 + ], + [ + 303, + "0.6423292927", + 0.64232929267097 + ], + [ + 304, + "0.643764003", + 0.64376400301408 + ], + [ + 305, + "0.6438509126", + 0.6438509126398 + ], + [ + 306, + "0.6461636464", + 0.64616364643264 + ], + [ + 307, + "0.6471605886", + 0.64716058859935 + ], + [ + 308, + "0.6472982353", + 0.64729823528197 + ], + [ + 309, + "0.6481599396", + 0.64815993963189 + ], + [ + 310, + "0.6519840749", + 0.65198407492227 + ], + [ + 311, + "0.6538249178", + 0.65382491781088 + ], + [ + 312, + "0.654417035", + 0.65441703500897 + ], + [ + 313, + "0.6551565023", + 0.65515650233959 + ], + [ + 314, + "0.6580030046", + 0.65800300457421 + ], + [ + 315, + "0.6585909131", + 0.65859091312558 + ], + [ + 316, + "0.6598943354", + 0.65989433539095 + ], + [ + 317, + "0.6628110109", + 0.66281101091895 + ], + [ + 318, + "0.6652203061", + 0.66522030609902 + ], + [ + 319, + "0.6657726218", + 0.66577262182988 + ], + [ + 320, + "0.6672786696", + 0.66727866961959 + ], + [ + 321, + "0.6682578873", + 0.66825788732071 + ], + [ + 322, + "0.6706138443", + 0.67061384425992 + ], + [ + 323, + "0.6728389774", + 0.6728389773857 + ], + [ + 324, + "0.6738104656", + 0.6738104655751 + ], + [ + 325, + "0.6739414286", + 0.67394142862127 + ], + [ + 326, + "0.6789427873", + 0.67894278731147 + ], + [ + 327, + "0.6792435556", + 0.67924355560878 + ], + [ + 328, + "0.6839609233", + 0.68396092331221 + ], + [ + 329, + "0.6843712538", + 0.68437125379423 + ], + [ + 330, + "0.686917588", + 0.68691758796894 + ], + [ + 331, + "0.6886296313", + 0.68862963127374 + ], + [ + 332, + "0.6897600837", + 0.68976008365385 + ], + [ + 333, + "0.6902719348", + 0.6902719348158 + ], + [ + 334, + "0.6965584935", + 0.69655849351387 + ], + [ + 335, + "0.6982833937", + 0.69828339372681 + ], + [ + 336, + "0.6993319917", + 0.69933199170014 + ], + [ + 337, + "0.7005978272", + 0.70059782718336 + ], + [ + 338, + "0.7030775499", + 0.70307754990788 + ], + [ + 339, + "0.7083388677", + 0.70833886773713 + ], + [ + 340, + "0.7095440625", + 0.70954406247918 + ], + [ + 341, + "0.7128569939", + 0.71285699387679 + ], + [ + 342, + "0.7129457475", + 0.71294574752121 + ], + [ + 343, + "0.7148045514", + 0.71480455143135 + ], + [ + 344, + "0.7163206705", + 0.71632067054338 + ], + [ + 345, + "0.7194143854", + 0.71941438537063 + ], + [ + 346, + "0.7206447743", + 0.72064477425098 + ], + [ + 347, + "0.7221357979", + 0.72213579794491 + ], + [ + 348, + "0.7237609353", + 0.72376093534927 + ], + [ + 349, + "0.7239382587", + 0.7239382587019 + ], + [ + 350, + "0.7243118704", + 0.72431187039441 + ], + [ + 351, + "0.726473275", + 0.72647327497902 + ], + [ + 352, + "0.7296714185", + 0.72967141854095 + ], + [ + 353, + "0.7351543967", + 0.73515439673101 + ], + [ + 354, + "0.7355358548", + 0.73553585481622 + ], + [ + 355, + "0.7421012711", + 0.74210127105102 + ], + [ + 356, + "0.7431389316", + 0.74313893157203 + ], + [ + 357, + "0.7439721426", + 0.74397214257343 + ], + [ + 358, + "0.745112982", + 0.74511298199422 + ], + [ + 359, + "0.7457633935", + 0.74576339346625 + ], + [ + 360, + "0.7471672286", + 0.74716722860334 + ], + [ + 361, + "0.7481874147", + 0.74818741471887 + ], + [ + 362, + "0.7482518003", + 0.74825180030812 + ], + [ + 363, + "0.7485077012", + 0.74850770120905 + ], + [ + 364, + "0.7505016126", + 0.75050161255081 + ], + [ + 365, + "0.7530099637", + 0.75300996366562 + ], + [ + 366, + "0.754795242", + 0.75479524198677 + ], + [ + 367, + "0.7557260197", + 0.75572601973811 + ], + [ + 368, + "0.7562984739", + 0.75629847392267 + ], + [ + 369, + "0.7598333898", + 0.75983338978133 + ], + [ + 370, + "0.7600311771", + 0.7600311770849 + ], + [ + 371, + "0.7601212798", + 0.76012127975007 + ], + [ + 372, + "0.7640370269", + 0.76403702691385 + ], + [ + 373, + "0.7656979653", + 0.76569796528932 + ], + [ + 374, + "0.7679536002", + 0.76795360016075 + ], + [ + 375, + "0.7680506472", + 0.7680506472327 + ], + [ + 376, + "0.7683535613", + 0.76835356129722 + ], + [ + 377, + "0.7695589502", + 0.76955895022002 + ], + [ + 378, + "0.7719003185", + 0.77190031845676 + ], + [ + 379, + "0.7721947607", + 0.77219476074548 + ], + [ + 380, + "0.7730772094", + 0.77307720937443 + ], + [ + 381, + "0.7781522706", + 0.77815227060492 + ], + [ + 382, + "0.7822206192", + 0.78222061916357 + ], + [ + 383, + "0.7828206866", + 0.78282068659682 + ], + [ + 384, + "0.7894097486", + 0.78940974864615 + ], + [ + 385, + "0.789710713", + 0.78971071298686 + ], + [ + 386, + "0.7914886022", + 0.79148860219469 + ], + [ + 387, + "0.7948410128", + 0.79484101282192 + ], + [ + 388, + "0.8025113385", + 0.80251133851823 + ], + [ + 389, + "0.807042594", + 0.80704259397789 + ], + [ + 390, + "0.8079456518", + 0.80794565184411 + ], + [ + 391, + "0.8089167535", + 0.80891675353465 + ], + [ + 392, + "0.8097375109", + 0.80973751089057 + ], + [ + 393, + "0.8114332509", + 0.81143325092803 + ], + [ + 394, + "0.8127308357", + 0.81273083566349 + ], + [ + 395, + "0.8143003941", + 0.81430039406488 + ], + [ + 396, + "0.8183699259", + 0.81836992586886 + ], + [ + 397, + "0.8183761732", + 0.8183761731807 + ], + [ + 398, + "0.8191833593", + 0.81918335930406 + ], + [ + 399, + "0.8277966272", + 0.82779662722153 + ], + [ + 400, + "0.8281171298", + 0.82811712977854 + ], + [ + 401, + "0.8300228849", + 0.83002288491931 + ], + [ + 402, + "0.8319003712", + 0.83190037116031 + ], + [ + 403, + "0.8335338011", + 0.83353380106088 + ], + [ + 404, + "0.8382751536", + 0.83827515358025 + ], + [ + 405, + "0.8427027133", + 0.84270271325609 + ], + [ + 406, + "0.8444202141", + 0.84442021411118 + ], + [ + 407, + "0.8452174369", + 0.84521743694563 + ], + [ + 408, + "0.8468697895", + 0.84686978945828 + ], + [ + 409, + "0.8484499486", + 0.84844994863888 + ], + [ + 410, + "0.8530562175", + 0.85305621747535 + ], + [ + 411, + "0.8552265628", + 0.85522656275668 + ], + [ + 412, + "0.8554183398", + 0.85541833977001 + ], + [ + 413, + "0.8557945787", + 0.85579457872351 + ], + [ + 414, + "0.8560648569", + 0.85606485691669 + ], + [ + 415, + "0.8575603132", + 0.85756031324042 + ], + [ + 416, + "0.8575992262", + 0.85759922622591 + ], + [ + 417, + "0.8619446959", + 0.86194469587036 + ], + [ + 418, + "0.862746885", + 0.86274688498244 + ], + [ + 419, + "0.8637428497", + 0.86374284972611 + ], + [ + 420, + "0.8638405962", + 0.86384059622131 + ], + [ + 421, + "0.8667194014", + 0.86671940137945 + ], + [ + 422, + "0.8693330497", + 0.86933304968724 + ], + [ + 423, + "0.8706746715", + 0.870674671545 + ], + [ + 424, + "0.8726787776", + 0.87267877760933 + ], + [ + 425, + "0.8727606055", + 0.87276060547342 + ], + [ + 426, + "0.8727652737", + 0.87276527372783 + ], + [ + 427, + "0.8740768828", + 0.87407688278429 + ], + [ + 428, + "0.8801450408", + 0.88014504075057 + ], + [ + 429, + "0.8845914518", + 0.88459145179232 + ], + [ + 430, + "0.8846158562", + 0.88461585616907 + ], + [ + 431, + "0.8870095545", + 0.88700955448998 + ], + [ + 432, + "0.8874592939", + 0.88745929388676 + ], + [ + 433, + "0.8890389995", + 0.88903899951327 + ], + [ + 434, + "0.8911287784", + 0.89112877840694 + ], + [ + 435, + "0.892701324", + 0.89270132402549 + ], + [ + 436, + "0.893638656", + 0.89363865595946 + ], + [ + 437, + "0.8939921334", + 0.89399213338922 + ], + [ + 438, + "0.9002775321", + 0.90027753212502 + ], + [ + 439, + "0.9019281095", + 0.90192810953684 + ], + [ + 440, + "0.9037487516", + 0.90374875157314 + ], + [ + 441, + "0.9047026345", + 0.90470263450625 + ], + [ + 442, + "0.9050359586", + 0.90503595858115 + ], + [ + 443, + "0.9053011983", + 0.9053011983192 + ], + [ + 444, + "0.9054982611", + 0.90549826105381 + ], + [ + 445, + "0.9057884239", + 0.90578842391529 + ], + [ + 446, + "0.9078596592", + 0.90785965924517 + ], + [ + 447, + "0.9101276025", + 0.91012760247575 + ], + [ + 448, + "0.9110809797", + 0.9110809797007 + ], + [ + 449, + "0.9136646748", + 0.91366467481184 + ], + [ + 450, + "0.9159638099", + 0.9159638098981 + ], + [ + 451, + "0.9166537476", + 0.91665374763154 + ], + [ + 452, + "0.9186017285", + 0.9186017284722 + ], + [ + 453, + "0.919220488", + 0.91922048801519 + ], + [ + 454, + "0.9212328652", + 0.92123286515531 + ], + [ + 455, + "0.9217749945", + 0.92177499454551 + ], + [ + 456, + "0.9218236827", + 0.92182368269275 + ], + [ + 457, + "0.9225795371", + 0.92257953710974 + ], + [ + 458, + "0.923005158", + 0.92300515804579 + ], + [ + 459, + "0.9295114483", + 0.9295114483356 + ], + [ + 460, + "0.9334455854", + 0.93344558539495 + ], + [ + 461, + "0.9337331415", + 0.93373314148454 + ], + [ + 462, + "0.9358259239", + 0.93582592389351 + ], + [ + 463, + "0.9380399426", + 0.93803994261568 + ], + [ + 464, + "0.9392540212", + 0.93925402124377 + ], + [ + 465, + "0.9408260081", + 0.94082600806878 + ], + [ + 466, + "0.9412178755", + 0.94121787554641 + ], + [ + 467, + "0.9421049645", + 0.94210496449009 + ], + [ + 468, + "0.9443434551", + 0.9443434551099 + ], + [ + 469, + "0.947649973", + 0.9476499729546 + ], + [ + 470, + "0.9494116972", + 0.9494116971965 + ], + [ + 471, + "0.9497451694", + 0.94974516935169 + ], + [ + 472, + "0.9517337316", + 0.95173373164224 + ], + [ + 473, + "0.9577067233", + 0.95770672334251 + ], + [ + 474, + "0.9624094944", + 0.96240949442722 + ], + [ + 475, + "0.9642330622", + 0.96423306221339 + ], + [ + 476, + "0.9677599529", + 0.96775995286542 + ], + [ + 477, + "0.9683029465", + 0.96830294652297 + ], + [ + 478, + "0.9700463307", + 0.97004633069506 + ], + [ + 479, + "0.9729755972", + 0.97297559723862 + ], + [ + 480, + "0.9743401203", + 0.9743401203185 + ], + [ + 481, + "0.977525881", + 0.97752588101547 + ], + [ + 482, + "0.9788602395", + 0.97886023948847 + ], + [ + 483, + "0.9829722652", + 0.98297226521324 + ], + [ + 484, + "0.9838584969", + 0.9838584968745 + ], + [ + 485, + "0.986392145", + 0.98639214503876 + ], + [ + 486, + "0.9886501227", + 0.98865012265213 + ], + [ + 487, + "0.9908347088", + 0.99083470878695 + ], + [ + 488, + "0.9918390666", + 0.99183906660966 + ], + [ + 489, + "0.9933680082", + 0.99336800817091 + ], + [ + 490, + "0.9935915098", + 0.99359150975644 + ], + [ + 491, + "0.9990555178", + 0.99905551783696 + ], + [ + 492, + "1613.001", + 1613.001 + ], + [ + 493, + "1613.0011235", + 1613.001123456 + ], + [ + 494, + "42", + 42 + ] +] +, "dynamic_extended_values": +[ + [ + null, + "", + "", + "", + null, + "", + null + ] +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/getdynamiccolvals" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD815F932A6E9840B6ED0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T11:51:41.486000" +,"MEMSIZE" : "93GB" +} +` + +if (_WEBIN_FILENAME1.includes('SASControlTable')) jsDataFileText = _WEBIN_FILEREF1.toString() +if (_WEBIN_FILENAME2.includes('SASControlTable')) jsDataFileText = _WEBIN_FILEREF2.toString() + +if (jsDataFileText.length > 0) { + if (jsDataFileText.includes('MPE_TABLES')) { + _webout = mpe_tables + } else { + _webout = other + } +} else { + console.log('Error reading jsdata input') +} \ No newline at end of file diff --git a/sas/mocks/sasjs/services/editors/getsubmits.js b/sas/mocks/sasjs/services/editors/getsubmits.js new file mode 100644 index 0000000..3a969bf --- /dev/null +++ b/sas/mocks/sasjs/services/editors/getsubmits.js @@ -0,0 +1,29 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:27" +, "fromsas": +[ +{"TABLE_ID":"DC20221006T142649516_059582_7169" ,"BASE_TABLE":"DC988196.MPE_X_TEST" ,"INPUT_VARS":10 ,"INPUT_OBS":1 ,"SUBMITTED_BY_NM":"mihajlo" ,"SUBMITTED_REASON_TXT":"" ,"APPROVE_GROUP":"DEPRECATED" ,"REVIEW_STATUS_ID":"SUBMITTED" ,"REVIEWED_BY_NM":"" ,"REVIEWED_ON_DTTM":null ,"SUBMITTED_ON_DTTM":"2022-10-06 14:26:49" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/mihajlo/services/editors/getsubmits" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221006142715-27976-1665066435798%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B751004C270000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717223" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:28:37.460122" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/editors/loadfile.js b/sas/mocks/sasjs/services/editors/loadfile.js new file mode 100644 index 0000000..264d56b --- /dev/null +++ b/sas/mocks/sasjs/services/editors/loadfile.js @@ -0,0 +1,33 @@ +_webout = `{"SYSDATE" : "29SEP22" +,"SYSTIME" : "11:57" +, "sasparams": +[ + { + "STATUS": "SUCCESS", + "DSID": "DC20220929T115713486_609542_1443" + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/loadfile" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD815FE643C6A840C0278000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T11:57:14.118000" +,"MEMSIZE" : "93GB" +} + +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/editors/stagedata.js b/sas/mocks/sasjs/services/editors/stagedata.js new file mode 100644 index 0000000..54c6f6a --- /dev/null +++ b/sas/mocks/sasjs/services/editors/stagedata.js @@ -0,0 +1,76 @@ +const path = require('path') + +let writeError = 0 +let user_count = 0 +let appLoc = path.join(..._program.split('services')[0].split('/')) +const sessionStoragePath = path.resolve(__dirname, '..', '..', 'drive', 'files', appLoc, 'mock-storage') + +if (!fs.existsSync(sessionStoragePath)){ + fs.mkdirSync(sessionStoragePath); +} + +let jsDataFileText = '' + +if (_WEBIN_FILENAME1.includes('jsdata')) jsDataFileText = _WEBIN_FILEREF1.toString() +if (_WEBIN_FILENAME2.includes('jsdata')) jsDataFileText = _WEBIN_FILEREF2.toString() + +if (jsDataFileText.length > 0) { + if (jsDataFileText.includes('USER_ID')) { + user_count = jsDataFileText.split('\n').length - 1 + + const usersStore = path.resolve(sessionStoragePath, 'users.json') + let isRegistered = 1 + + if (jsDataFileText.includes('notregistered')) { + isRegistered = 0 + } + + const json = { + REGISTERCOUNT: user_count, + ISREGISTERED: isRegistered + } + + try { + fs.writeFileSync(usersStore, JSON.stringify(json)) + } catch (err) { + writeError = 1 + } + } +} else { + console.log('Error reading jsdata input') +} + +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:43" +, "sasparams": +[ +{ +"USER_COUNT": "${user_count}", +"STATUS": "${writeError === 0 ? 'SUCCESS' : 'ERROR WRITING'}", +"DSID": "DC20220926T084322234_729360_2744", +"URL": "http://SAS.demo.sas.com:80/SASStoredProcess?_program=/Projects/app/dc/services/editors/getlog&table=DC20220926T084322234_729360_2744" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/editors/stagedata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD80576A63958140A31C0000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:43:24.624000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/lineage/fetchlineage.js b/sas/mocks/sasjs/services/lineage/fetchlineage.js new file mode 100644 index 0000000..9fe529b --- /dev/null +++ b/sas/mocks/sasjs/services/lineage/fetchlineage.js @@ -0,0 +1,73 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:54" +, "fromsas": +[ +{ +"STRING": "digraph G { concentrate=true; node [style=filled,shape=plain]; labelloc = "t";" +}, +{ +"STRING": "label=< + + + + + + + + + + + + + + + +
REVERSE Lineage for changed_records
Library:
DC996664Generated by:sasdemo
Table:MPE_DATALOADSGenerated on: 26SEP2022:08:54:38
>" + }, + { + "STRING": "x [label="No lineage found" shape=Mdiamond]} + } + ] + , "clickableids": + [ + + ] + , "info": + [ + { + "COLURI": "", + "COLNAME": "changed_records", + "TABURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR00002J", + "TABNAME": "MPE_DATALOADS", + "LIBURI": "OMSOBJ:SASLibrary\A59LNVZG.B500000K", + "LIBREF": "DC996664", + "RC": 0 + } + ] + , "flatdata": + [ + + ] + ,"_DEBUG" : "" + ,"_METAUSER": "sasdemo@SAS" + ,"_METAPERSON": "sasdemo" + ,"_PROGRAM" : "/Projects/app/dc/services/lineage/fetchcollineage" + ,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" + ,"MF_GETUSER" : "sasdemo" + ,"SYSCC" : "0" + ,"SYSENCODING" : "wlatin1" + ,"SYSERRORTEXT" : "" + ,"SYSHOSTNAME" : "SAS" + ,"SYSPROCESSID" : "41DD8058137FCED940C5250000000000" + ,"SYSPROCESSMODE" : "SAS Stored Process Server" + ,"SYSPROCESSNAME" : "" + ,"SYSJOBID" : "27448" + ,"SYSSCPL" : "Linunx" + ,"SYSSITE" : "123" + ,"SYSUSERID" : "sassrv" + ,"SYSVLONG" : "9.04.01M7P080520" + ,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." + ,"END_DTTM" : "2022-09-26T08:54:39.013000" + ,"MEMSIZE" : "46GB" + } +` diff --git a/sas/mocks/sasjs/services/lineage/fetchtablelineage.js b/sas/mocks/sasjs/services/lineage/fetchtablelineage.js new file mode 100644 index 0000000..d7aee12 --- /dev/null +++ b/sas/mocks/sasjs/services/lineage/fetchtablelineage.js @@ -0,0 +1,46 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:54" +, "finalfinal": +[ + +] +, "info": +[ +{ +"TABLEID": "A59LNVZG.BR00002J", +"TABLENAME": "MPE_DATALOADS", +"LIBURI": "OMSOBJ:SASLibrary\A59LNVZG.B500000K", +"LIBREF": "DC996664" +} +] +, "flatdata": +[ + +] +, "idlookup": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/fetchtablelineage" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD805811AA4DD340C4BD8000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:54:31.395000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/lineage/getmetacols.js b/sas/mocks/sasjs/services/lineage/getmetacols.js new file mode 100644 index 0000000..7df6bae --- /dev/null +++ b/sas/mocks/sasjs/services/lineage/getmetacols.js @@ -0,0 +1,83 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:54" +, "metacols": +[ +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L8", +"COLNAME": "changed_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LA", +"COLNAME": "deleted_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L5", +"COLNAME": "dsn", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LB", +"COLNAME": "duration", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L6", +"COLNAME": "etlsource", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L4", +"COLNAME": "libref", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L7", +"COLNAME": "loadtype", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LE", +"COLNAME": "mac_ver", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001L9", +"COLNAME": "new_records", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LD", +"COLNAME": "processed_dttm", +"COLDESC": "" +}, +{ +"COLURI": "OMSOBJ:Column\A59LNVZG.BT0001LC", +"COLNAME": "user_nm", +"COLDESC": "" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/getmetacols" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8058115E041940C4910000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:54:29.833000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/lineage/getmetatables.js b/sas/mocks/sasjs/services/lineage/getmetatables.js new file mode 100644 index 0000000..34198ff --- /dev/null +++ b/sas/mocks/sasjs/services/lineage/getmetatables.js @@ -0,0 +1,42 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:53" +, "metatables": +[ +{ +"LIBNAME": "Sankey", +"SERVERCONTEXT": "SASApp", +"AUTHDOMAIN": "", +"PATH_SCHEMA": "D:\MyDemo\Sankey", +"TABLEURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR000023", +"ID": "A59LNVZG.B600000M", +"LIBDESC": "", +"LIBREF": "sankey", +"ENGINE": "BASE", +"ISDBMSLIBNAME": "0", +"ISPREASSIGNED": "0", +"TABLENAME": "WEBTEST4" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/lineage/getmetatables" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8058084D916840C4690000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:53:53.567000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/metanav/metadetails.js b/sas/mocks/sasjs/services/metanav/metadetails.js new file mode 100644 index 0000000..f8f8e9e --- /dev/null +++ b/sas/mocks/sasjs/services/metanav/metadetails.js @@ -0,0 +1,101 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "attributes": +[ +{ +"TYPE": "Attr", +"NAME": "ChangeState", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "Desc", +"VALUE": "Input Stream." +}, +{ +"TYPE": "Attr", +"NAME": "Id", +"VALUE": "A59LNVZG.BW000001" +}, +{ +"TYPE": "Attr", +"NAME": "IsHidden", +"VALUE": "0" +}, +{ +"TYPE": "Attr", +"NAME": "LockedBy", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "MetadataCreated", +"VALUE": "19Aug2020:11:12:46" +}, +{ +"TYPE": "Attr", +"NAME": "MetadataUpdated", +"VALUE": "19Aug2020:11:12:46" +}, +{ +"TYPE": "Attr", +"NAME": "Name", +"VALUE": "instream" +}, +{ +"TYPE": "Attr", +"NAME": "Protocol", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "PublicType", +"VALUE": "" +}, +{ +"TYPE": "Attr", +"NAME": "UsageVersion", +"VALUE": "0" +}, +{ +"TYPE": "Prop", +"NAME": "MultiPass", +"VALUE": "1" +} +] +, "associations": +[ +{ +"ASSOC": "Properties", +"ASSOCURI": "OMSOBJ:Property\A59LNVZG.AC0003EG", +"NAME": "MultiPass" +}, +{ +"ASSOC": "Reports", +"ASSOCURI": "OMSOBJ:Report\A59LNVZG.BV000001", +"NAME": "instream" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metadetails" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D94B645A40C1608000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:45.706000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/metanav/metaobjects.js b/sas/mocks/sasjs/services/metanav/metaobjects.js new file mode 100644 index 0000000..712e31f --- /dev/null +++ b/sas/mocks/sasjs/services/metanav/metaobjects.js @@ -0,0 +1,32 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "objects": +[ +{ +"ID": "A59LNVZG.BW000001", +"NAME": "instream" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metaobjects" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D89978D540C1368000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:42.814000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/metanav/metarepos.js b/sas/mocks/sasjs/services/metanav/metarepos.js new file mode 100644 index 0000000..d72765c --- /dev/null +++ b/sas/mocks/sasjs/services/metanav/metarepos.js @@ -0,0 +1,36 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "outrepos": +[ +{ +"ID": "A0000001.A573PBI4", +"NAME": "BILineage" +}, +{ +"ID": "A0000001.A59LNVZG", +"NAME": "Foundation" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metarepos" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "4" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D3E04189409F380000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "21468" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:23.895000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/metanav/metatypes.js b/sas/mocks/sasjs/services/metanav/metatypes.js new file mode 100644 index 0000000..b3393f0 --- /dev/null +++ b/sas/mocks/sasjs/services/metanav/metatypes.js @@ -0,0 +1,383 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:50" +, "types": +[ +{ +"ID": "AccessControlEntry", +"DESC": "Access control entry", +"HASSUBTYPES": "0" +}, +{ +"ID": "AccessControlTemplate", +"DESC": "Access control template", +"HASSUBTYPES": "0" +}, +{ +"ID": "Action", +"DESC": "Action", +"HASSUBTYPES": "0" +}, +{ +"ID": "AnalyticContext", +"DESC": "Analytic context", +"HASSUBTYPES": "0" +}, +{ +"ID": "ApplicationAction", +"DESC": "Application action", +"HASSUBTYPES": "0" +}, +{ +"ID": "AssociationProperty", +"DESC": "Association property", +"HASSUBTYPES": "0" +}, +{ +"ID": "AttributeProperty", +"DESC": "Attribute property", +"HASSUBTYPES": "0" +}, +{ +"ID": "AuthenticationDomain", +"DESC": "Authentication domain", +"HASSUBTYPES": "0" +}, +{ +"ID": "ClassifierMap", +"DESC": "Classifier map", +"HASSUBTYPES": "1" +}, +{ +"ID": "Column", +"DESC": "Column", +"HASSUBTYPES": "1" +}, +{ +"ID": "Condition", +"DESC": "Condition", +"HASSUBTYPES": "0" +}, +{ +"ID": "ConditionActionSet", +"DESC": "Condition action set", +"HASSUBTYPES": "0" +}, +{ +"ID": "ConfiguredComponent", +"DESC": "Configured component", +"HASSUBTYPES": "1" +}, +{ +"ID": "CustomAssociation", +"DESC": "Custom association", +"HASSUBTYPES": "0" +}, +{ +"ID": "DatabaseCatalog", +"DESC": "Database catalog", +"HASSUBTYPES": "0" +}, +{ +"ID": "DatabaseSchema", +"DESC": "Database schema", +"HASSUBTYPES": "0" +}, +{ +"ID": "DeployedComponent", +"DESC": "Deployed component", +"HASSUBTYPES": "1" +}, +{ +"ID": "Directory", +"DESC": "Directory", +"HASSUBTYPES": "1" +}, +{ +"ID": "Document", +"DESC": "Document", +"HASSUBTYPES": "0" +}, +{ +"ID": "Extension", +"DESC": "Extension", +"HASSUBTYPES": "0" +}, +{ +"ID": "ExternalIdentity", +"DESC": "External identity", +"HASSUBTYPES": "0" +}, +{ +"ID": "FavoritesContainer", +"DESC": "Favorites container", +"HASSUBTYPES": "0" +}, +{ +"ID": "File", +"DESC": "File", +"HASSUBTYPES": "1" +}, +{ +"ID": "Group", +"DESC": "Group", +"HASSUBTYPES": "1" +}, +{ +"ID": "ITChannel", +"DESC": "IT channel", +"HASSUBTYPES": "0" +}, +{ +"ID": "IdentityGroup", +"DESC": "Identity group", +"HASSUBTYPES": "0" +}, +{ +"ID": "Index", +"DESC": "Index", +"HASSUBTYPES": "0" +}, +{ +"ID": "InternalLogin", +"DESC": "Internal login", +"HASSUBTYPES": "0" +}, +{ +"ID": "Job", +"DESC": "Job", +"HASSUBTYPES": "0" +}, +{ +"ID": "Keyword", +"DESC": "Keyword", +"HASSUBTYPES": "0" +}, +{ +"ID": "LogicalServer", +"DESC": "Logical server", +"HASSUBTYPES": "0" +}, +{ +"ID": "Login", +"DESC": "Login", +"HASSUBTYPES": "0" +}, +{ +"ID": "Machine", +"DESC": "Machine", +"HASSUBTYPES": "0" +}, +{ +"ID": "NamedService", +"DESC": "Named service", +"HASSUBTYPES": "0" +}, +{ +"ID": "OLAPSchema", +"DESC": "OLAP schema", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSColumnLayoutComponent", +"DESC": "PS column layout component", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSPortalPage", +"DESC": "PS portal page", +"HASSUBTYPES": "0" +}, +{ +"ID": "PSPortlet", +"DESC": "PS portlet", +"HASSUBTYPES": "0" +}, +{ +"ID": "Permission", +"DESC": "Permission", +"HASSUBTYPES": "0" +}, +{ +"ID": "Person", +"DESC": "People", +"HASSUBTYPES": "0" +}, +{ +"ID": "PhysicalTable", +"DESC": "Physical table", +"HASSUBTYPES": "1" +}, +{ +"ID": "Prompt", +"DESC": "Prompt", +"HASSUBTYPES": "0" +}, +{ +"ID": "PromptGroup", +"DESC": "Prompt group", +"HASSUBTYPES": "0" +}, +{ +"ID": "Property", +"DESC": "Property", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertyGroup", +"DESC": "Property group", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertySet", +"DESC": "Property set", +"HASSUBTYPES": "0" +}, +{ +"ID": "PropertyType", +"DESC": "Property type", +"HASSUBTYPES": "0" +}, +{ +"ID": "Prototype", +"DESC": "Prototype", +"HASSUBTYPES": "0" +}, +{ +"ID": "Report", +"DESC": "Report", +"HASSUBTYPES": "0" +}, +{ +"ID": "ResponsibleParty", +"DESC": "Responsible party", +"HASSUBTYPES": "0" +}, +{ +"ID": "SASClientConnection", +"DESC": "SAS client connection", +"HASSUBTYPES": "0" +}, +{ +"ID": "SASLibrary", +"DESC": "SAS library", +"HASSUBTYPES": "1" +}, +{ +"ID": "SASPassword", +"DESC": "SAS password", +"HASSUBTYPES": "0" +}, +{ +"ID": "Search", +"DESC": "Search", +"HASSUBTYPES": "0" +}, +{ +"ID": "SecurityRuleScheme", +"DESC": "Security rule scheme", +"HASSUBTYPES": "0" +}, +{ +"ID": "SecurityTypeContainmentRule", +"DESC": "Security type containment rule", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServerComponent", +"DESC": "Server component", +"HASSUBTYPES": "1" +}, +{ +"ID": "ServerContext", +"DESC": "Server context", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServiceComponent", +"DESC": "Service component", +"HASSUBTYPES": "0" +}, +{ +"ID": "ServiceType", +"DESC": "Service type", +"HASSUBTYPES": "0" +}, +{ +"ID": "SoftwareComponent", +"DESC": "Software component", +"HASSUBTYPES": "1" +}, +{ +"ID": "Stream", +"DESC": "Stream", +"HASSUBTYPES": "0" +}, +{ +"ID": "TCPIPConnection", +"DESC": "TCPIP connection", +"HASSUBTYPES": "0" +}, +{ +"ID": "TextStore", +"DESC": "Text store", +"HASSUBTYPES": "0" +}, +{ +"ID": "Timestamp", +"DESC": "Timestamp", +"HASSUBTYPES": "0" +}, +{ +"ID": "Transformation", +"DESC": "Transformation", +"HASSUBTYPES": "1" +}, +{ +"ID": "TransformationActivity", +"DESC": "Transformation activity", +"HASSUBTYPES": "0" +}, +{ +"ID": "TransformationStep", +"DESC": "Transformation step", +"HASSUBTYPES": "1" +}, +{ +"ID": "Tree", +"DESC": "Metadata Trees", +"HASSUBTYPES": "0" +}, +{ +"ID": "TypeDefinition", +"DESC": "Type definition", +"HASSUBTYPES": "0" +}, +{ +"ID": "UniqueKey", +"DESC": "Unique key", +"HASSUBTYPES": "0" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/metanav/metatypes" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057D3E020C540C10F8000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:50:23.928000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/getchangeinfo.js b/sas/mocks/sasjs/services/public/getchangeinfo.js new file mode 100644 index 0000000..4070ba3 --- /dev/null +++ b/sas/mocks/sasjs/services/public/getchangeinfo.js @@ -0,0 +1,29 @@ +_webout = `{"SYSDATE" : "07OCT22" +,"SYSTIME" : "12:25" +, "jsparams": +[ +{"TABLE_ID":"DC20221007T122326121_612316_7259" ,"SUBMIT_STATUS_CD":"SUBMITTED" ,"BASE_LIB":"DC988196" ,"BASE_DS":"MPE_X_TEST" ,"SUBMITTED_BY_NM":"mihajlo" ,"SUBMITTED_ON":1980764606.22 ,"SUBMITTED_REASON_TXT":"" ,"INPUT_OBS":15 ,"INPUT_VARS":10 ,"NUM_OF_APPROVALS_REQUIRED":1 ,"NUM_OF_APPROVALS_REMAINING":1 ,"REVIEWED_BY_NM":"" ,"REVIEWED_ON":null ,"TABLE_NM":"DC988196.MPE_X_TEST" ,"BASE_TABLE":"DC988196.MPE_X_TEST" ,"REVIEWED_ON_DTTM":"." ,"SUBMITTED_ON_DTTM":"07OCT2022:12:23:26" ,"LIB_ENGINE":"WPD" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/mihajlo/services/public/getchangeinfo" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221007122549-44480-1665145549621%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD8404936CF0DC0000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "726819" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-07T12:25:57.433259" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/getcolvals.js b/sas/mocks/sasjs/services/public/getcolvals.js new file mode 100644 index 0000000..065f513 --- /dev/null +++ b/sas/mocks/sasjs/services/public/getcolvals.js @@ -0,0 +1,449 @@ +_webout = `{ + "SYSDATE": "26SEP22", + "SYSTIME": "08:49", + "vals": [ + { + "FORMATTED": "0", + "UNFORMATTED": 0 + }, + { + "FORMATTED": "1", + "UNFORMATTED": 1 + }, + { + "FORMATTED": "3", + "UNFORMATTED": 3 + }, + { + "FORMATTED": "4", + "UNFORMATTED": 4 + }, + { + "FORMATTED": "5", + "UNFORMATTED": 5 + }, + { + "FORMATTED": "6", + "UNFORMATTED": 6 + }, + { + "FORMATTED": "7", + "UNFORMATTED": 7 + }, + { + "FORMATTED": "8", + "UNFORMATTED": 8 + }, + { + "FORMATTED": "9", + "UNFORMATTED": 9 + }, + { + "FORMATTED": "10", + "UNFORMATTED": 10 + }, + { + "FORMATTED": "11", + "UNFORMATTED": 11 + }, + { + "FORMATTED": "12", + "UNFORMATTED": 12 + }, + { + "FORMATTED": "13", + "UNFORMATTED": 13 + }, + { + "FORMATTED": "14", + "UNFORMATTED": 14 + }, + { + "FORMATTED": "15", + "UNFORMATTED": 15 + }, + { + "FORMATTED": "16", + "UNFORMATTED": 16 + }, + { + "FORMATTED": "17", + "UNFORMATTED": 17 + }, + { + "FORMATTED": "18", + "UNFORMATTED": 18 + }, + { + "FORMATTED": "19", + "UNFORMATTED": 19 + }, + { + "FORMATTED": "20", + "UNFORMATTED": 20 + }, + { + "FORMATTED": "21", + "UNFORMATTED": 21 + }, + { + "FORMATTED": "22", + "UNFORMATTED": 22 + }, + { + "FORMATTED": "23", + "UNFORMATTED": 23 + }, + { + "FORMATTED": "24", + "UNFORMATTED": 24 + }, + { + "FORMATTED": "25", + "UNFORMATTED": 25 + }, + { + "FORMATTED": "26", + "UNFORMATTED": 26 + }, + { + "FORMATTED": "27", + "UNFORMATTED": 27 + }, + { + "FORMATTED": "28", + "UNFORMATTED": 28 + }, + { + "FORMATTED": "29", + "UNFORMATTED": 29 + }, + { + "FORMATTED": "30", + "UNFORMATTED": 30 + }, + { + "FORMATTED": "31", + "UNFORMATTED": 31 + }, + { + "FORMATTED": "32", + "UNFORMATTED": 32 + }, + { + "FORMATTED": "33", + "UNFORMATTED": 33 + }, + { + "FORMATTED": "34", + "UNFORMATTED": 34 + }, + { + "FORMATTED": "35", + "UNFORMATTED": 35 + }, + { + "FORMATTED": "36", + "UNFORMATTED": 36 + }, + { + "FORMATTED": "37", + "UNFORMATTED": 37 + }, + { + "FORMATTED": "38", + "UNFORMATTED": 38 + }, + { + "FORMATTED": "39", + "UNFORMATTED": 39 + }, + { + "FORMATTED": "40", + "UNFORMATTED": 40 + }, + { + "FORMATTED": "41", + "UNFORMATTED": 41 + }, + { + "FORMATTED": "42", + "UNFORMATTED": 42 + }, + { + "FORMATTED": "43", + "UNFORMATTED": 43 + }, + { + "FORMATTED": "44", + "UNFORMATTED": 44 + }, + { + "FORMATTED": "45", + "UNFORMATTED": 45 + }, + { + "FORMATTED": "46", + "UNFORMATTED": 46 + }, + { + "FORMATTED": "47", + "UNFORMATTED": 47 + }, + { + "FORMATTED": "48", + "UNFORMATTED": 48 + }, + { + "FORMATTED": "49", + "UNFORMATTED": 49 + }, + { + "FORMATTED": "50", + "UNFORMATTED": 50 + }, + { + "FORMATTED": "51", + "UNFORMATTED": 51 + }, + { + "FORMATTED": "52", + "UNFORMATTED": 52 + }, + { + "FORMATTED": "53", + "UNFORMATTED": 53 + }, + { + "FORMATTED": "54", + "UNFORMATTED": 54 + }, + { + "FORMATTED": "55", + "UNFORMATTED": 55 + }, + { + "FORMATTED": "56", + "UNFORMATTED": 56 + }, + { + "FORMATTED": "57", + "UNFORMATTED": 57 + }, + { + "FORMATTED": "58", + "UNFORMATTED": 58 + }, + { + "FORMATTED": "59", + "UNFORMATTED": 59 + }, + { + "FORMATTED": "60", + "UNFORMATTED": 60 + }, + { + "FORMATTED": "61", + "UNFORMATTED": 61 + }, + { + "FORMATTED": "62", + "UNFORMATTED": 62 + }, + { + "FORMATTED": "63", + "UNFORMATTED": 63 + }, + { + "FORMATTED": "64", + "UNFORMATTED": 64 + }, + { + "FORMATTED": "65", + "UNFORMATTED": 65 + }, + { + "FORMATTED": "66", + "UNFORMATTED": 66 + }, + { + "FORMATTED": "67", + "UNFORMATTED": 67 + }, + { + "FORMATTED": "68", + "UNFORMATTED": 68 + }, + { + "FORMATTED": "69", + "UNFORMATTED": 69 + }, + { + "FORMATTED": "70", + "UNFORMATTED": 70 + }, + { + "FORMATTED": "71", + "UNFORMATTED": 71 + }, + { + "FORMATTED": "72", + "UNFORMATTED": 72 + }, + { + "FORMATTED": "73", + "UNFORMATTED": 73 + }, + { + "FORMATTED": "74", + "UNFORMATTED": 74 + }, + { + "FORMATTED": "75", + "UNFORMATTED": 75 + }, + { + "FORMATTED": "76", + "UNFORMATTED": 76 + }, + { + "FORMATTED": "77", + "UNFORMATTED": 77 + }, + { + "FORMATTED": "78", + "UNFORMATTED": 78 + }, + { + "FORMATTED": "79", + "UNFORMATTED": 79 + }, + { + "FORMATTED": "80", + "UNFORMATTED": 80 + }, + { + "FORMATTED": "81", + "UNFORMATTED": 81 + }, + { + "FORMATTED": "82", + "UNFORMATTED": 82 + }, + { + "FORMATTED": "83", + "UNFORMATTED": 83 + }, + { + "FORMATTED": "84", + "UNFORMATTED": 84 + }, + { + "FORMATTED": "85", + "UNFORMATTED": 85 + }, + { + "FORMATTED": "86", + "UNFORMATTED": 86 + }, + { + "FORMATTED": "87", + "UNFORMATTED": 87 + }, + { + "FORMATTED": "88", + "UNFORMATTED": 88 + }, + { + "FORMATTED": "89", + "UNFORMATTED": 89 + }, + { + "FORMATTED": "90", + "UNFORMATTED": 90 + }, + { + "FORMATTED": "91", + "UNFORMATTED": 91 + }, + { + "FORMATTED": "92", + "UNFORMATTED": 92 + }, + { + "FORMATTED": "93", + "UNFORMATTED": 93 + }, + { + "FORMATTED": "94", + "UNFORMATTED": 94 + }, + { + "FORMATTED": "95", + "UNFORMATTED": 95 + }, + { + "FORMATTED": "96", + "UNFORMATTED": 96 + }, + { + "FORMATTED": "97", + "UNFORMATTED": 97 + }, + { + "FORMATTED": "98", + "UNFORMATTED": 98 + }, + { + "FORMATTED": "99", + "UNFORMATTED": 99 + }, + { + "FORMATTED": "100", + "UNFORMATTED": 100 + } + ], + "$vals": { + "vars": { + "FORMATTED": { + "format": "$12.", + "label": "FORMATTED", + "length": "12", + "type": "char" + }, + "UNFORMATTED": { + "format": "best.", + "label": "UNFORMATTED", + "length": "8", + "type": "num" + } + } + }, + "meta": [ + { + "COLUMN": "SOME_BESTNUM", + "SASFORMAT": "BEST." + } + ], + "_DEBUG": "", + "_METAUSER": "sasdemo@SAS", + "_METAPERSON": "sasdemo", + "_PROGRAM": "/Projects/app/dc/services/public/getcolvals", + "AUTOEXEC": "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas", + "MF_GETUSER": "sasdemo", + "SYSCC": "0", + "SYSENCODING": "wlatin1", + "SYSERRORTEXT": "", + "SYSHOSTNAME": "SAS", + "SYSPROCESSID": "41DD8057C8923D7140BEF70000000000", + "SYSPROCESSMODE": "SAS Stored Process Server", + "SYSPROCESSNAME": "", + "SYSJOBID": "27448", + "SYSSCPL": "Linunx", + "SYSSITE": "123", + "SYSUSERID": "sassrv", + "SYSVLONG": "9.04.01M7P080520", + "SYSWARNINGTEXT": "ENCODING option ignored for files opened with RECFM=N.", + "END_DTTM": "2022-09-26T08:49:39.137000", + "MEMSIZE": "46GB" +}` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/getddl.js b/sas/mocks/sasjs/services/public/getddl.js new file mode 100644 index 0000000..ad2176e --- /dev/null +++ b/sas/mocks/sasjs/services/public/getddl.js @@ -0,0 +1,27 @@ +let mimeType = `application/octet-stream` +let filename = `dc-download` + +if (libref) filename = `${libref}.ddl` + +fs.writeFile(_SASJS_WEBOUT_HEADERS, `Content-type: ${mimeType} \n Content-Disposition: attachment;filename=\"${filename}\"`, function (err) { + if (err) throw err; +}) + +_webout = `/* DDL generated by sassrv on 29SEP2022:11:59:44 */ +CREATE SCHEMA DC996664; +/* Postgres Flavour DDL for DC996664.MPE_X_TEST */ +CREATE TABLE DC996664.MPE_X_TEST ( + "primary_key_field" DOUBLE PRECISION NOT NULL + ,"some_char" VARCHAR(32767) + ,"some_dropdown" VARCHAR(128) + ,"some_num" DOUBLE PRECISION + ,"some_date" DOUBLE PRECISION + ,"some_datetime" TIMESTAMP + ,"some_time" DOUBLE PRECISION + ,"some_shortnum" DOUBLE PRECISION + ,"some_bestnum" DOUBLE PRECISION +); +CREATE UNIQUE INDEX "primary_key_field" ON DC996664.MPE_X_TEST( + "primary_key_field" +); +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/getgroups.js b/sas/mocks/sasjs/services/public/getgroups.js new file mode 100644 index 0000000..745fc2b --- /dev/null +++ b/sas/mocks/sasjs/services/public/getgroups.js @@ -0,0 +1,30 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:43" +, "groups": +[ +{"GROUPURI":"1" ,"GROUPNAME":"AllUsers" ,"GROUPDESC":"Group contains all users" } +,{"GROUPURI":"2" ,"GROUPNAME":"Public" ,"GROUPDESC":"A special group that can be used to bypass authentication for pa" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/mihajlo/services/public/getgroups" +,"AUTOEXEC" : "%2Fhome%2Fmihajlo%2Fsasjs_root%2Fsessions%2F20221006144330-61991-1665067410430%2Fautoexec.sas" +,"MF_GETUSER" : "mihajlo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B844F8941D0000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717841" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "mihajlo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:46:29.671882" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/getrawdata.js b/sas/mocks/sasjs/services/public/getrawdata.js new file mode 100644 index 0000000..bafbb4f --- /dev/null +++ b/sas/mocks/sasjs/services/public/getrawdata.js @@ -0,0 +1,530 @@ +let mimeType = `application/octet-stream` +let filename = `dc-download` + +if (table) filename = `${table}` + +switch(type) { + case 'CSV': { + mimeType = 'text/csv' + filename += '.csv' + break + } + case 'EXCEL': { + mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + filename += '.xlsx' + break + } + case 'MARKDOWN': { + mimeType = 'application/octet-stream' + filename += '.md' + break + } + default: + mimeType = 'application/octet-stream' + filename += '.sas' + break +} + +fs.writeFile(_SASJS_WEBOUT_HEADERS, `Content-type: ${mimeType} \n Content-Disposition: attachment;filename=\"${filename}\"`, function (err) { + if (err) throw err; +}) + +_webout=` +2,even more dummy data,Option/* */ 3,42,42,42,142,3,44 +3,"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:",Option 2,1613.001,423,423,44,3,44 +4,if you can fill the unforgiving minute,Option 1,1613.001123456,4231,423123123,412,3,44 +1010,10 bottles of beer on the wall,Option 1,0.36778671125312,429,29804,35,1,72 +1011,11 bottles of beer on the wall,Option 1,0.86933304968724,385,5119,1,6,54 +1012,12 bottles of beer on the wall,Option 1,0.54327790650691,644,10655,35,54,62 +1013,13 bottles of beer on the wall,Option 1,0.50519398669954,781,24475,41,38,4 +1014,14 bottles of beer on the wall,Option 1,0.0130502507151339,12,13693,14,92,57 +1015,15 bottles of beer on the wall,Option 1,0.58227080087283,923,43518,54,92,80 +1016,16 bottles of beer on the wall,Option 1,0.13827249786736,241,10081,1,28,91 +1017,17 bottles of beer on the wall,Option 1,0.89270132402549,622,25438,97,91,72 +1018,18 bottles of beer on the wall,Option 1,0.18527885674744,432,1368,32,93,79 +1019,19 bottles of beer on the wall,Option 1,0.07375510180078,389,11673,21,22,90 +1020,20 bottles of beer on the wall,Option 1,0.71285699387679,404,6623,100,65,34 +1021,21 bottles of beer on the wall,Option 1,0.67061384425992,433,17575,13,44,97 +1022,22 bottles of beer on the wall,Option 1,0.14232157922457,933,26701,70,66,98 +1023,23 bottles of beer on the wall,Option 1,0.12598480662609,974,34354,76,44,98 +1024,24 bottles of beer on the wall,Option 1,0.38994686370247,705,24831,33,30,90 +1025,25 bottles of beer on the wall,Option 1,0.0310356193366626,60,10687,27,73,59 +1026,26 bottles of beer on the wall,Option 1,0.90578842391529,277,40648,41,82,46 +1027,27 bottles of beer on the wall,Option 1,0.59206758560243,926,12941,22,46,73 +1028,28 bottles of beer on the wall,Option 1,0.65800300457421,281,47610,40,35,40 +1029,29 bottles of beer on the wall,Option 1,0.80704259397789,360,43034,19,80,12 +1030,30 bottles of beer on the wall,Option 1,0.88014504075057,500,36665,25,70,19 +1031,31 bottles of beer on the wall,Option 1,0.41501947046025,757,41229,64,94,48 +1032,32 bottles of beer on the wall,Option 1,0.9743401203185,739,27875,67,43,3 +1033,33 bottles of beer on the wall,Option 1,0.20355956917794,250,42739,42,29,56 +1034,34 bottles of beer on the wall,Option 1,0.67924355560878,111,26224,74,68,9 +1035,35 bottles of beer on the wall,Option 1,0.9494116971965,18,36938,76,91,10 +1036,36 bottles of beer on the wall,Option 1,0.54461349106608,299,14127,84,72,36 +1037,37 bottles of beer on the wall,Option 1,0.45877589399869,325,48877,95,97,32 +1038,38 bottles of beer on the wall,Option 1,0.15371942387601,491,22453,29,60,98 +1039,39 bottles of beer on the wall,Option 1,0.4935002562094,156,25182,45,95,55 +1040,40 bottles of beer on the wall,Option 1,0.12472885899465,433,10986,83,35,79 +1041,41 bottles of beer on the wall,Option 1,0.27944220010165,917,19766,51,86,66 +1042,42 bottles of beer on the wall,Option 1,0.70307754990788,223,43884,38,86,97 +1043,43 bottles of beer on the wall,Option 1,0.0701107536769,394,13449,3,25,8 +1044,44 bottles of beer on the wall,Option 1,0.64232929267097,745,3427,9,97,37 +1045,45 bottles of beer on the wall,Option 1,0.72064477425098,652,44732,7,58,58 +1046,46 bottles of beer on the wall,Option 1,0.0431997366450726,255,18777,95,17,8 +1047,47 bottles of beer on the wall,Option 1,0.3704071367953,182,9877,6,45,26 +1048,48 bottles of beer on the wall,Option 1,0.65441703500897,489,4987,98,41,13 +1049,49 bottles of beer on the wall,Option 1,0.13002125645523,371,19649,81,37,66 +1050,50 bottles of beer on the wall,Option 1,0.0058409725343068,204,264,40,15,32 +1051,51 bottles of beer on the wall,Option 1,0.7239382587019,160,11709,4,42,82 +1052,52 bottles of beer on the wall,Option 1,0.83190037116031,225,27515,36,69,81 +1053,53 bottles of beer on the wall,Option 1,0.50308288750382,538,41129,53,39,75 +1054,54 bottles of beer on the wall,Option 1,0.71480455143135,238,36609,39,6,4 +1055,55 bottles of beer on the wall,Option 1,0.85579457872351,292,8252,8,93,36 +1056,56 bottles of beer on the wall,Option 1,0.97004633069506,922,40721,51,25,35 +1057,57 bottles of beer on the wall,Option 1,0.93803994261568,542,47713,52,57,66 +1058,58 bottles of beer on the wall,Option 1,0.84844994863888,153,4491,0,80,58 +1059,59 bottles of beer on the wall,Option 1,0.14157076279705,574,23596,58,11,32 +1060,60 bottles of beer on the wall,Option 1,0.28267451295753,816,1537,56,79,58 +1061,61 bottles of beer on the wall,Option 1,0.37272800801914,734,18463,60,86,92 +1062,62 bottles of beer on the wall,Option 1,0.95173373164224,606,9605,5,30,93 +1063,63 bottles of beer on the wall,Option 1,0.09674986828898,778,27041,29,90,82 +1064,64 bottles of beer on the wall,Option 1,0.054067135348016,511,47623,8,88,45 +1065,65 bottles of beer on the wall,Option 1,0.64616364643264,757,10601,19,41,38 +1066,66 bottles of beer on the wall,Option 1,0.9053011983192,275,12949,64,68,39 +1067,67 bottles of beer on the wall,Option 1,0.97752588101547,930,21200,28,28,34 +1068,68 bottles of beer on the wall,Option 1,0.21655531610201,133,6242,72,63,23 +1069,69 bottles of beer on the wall,Option 1,0.22483527950236,494,273,9,26,93 +1070,70 bottles of beer on the wall,Option 1,0.13862833666551,868,12720,96,83,89 +1071,71 bottles of beer on the wall,Option 1,0.93373314148454,501,49614,47,27,56 +1072,72 bottles of beer on the wall,Option 1,0.035223550645273,522,32960,76,7,27 +1073,73 bottles of beer on the wall,Option 1,0.32066626954854,72,38291,68,3,50 +1074,74 bottles of beer on the wall,Option 1,0.46108617049692,608,34541,68,54,68 +1075,75 bottles of beer on the wall,Option 1,0.45277456215246,746,24567,45,96,63 +1076,76 bottles of beer on the wall,Option 1,0.35812440577807,136,3400,73,72,24 +1077,77 bottles of beer on the wall,Option 1,0.89399213338922,386,33391,75,88,69 +1078,78 bottles of beer on the wall,Option 1,0.24457270663444,356,11474,97,88,32 +1079,79 bottles of beer on the wall,Option 1,0.96830294652297,591,17143,69,51,60 +1080,80 bottles of beer on the wall,Option 1,0.13035413675492,789,8090,21,79,87 +1081,81 bottles of beer on the wall,Option 1,0.76569796528932,580,24590,91,58,30 +1082,82 bottles of beer on the wall,Option 1,0.18556296740917,350,23241,33,1,72 +1083,83 bottles of beer on the wall,Option 1,0.47821786416611,471,29123,70,0,1 +1084,84 bottles of beer on the wall,Option 1,0.16702721322282,902,49400,27,53,6 +1085,85 bottles of beer on the wall,Option 1,0.60682491893266,141,39911,8,17,68 +1086,86 bottles of beer on the wall,Option 1,0.09360499172173,931,26169,46,73,37 +1087,87 bottles of beer on the wall,Option 1,0.65382491781088,114,7614,59,95,32 +1088,88 bottles of beer on the wall,Option 1,0.88461585616907,688,20127,61,87,30 +1089,89 bottles of beer on the wall,Option 1,0.15782083159211,427,32522,23,60,53 +1090,90 bottles of beer on the wall,Option 1,0.42257537526198,78,44044,60,57,64 +1091,91 bottles of beer on the wall,Option 1,0.65989433539095,625,10993,60,41,28 +1092,92 bottles of beer on the wall,Option 1,0.62935016892354,656,1273,71,64,7 +1093,93 bottles of beer on the wall,Option 1,0.43788449859148,540,37239,27,30,78 +1094,94 bottles of beer on the wall,Option 1,0.9838584968745,875,10746,59,48,98 +1095,95 bottles of beer on the wall,Option 1,0.08925237697048,532,17660,10,75,33 +1096,96 bottles of beer on the wall,Option 1,0.45782051536153,19,38160,41,14,17 +1097,97 bottles of beer on the wall,Option 1,0.58632715865332,840,40451,88,66,84 +1098,98 bottles of beer on the wall,Option 1,0.29942320580567,185,29741,88,99,85 +1099,99 bottles of beer on the wall,Option 1,0.09813780528406,35,40211,43,23,65 +10100,100 bottles of beer on the wall,Option 1,0.98297226521324,31,20706,76,28,44 +10101,101 bottles of beer on the wall,Option 1,0.45407949129775,945,34023,70,42,44 +10102,102 bottles of beer on the wall,Option 1,0.84521743694563,275,11327,23,10,14 +10103,103 bottles of beer on the wall,Option 1,0.59049196056578,211,47398,10,68,53 +10104,104 bottles of beer on the wall,Option 1,0.70833886773713,205,20990,89,84,33 +10105,105 bottles of beer on the wall,Option 1,0.31835502587182,622,8914,51,69,97 +10106,106 bottles of beer on the wall,Option 1,0.97297559723862,585,16241,10,91,29 +10107,107 bottles of beer on the wall,Option 1,0.5090773215094,266,19231,43,92,73 +10108,108 bottles of beer on the wall,Option 1,0.60501769259805,442,8188,35,88,21 +10109,109 bottles of beer on the wall,Option 1,0.36126818152203,732,39786,39,67,1 +10110,110 bottles of beer on the wall,Option 1,0.92257953710974,181,27439,53,45,96 +10111,111 bottles of beer on the wall,Option 1,0.57620774422595,1,10732,13,85,94 +10112,112 bottles of beer on the wall,Option 1,0.72213579794491,368,24381,11,81,4 +10113,113 bottles of beer on the wall,Option 1,0.68396092331221,876,7786,88,88,35 +10114,114 bottles of beer on the wall,Option 1,0.06275422035844,242,39301,65,37,30 +10115,115 bottles of beer on the wall,Option 1,0.14623936319082,763,31112,32,26,92 +10116,116 bottles of beer on the wall,Option 1,0.88700955448998,461,29947,67,93,100 +10117,117 bottles of beer on the wall,Option 1,0.58625199812755,772,33489,84,17,65 +10118,118 bottles of beer on the wall,Option 1,0.11950912844366,88,18030,83,74,91 +10119,119 bottles of beer on the wall,Option 1,0.25274958287028,73,40520,3,35,48 +10120,120 bottles of beer on the wall,Option 1,0.20096259713217,322,37079,25,72,46 +10121,121 bottles of beer on the wall,Option 1,0.51715718140693,696,35623,70,2,29 +10122,122 bottles of beer on the wall,Option 1,0.62535265396598,349,18863,77,55,42 +10123,123 bottles of beer on the wall,Option 1,0.0397578571176892,616,2222,57,21,21 +10124,124 bottles of beer on the wall,Option 1,0.15299692198308,781,31566,49,77,36 +10125,125 bottles of beer on the wall,Option 1,0.55944163518,848,18125,98,89,81 +10126,126 bottles of beer on the wall,Option 1,0.0545679247260876,102,12528,93,78,97 +10127,127 bottles of beer on the wall,Option 1,0.37134892836741,650,8167,52,54,88 +10128,128 bottles of beer on the wall,Option 1,0.64729823528197,93,1934,51,6,19 +10129,129 bottles of beer on the wall,Option 1,0.83002288491931,4,49511,33,81,10 +10130,130 bottles of beer on the wall,Option 1,0.26566079038458,556,19220,44,64,96 +10131,131 bottles of beer on the wall,Option 1,0.3515388878768,465,9268,65,33,47 +10132,132 bottles of beer on the wall,Option 1,0.58481269170754,369,3487,9,27,23 +10133,133 bottles of beer on the wall,Option 1,0.35976610256348,821,16327,12,6,79 +10134,134 bottles of beer on the wall,Option 1,0.66825788732071,692,43769,43,39,24 +10135,135 bottles of beer on the wall,Option 1,0.6738104655751,506,29856,85,25,81 +10136,136 bottles of beer on the wall,Option 1,0.61094559291887,719,22506,35,54,62 +10137,137 bottles of beer on the wall,Option 1,0.90374875157314,72,5697,78,47,95 +10138,138 bottles of beer on the wall,Option 1,0.80794565184411,642,42356,27,12,85 +10139,139 bottles of beer on the wall,Option 1,0.38307386654572,96,27737,91,35,33 +10140,140 bottles of beer on the wall,Option 1,0.56504530905049,50,436,92,79,7 +10141,141 bottles of beer on the wall,Option 1,0.88745929388676,790,2062,19,22,14 +10142,142 bottles of beer on the wall,Option 1,0.40486131394508,401,39461,31,67,8 +10143,143 bottles of beer on the wall,Option 1,0.46010804244322,141,38118,13,5,56 +10144,144 bottles of beer on the wall,Option 1,0.80973751089057,391,29194,40,99,51 +10145,145 bottles of beer on the wall,Option 1,0.99359150975644,439,46193,72,64,36 +10146,146 bottles of beer on the wall,Option 1,0.0452116918960641,118,22701,24,60,96 +10147,147 bottles of beer on the wall,Option 1,0.82811712977854,260,12725,17,62,66 +10148,148 bottles of beer on the wall,Option 1,0.10816729632586,938,26840,50,84,81 +10149,149 bottles of beer on the wall,Option 1,0.38052640686767,683,3221,86,85,46 +10150,150 bottles of beer on the wall,Option 1,0.75572601973811,982,19125,32,95,95 +10151,151 bottles of beer on the wall,Option 1,0.14433648304284,978,10712,67,60,46 +10152,152 bottles of beer on the wall,Option 1,0.0478734295106835,195,20803,16,11,31 +10153,153 bottles of beer on the wall,Option 1,0.99183906660966,846,17321,72,56,75 +10154,154 bottles of beer on the wall,Option 1,0.9159638098981,247,6539,24,83,15 +10155,155 bottles of beer on the wall,Option 1,0.36824048886459,754,32386,14,80,100 +10156,156 bottles of beer on the wall,Option 1,0.26111941517382,730,2622,30,83,10 +10157,157 bottles of beer on the wall,Option 1,0.88903899951327,332,11975,96,11,35 +10158,158 bottles of beer on the wall,Option 1,0.13194132788662,604,26809,16,51,85 +10159,159 bottles of beer on the wall,Option 1,0.62617524323341,174,9160,21,48,61 +10160,160 bottles of beer on the wall,Option 1,0.57026278207556,696,43887,57,83,1 +10161,161 bottles of beer on the wall,Option 1,0.85756031324042,271,49234,27,2,27 +10162,162 bottles of beer on the wall,Option 1,0.1826881850989,47,10724,78,2,97 +10163,163 bottles of beer on the wall,Option 1,0.23421087266607,482,10522,88,20,48 +10164,164 bottles of beer on the wall,Option 1,0.35695342596478,161,38915,54,32,10 +10165,165 bottles of beer on the wall,Option 1,0.91366467481184,378,38006,70,63,6 +10166,166 bottles of beer on the wall,Option 1,0.99905551783696,818,43080,35,10,36 +10167,167 bottles of beer on the wall,Option 1,0.52259193245442,62,47314,77,73,92 +10168,168 bottles of beer on the wall,Option 1,0.37612532376131,455,10513,79,37,41 +10169,169 bottles of beer on the wall,Option 1,0.32677267646732,900,43022,33,56,4 +10170,170 bottles of beer on the wall,Option 1,0.78282068659682,584,35703,11,96,19 +10171,171 bottles of beer on the wall,Option 1,0.86384059622131,383,16268,72,97,52 +10172,172 bottles of beer on the wall,Option 1,0.78971071298686,274,40013,11,12,77 +10173,173 bottles of beer on the wall,Option 1,0.80251133851823,141,24834,3,24,52 +10174,174 bottles of beer on the wall,Option 1,0.75300996366562,391,25598,69,10,50 +10175,175 bottles of beer on the wall,Option 1,0.71632067054338,957,17312,75,80,50 +10176,176 bottles of beer on the wall,Option 1,0.79148860219469,146,43778,51,4,35 +10177,177 bottles of beer on the wall,Option 1,0.09253642060446,108,5706,3,54,99 +10178,178 bottles of beer on the wall,Option 1,0.11753227706883,629,20998,30,9,4 +10179,179 bottles of beer on the wall,Option 1,0.7680506472327,480,16698,64,29,40 +10180,180 bottles of beer on the wall,Option 1,0.72647327497902,3,692,98,26,63 +10181,181 bottles of beer on the wall,Option 1,0.61187958652706,804,15515,35,74,9 +10182,182 bottles of beer on the wall,Option 1,0.37813100422645,947,17165,45,40,70 +10183,183 bottles of beer on the wall,Option 1,0.77219476074548,333,18572,47,75,13 +10184,184 bottles of beer on the wall,Option 1,0.08129415338919,544,41948,73,69,42 +10185,185 bottles of beer on the wall,Option 1,0.31256898320865,788,40399,79,46,81 +10186,186 bottles of beer on the wall,Option 1,0.17449143863026,792,48899,82,75,11 +10187,187 bottles of beer on the wall,Option 1,0.96775995286542,287,49710,56,53,48 +10188,188 bottles of beer on the wall,Option 1,0.89112877840694,64,19729,89,53,7 +10189,189 bottles of beer on the wall,Option 1,0.06672863013424,76,28616,10,62,87 +10190,190 bottles of beer on the wall,Option 1,0.94082600806878,147,42133,34,45,53 +10191,191 bottles of beer on the wall,Option 1,0.31033688146171,836,30910,16,47,17 +10192,192 bottles of beer on the wall,Option 1,0.18763532265445,337,40521,3,51,83 +10193,193 bottles of beer on the wall,Option 1,0.96240949442722,291,15471,49,39,59 +10194,194 bottles of beer on the wall,Option 1,0.8183761731807,419,40108,43,39,67 +10195,195 bottles of beer on the wall,Option 1,0.24989856139286,670,15344,92,43,42 +10196,196 bottles of beer on the wall,Option 1,0.30300405309675,389,23570,23,54,49 +10197,197 bottles of beer on the wall,Option 1,0.72431187039441,253,33148,8,44,61 +10198,198 bottles of beer on the wall,Option 1,0.28154017463398,990,5590,35,70,58 +10199,199 bottles of beer on the wall,Option 1,0.91922048801519,128,34408,69,54,0 +10200,200 bottles of beer on the wall,Option 1,0.50593937258512,107,18850,78,83,97 +10201,201 bottles of beer on the wall,Option 1,0.14390773612256,946,17067,64,26,8 +10202,202 bottles of beer on the wall,Option 1,0.22146828529493,610,24559,46,49,59 +10203,203 bottles of beer on the wall,Option 1,0.25821849576114,663,34629,1,6,71 +10204,204 bottles of beer on the wall,Option 1,0.07666777590134,466,27138,26,99,30 +10205,205 bottles of beer on the wall,Option 1,0.99336800817091,694,16168,65,11,46 +10206,206 bottles of beer on the wall,Option 1,0.87276060547342,576,25229,80,91,90 +10207,207 bottles of beer on the wall,Option 1,0.78940974864615,6,47096,26,63,27 +10208,208 bottles of beer on the wall,Option 1,0.34292900066027,14,31458,36,22,82 +10209,209 bottles of beer on the wall,Option 1,0.85305621747535,993,2251,86,89,14 +10210,210 bottles of beer on the wall,Option 1,0.15697739560016,198,45644,46,91,4 +10211,211 bottles of beer on the wall,Option 1,0.28367675109006,906,13627,42,90,59 +10212,212 bottles of beer on the wall,Option 1,0.31982582077375,378,7369,78,38,8 +10213,213 bottles of beer on the wall,Option 1,0.23638620564545,648,44244,93,90,55 +10214,214 bottles of beer on the wall,Option 1,0.74210127105102,24,20396,94,44,25 +10215,215 bottles of beer on the wall,Option 1,0.86374284972611,74,48658,100,86,85 +10216,216 bottles of beer on the wall,Option 1,0.75050161255081,59,46121,89,20,42 +10217,217 bottles of beer on the wall,Option 1,0.66522030609902,994,42468,11,56,86 +10218,218 bottles of beer on the wall,Option 1,0.31411136375465,655,27263,65,25,96 +10219,219 bottles of beer on the wall,Option 1,0.47560207800734,499,48744,43,95,39 +10220,220 bottles of beer on the wall,Option 1,0.29217880745054,499,11765,39,38,34 +10221,221 bottles of beer on the wall,Option 1,0.34208696444616,782,48914,46,28,67 +10222,222 bottles of beer on the wall,Option 1,0.3618709479281,17,35101,36,32,96 +10223,223 bottles of beer on the wall,Option 1,0.57169641674109,255,39862,46,25,32 +10224,224 bottles of beer on the wall,Option 1,0.81918335930406,52,678,48,93,9 +10225,225 bottles of beer on the wall,Option 1,0.0242283884548714,85,42068,83,16,80 +10226,226 bottles of beer on the wall,Option 1,0.41845829338694,302,24667,57,21,94 +10227,227 bottles of beer on the wall,Option 1,0.85522656275668,25,4962,39,16,92 +10228,228 bottles of beer on the wall,Option 1,0.61243204661292,211,29623,51,3,47 +10229,229 bottles of beer on the wall,Option 1,0.0565994717444291,895,43578,3,89,43 +10230,230 bottles of beer on the wall,Option 1,0.23499503882368,490,4308,62,37,48 +10231,231 bottles of beer on the wall,Option 1,0.90549826105381,400,6623,89,33,46 +10232,232 bottles of beer on the wall,Option 1,0.48989009600593,744,25625,56,51,95 +10233,233 bottles of beer on the wall,Option 1,0.45866525287677,218,44935,69,85,54 +10234,234 bottles of beer on the wall,Option 1,0.85541833977001,639,24786,23,38,89 +10235,235 bottles of beer on the wall,Option 1,0.85759922622591,668,22410,58,67,99 +10236,236 bottles of beer on the wall,Option 1,0.84442021411118,101,1665,82,65,33 +10237,237 bottles of beer on the wall,Option 1,0.47433742809777,378,24480,58,22,29 +10238,238 bottles of beer on the wall,Option 1,0.32656197777323,516,43954,3,94,67 +10239,239 bottles of beer on the wall,Option 1,0.92182368269275,712,4843,71,46,48 +10240,240 bottles of beer on the wall,Option 1,0.12125048326386,352,9277,22,2,32 +10241,241 bottles of beer on the wall,Option 1,0.94974516935169,523,24517,34,3,67 +10242,242 bottles of beer on the wall,Option 1,0.25598201866074,802,27462,64,76,70 +10243,243 bottles of beer on the wall,Option 1,0.75983338978133,179,29989,61,29,71 +10244,244 bottles of beer on the wall,Option 1,0.70059782718336,205,18615,38,53,10 +10245,245 bottles of beer on the wall,Option 1,0.22119579474497,248,32376,67,44,33 +10246,246 bottles of beer on the wall,Option 1,0.20074144573916,83,8942,9,37,88 +10247,247 bottles of beer on the wall,Option 1,0.28749029351747,570,10557,57,30,33 +10248,248 bottles of beer on the wall,Option 1,0.56116712678278,176,7262,96,49,90 +10249,249 bottles of beer on the wall,Option 1,0.34936685829859,424,16012,95,81,25 +10250,250 bottles of beer on the wall,Option 1,0.2531839875752,400,13060,93,38,32 +10251,251 bottles of beer on the wall,Option 1,0.74716722860334,104,36045,95,12,91 +10252,252 bottles of beer on the wall,Option 1,0.2776136003796,621,32945,24,43,56 +10253,253 bottles of beer on the wall,Option 1,0.10966447093974,824,1582,82,47,71 +10254,254 bottles of beer on the wall,Option 1,0.20580046819793,515,48029,52,84,12 +10255,255 bottles of beer on the wall,Option 1,0.25379118707673,528,20603,24,50,93 +10256,256 bottles of beer on the wall,Option 1,0.91665374763154,340,33728,92,65,18 +10257,257 bottles of beer on the wall,Option 1,0.76795360016075,986,2750,46,80,97 +10258,258 bottles of beer on the wall,Option 1,0.54184350210327,343,36848,56,32,90 +10259,259 bottles of beer on the wall,Option 1,0.32811180051793,455,28710,88,44,88 +10260,260 bottles of beer on the wall,Option 1,0.21353805913288,312,29544,13,52,11 +10261,261 bottles of beer on the wall,Option 1,0.9443434551099,512,8527,20,62,6 +10262,262 bottles of beer on the wall,Option 1,0.85606485691669,897,5860,30,57,8 +10263,263 bottles of beer on the wall,Option 1,0.99083470878695,807,13039,86,67,60 +10264,264 bottles of beer on the wall,Option 1,0.81836992586886,962,4598,39,30,45 +10265,265 bottles of beer on the wall,Option 1,0.42497428805798,61,6536,89,38,44 +10266,266 bottles of beer on the wall,Option 1,0.0560880252421312,251,6156,80,39,13 +10267,267 bottles of beer on the wall,Option 1,0.62838333175908,976,41904,69,80,5 +10268,268 bottles of beer on the wall,Option 1,0.86274688498244,801,38326,57,37,67 +10269,269 bottles of beer on the wall,Option 1,0.90785965924517,430,4760,53,46,12 +10270,270 bottles of beer on the wall,Option 1,0.96423306221339,881,13359,26,76,85 +10271,271 bottles of beer on the wall,Option 1,0.4007478316318,386,9372,92,46,37 +10272,272 bottles of beer on the wall,Option 1,0.1693538530587,770,30938,83,37,54 +10273,273 bottles of beer on the wall,Option 1,0.31195034380627,685,24382,100,69,19 +10274,274 bottles of beer on the wall,Option 1,0.76835356129722,187,47688,55,89,64 +10275,275 bottles of beer on the wall,Option 1,0.55031902461793,584,3730,14,0,81 +10276,276 bottles of beer on the wall,Option 1,0.95770672334251,363,3953,24,30,88 +10277,277 bottles of beer on the wall,Option 1,0.6728389773857,420,8182,39,53,83 +10278,278 bottles of beer on the wall,Option 1,0.89363865595946,704,46747,31,74,16 +10279,279 bottles of beer on the wall,Option 1,0.40898148175747,924,47734,97,7,24 +10280,280 bottles of beer on the wall,Option 1,0.66577262182988,64,20201,32,44,54 +10281,281 bottles of beer on the wall,Option 1,0.51660140814101,280,12454,79,10,71 +10282,282 bottles of beer on the wall,Option 1,0.53854070070131,104,43120,90,44,24 +10283,283 bottles of beer on the wall,Option 1,0.23819732723673,558,15573,20,6,23 +10284,284 bottles of beer on the wall,Option 1,0.47946875704427,243,36842,53,32,21 +10285,285 bottles of beer on the wall,Option 1,0.77190031845676,651,28782,56,39,60 +10286,286 bottles of beer on the wall,Option 1,0.32027244256822,383,42285,47,100,10 +10287,287 bottles of beer on the wall,Option 1,0.74313893157203,31,16412,3,74,65 +10288,288 bottles of beer on the wall,Option 1,0.76955895022002,602,446,96,3,76 +10289,289 bottles of beer on the wall,Option 1,0.34185171050105,952,13939,62,5,36 +10290,290 bottles of beer on the wall,Option 1,0.56766681958346,767,45844,22,63,94 +10291,291 bottles of beer on the wall,Option 1,0.08876820145583,35,44015,18,67,75 +10292,292 bottles of beer on the wall,Option 1,0.60991968662008,537,25458,62,97,31 +10293,293 bottles of beer on the wall,Option 1,0.49679509200937,425,2032,71,57,28 +10294,294 bottles of beer on the wall,Option 1,0.75629847392267,128,18192,74,4,18 +10295,295 bottles of beer on the wall,Option 1,0.68437125379423,823,49500,26,26,27 +10296,296 bottles of beer on the wall,Option 1,0.93925402124377,544,41748,5,35,80 +10297,297 bottles of beer on the wall,Option 1,0.32460635729348,55,9662,69,4,43 +10298,298 bottles of beer on the wall,Option 1,0.69933199170014,168,2056,58,37,59 +10299,299 bottles of beer on the wall,Option 1,0.47544649638023,840,30210,53,53,68 +10300,300 bottles of beer on the wall,Option 1,0.0061305039590832,271,12274,76,89,63 +10301,301 bottles of beer on the wall,Option 1,0.48602948453558,62,326,17,10,61 +10302,302 bottles of beer on the wall,Option 1,0.66281101091895,85,25075,34,20,0 +10303,303 bottles of beer on the wall,Option 1,0.91012760247575,766,2167,24,10,59 +10304,304 bottles of beer on the wall,Option 1,0.25942224276225,900,10747,64,56,26 +10305,305 bottles of beer on the wall,Option 1,0.1962652361003,289,96,17,33,93 +10306,306 bottles of beer on the wall,Option 1,0.43586940478341,29,13418,16,53,29 +10307,307 bottles of beer on the wall,Option 1,0.59681117515862,118,27786,86,65,36 +10308,308 bottles of beer on the wall,Option 1,0.74818741471887,206,4604,24,24,25 +10309,309 bottles of beer on the wall,Option 1,0.08160290591493,312,21554,64,63,72 +10310,310 bottles of beer on the wall,Option 1,0.93582592389351,242,10979,27,81,61 +10311,311 bottles of beer on the wall,Option 1,0.80891675353465,209,5348,87,54,90 +10312,312 bottles of beer on the wall,Option 1,0.60018050931402,439,38290,61,90,76 +10313,313 bottles of beer on the wall,Option 1,0.24727975961159,881,20239,40,51,51 +10314,314 bottles of beer on the wall,Option 1,0.38803865312972,653,24155,89,31,85 +10315,315 bottles of beer on the wall,Option 1,0.87407688278429,313,37785,77,92,16 +10316,316 bottles of beer on the wall,Option 1,0.56551623696718,547,21387,24,23,97 +10317,317 bottles of beer on the wall,Option 1,0.76403702691385,58,9872,38,64,21 +10318,318 bottles of beer on the wall,Option 1,0.90192810953684,602,11179,10,90,11 +10319,319 bottles of beer on the wall,Option 1,0.19516248544452,214,4047,63,28,92 +10320,320 bottles of beer on the wall,Option 1,0.94210496449009,873,18179,99,68,3 +10321,321 bottles of beer on the wall,Option 1,0.38397014298661,768,6961,34,4,75 +10322,322 bottles of beer on the wall,Option 1,0.48192969592378,241,40181,42,3,47 +10323,323 bottles of beer on the wall,Option 1,0.9110809797007,103,40820,33,3,68 +10324,324 bottles of beer on the wall,Option 1,0.87276527372783,826,32198,4,39,97 +10325,325 bottles of beer on the wall,Option 1,0.79484101282192,372,7572,44,96,94 +10326,326 bottles of beer on the wall,Option 1,0.14490672719893,292,7727,52,59,76 +10327,327 bottles of beer on the wall,Option 1,0.39760627709217,61,39145,43,84,64 +10328,328 bottles of beer on the wall,Option 1,0.59372476655697,986,45366,56,32,42 +10329,329 bottles of beer on the wall,Option 1,0.84270271325609,730,48646,83,33,93 +10330,330 bottles of beer on the wall,Option 1,0.97886023948847,579,12493,3,47,51 +10331,331 bottles of beer on the wall,Option 1,0.06287532628647,13,33428,15,95,25 +10332,332 bottles of beer on the wall,Option 1,0.0144214248351853,986,14183,40,42,55 +10333,333 bottles of beer on the wall,Option 1,0.46513955689274,279,24669,74,6,96 +10334,334 bottles of beer on the wall,Option 1,0.65515650233959,940,7983,58,90,50 +10335,335 bottles of beer on the wall,Option 1,0.74576339346625,40,32933,42,66,64 +10336,336 bottles of beer on the wall,Option 1,0.25071058620266,249,35506,55,38,21 +10337,337 bottles of beer on the wall,Option 1,0.83827515358025,901,40729,55,96,40 +10338,338 bottles of beer on the wall,Option 1,0.37835469487046,787,39991,85,24,78 +10339,339 bottles of beer on the wall,Option 1,0.47124984649533,325,9386,13,46,83 +10340,340 bottles of beer on the wall,Option 1,0.81143325092803,276,21424,20,35,49 +10341,341 bottles of beer on the wall,Option 1,0.18923743590211,278,33884,35,66,56 +10342,342 bottles of beer on the wall,Option 1,0.31555957641245,652,3104,43,41,96 +10343,343 bottles of beer on the wall,Option 1,0.63393646135643,787,7242,50,79,80 +10344,344 bottles of beer on the wall,Option 1,0.42426411873859,900,7126,3,47,55 +10345,345 bottles of beer on the wall,Option 1,0.46336023717343,202,15278,8,27,22 +10346,346 bottles of beer on the wall,Option 1,0.74511298199422,941,9263,62,12,8 +10347,347 bottles of beer on the wall,Option 1,0.0509991273521442,175,17983,84,69,63 +10348,348 bottles of beer on the wall,Option 1,0.73515439673101,104,44565,39,89,43 +10349,349 bottles of beer on the wall,Option 1,0.54621437869324,419,43815,82,14,44 +10350,350 bottles of beer on the wall,Option 1,0.67394142862127,565,15879,83,78,24 +10351,351 bottles of beer on the wall,Option 1,0.14206720569267,724,48097,47,78,59 +10352,352 bottles of beer on the wall,Option 1,0.77307720937443,542,8575,12,59,56 +10353,353 bottles of beer on the wall,Option 1,0.30727765350941,969,2407,60,24,16 +10354,354 bottles of beer on the wall,Option 1,0.0010556476195602,556,26857,10,10,14 +10355,355 bottles of beer on the wall,Option 1,0.18200497244578,184,34597,36,44,73 +10356,356 bottles of beer on the wall,Option 1,0.13798288029524,955,24751,69,56,11 +10357,357 bottles of beer on the wall,Option 1,0.81430039406488,268,18672,62,91,35 +10358,358 bottles of beer on the wall,Option 1,0.43832174522724,693,32350,29,44,16 +10359,359 bottles of beer on the wall,Option 1,0.029728665030435,459,5440,18,15,73 +10360,360 bottles of beer on the wall,Option 1,0.0315013211367192,722,16356,36,94,34 +10361,361 bottles of beer on the wall,Option 1,0.5826698898257,689,39648,77,16,31 +10362,362 bottles of beer on the wall,Option 1,0.6902719348158,482,34034,34,28,24 +10363,363 bottles of beer on the wall,Option 1,0.31280953544788,122,8845,82,13,11 +10364,364 bottles of beer on the wall,Option 1,0.40638104565738,59,17576,51,83,33 +10365,365 bottles of beer on the wall,Option 1,0.0494814422211989,427,16863,86,58,83 +10366,366 bottles of beer on the wall,Option 1,0.11973315715777,211,5076,50,91,7 +10367,367 bottles of beer on the wall,Option 1,0.64716058859935,267,31744,84,38,0 +10368,368 bottles of beer on the wall,Option 1,0.26110028115152,618,5356,52,14,45 +10369,369 bottles of beer on the wall,Option 1,0.28273768829309,318,1330,93,89,55 +10370,370 bottles of beer on the wall,Option 1,0.2922141674404,632,46096,5,81,23 +10371,371 bottles of beer on the wall,Option 1,0.41764038541244,906,49463,57,1,62 +10372,372 bottles of beer on the wall,Option 1,0.46991869503162,514,18143,97,74,74 +10373,373 bottles of beer on the wall,Option 1,0.37822098302572,895,32283,70,48,12 +10374,374 bottles of beer on the wall,Option 1,0.29593264744427,113,4983,7,27,41 +10375,375 bottles of beer on the wall,Option 1,0.53441656172946,220,39018,54,89,65 +10376,376 bottles of beer on the wall,Option 1,0.0352940624744138,109,20139,36,100,10 +10377,377 bottles of beer on the wall,Option 1,0.20479777232035,608,6078,64,74,17 +10378,378 bottles of beer on the wall,Option 1,0.50705856806927,135,49049,10,54,37 +10379,379 bottles of beer on the wall,Option 1,0.66727866961959,412,46966,29,91,57 +10380,380 bottles of beer on the wall,Option 1,0.92177499454551,580,26551,28,51,48 +10381,381 bottles of beer on the wall,Option 1,0.38939245948074,78,4703,90,2,83 +10382,382 bottles of beer on the wall,Option 1,0.61963193706219,174,43627,79,32,20 +10383,383 bottles of beer on the wall,Option 1,0.28356101283969,199,30131,69,41,95 +10384,384 bottles of beer on the wall,Option 1,0.31165435086547,77,14822,68,53,73 +10385,385 bottles of beer on the wall,Option 1,0.31375717619143,905,21353,48,53,98 +10386,386 bottles of beer on the wall,Option 1,0.49205248127321,25,43511,50,63,86 +10387,387 bottles of beer on the wall,Option 1,0.0871032425608,546,41998,56,8,54 +10388,388 bottles of beer on the wall,Option 1,0.58564706965612,707,32080,48,13,71 +10389,389 bottles of beer on the wall,Option 1,0.11565735010227,962,23374,70,87,46 +10390,390 bottles of beer on the wall,Option 1,0.67894278731147,712,3675,22,39,59 +10391,391 bottles of beer on the wall,Option 1,0.55559360494631,485,35672,4,91,33 +10392,392 bottles of beer on the wall,Option 1,0.19414928331698,181,5016,91,63,77 +10393,393 bottles of beer on the wall,Option 1,0.35980724001294,784,45193,40,85,1 +10394,394 bottles of beer on the wall,Option 1,0.56788968181604,558,29278,34,1,48 +10395,395 bottles of beer on the wall,Option 1,0.443418078331,67,40850,25,96,88 +10396,396 bottles of beer on the wall,Option 1,0.37440109084099,80,28866,54,92,41 +10397,397 bottles of beer on the wall,Option 1,0.98865012265213,251,47673,91,46,37 +10398,398 bottles of beer on the wall,Option 1,0.92300515804579,559,10806,54,44,62 +10399,399 bottles of beer on the wall,Option 1,0.64376400301408,567,44649,57,61,58 +10400,400 bottles of beer on the wall,Option 1,0.71294574752121,715,6570,31,26,3 +10401,401 bottles of beer on the wall,Option 1,0.0256445333481042,635,9939,72,83,63 +10402,402 bottles of beer on the wall,Option 1,0.29210200267476,328,35640,57,94,97 +10403,403 bottles of beer on the wall,Option 1,0.6438509126398,426,17030,58,99,72 +10404,404 bottles of beer on the wall,Option 1,0.72967141854095,719,23973,72,4,19 +10405,405 bottles of beer on the wall,Option 1,0.64815993963189,589,16332,78,22,8 +10406,406 bottles of beer on the wall,Option 1,0.68862963127374,792,19827,98,95,84 +10407,407 bottles of beer on the wall,Option 1,0.57015705461155,315,8751,26,88,99 +10408,408 bottles of beer on the wall,Option 1,0.37385381263394,936,22120,63,22,62 +10409,409 bottles of beer on the wall,Option 1,0.42852969580727,575,4535,43,73,1 +10410,410 bottles of beer on the wall,Option 1,0.09136778679274,974,6568,15,99,89 +10411,411 bottles of beer on the wall,Option 1,0.35649286925629,150,8757,11,21,13 +10412,412 bottles of beer on the wall,Option 1,0.78222061916357,343,22099,52,78,86 +10413,413 bottles of beer on the wall,Option 1,0.14624287939921,416,38106,39,98,94 +10414,414 bottles of beer on the wall,Option 1,0.90027753212502,496,20157,67,58,67 +10415,415 bottles of beer on the wall,Option 1,0.33255961040619,752,49026,33,28,14 +10416,416 bottles of beer on the wall,Option 1,0.77815227060492,640,35944,70,52,55 +10417,417 bottles of beer on the wall,Option 1,0.0933360564957,758,15354,32,19,55 +10418,418 bottles of beer on the wall,Option 1,0.0289132245950928,180,5242,85,50,98 +10419,419 bottles of beer on the wall,Option 1,0.84686978945828,458,1258,80,25,73 +10420,420 bottles of beer on the wall,Option 1,0.338352090371,509,42861,22,43,54 +10421,421 bottles of beer on the wall,Option 1,0.86671940137945,577,8605,34,90,100 +10422,422 bottles of beer on the wall,Option 1,0.62074221233871,60,22854,9,99,38 +10423,423 bottles of beer on the wall,Option 1,0.33002009630669,355,5698,48,91,58 +10424,424 bottles of beer on the wall,Option 1,0.74825180030812,425,17426,75,51,47 +10425,425 bottles of beer on the wall,Option 1,0.15292107088161,413,42526,51,59,44 +10426,426 bottles of beer on the wall,Option 1,0.94121787554641,513,31473,8,93,82 +10427,427 bottles of beer on the wall,Option 1,0.30919636381286,556,31101,27,16,50 +10428,428 bottles of beer on the wall,Option 1,0.4236965931131,398,29008,36,85,56 +10429,429 bottles of beer on the wall,Option 1,0.75479524198677,249,47750,51,15,7 +10430,430 bottles of beer on the wall,Option 1,0.49933161796039,918,42396,88,38,92 +10431,431 bottles of beer on the wall,Option 1,0.93344558539495,45,43421,17,90,69 +10432,432 bottles of beer on the wall,Option 1,0.9476499729546,937,16157,85,76,3 +10433,433 bottles of beer on the wall,Option 1,0.74850770120905,311,40579,39,22,72 +10434,434 bottles of beer on the wall,Option 1,0.73553585481622,817,15748,47,77,22 +10435,435 bottles of beer on the wall,Option 1,0.3191975039985,383,22167,85,79,73 +10436,436 bottles of beer on the wall,Option 1,0.30836578146944,849,12164,85,65,1 +10437,437 bottles of beer on the wall,Option 1,0.24748317443182,80,12922,65,62,16 +10438,438 bottles of beer on the wall,Option 1,0.81273083566349,246,18919,42,57,78 +10439,439 bottles of beer on the wall,Option 1,0.23397017793449,549,49719,50,15,17 +10440,440 bottles of beer on the wall,Option 1,0.52619479481419,742,35354,61,87,16 +10441,441 bottles of beer on the wall,Option 1,0.52756361594775,100,42930,55,64,29 +10442,442 bottles of beer on the wall,Option 1,0.65198407492227,782,42167,14,41,44 +10443,443 bottles of beer on the wall,Option 1,0.0511230966314315,280,15886,87,31,52 +10444,444 bottles of beer on the wall,Option 1,0.68976008365385,105,46257,66,37,6 +10445,445 bottles of beer on the wall,Option 1,0.4041808938627,759,44435,63,71,69 +10446,446 bottles of beer on the wall,Option 1,0.12014651304117,860,30110,54,61,64 +10447,447 bottles of beer on the wall,Option 1,0.9186017284722,305,4246,75,84,61 +10448,448 bottles of beer on the wall,Option 1,0.026245259226414,413,8816,67,79,12 +10449,449 bottles of beer on the wall,Option 1,0.56787226887786,67,4407,31,5,8 +10450,450 bottles of beer on the wall,Option 1,0.28620145064136,903,36836,25,77,29 +10451,451 bottles of beer on the wall,Option 1,0.76012127975007,253,13863,59,65,36 +10452,452 bottles of beer on the wall,Option 1,0.7600311770849,106,46566,99,57,79 +10453,453 bottles of beer on the wall,Option 1,0.40851825634414,894,38655,14,34,57 +10454,454 bottles of beer on the wall,Option 1,0.60583713725481,215,48030,77,9,82 +10455,455 bottles of beer on the wall,Option 1,0.36183023097078,75,5740,13,76,95 +10456,456 bottles of beer on the wall,Option 1,0.9295114483356,699,10234,52,74,92 +10457,457 bottles of beer on the wall,Option 1,0.10465663303837,107,23068,27,59,18 +10458,458 bottles of beer on the wall,Option 1,0.26722961909474,742,12522,12,50,38 +10459,459 bottles of beer on the wall,Option 1,0.69828339372681,761,33853,42,31,59 +10460,460 bottles of beer on the wall,Option 1,0.18323942002991,818,9662,0,84,61 +10461,461 bottles of beer on the wall,Option 1,0.74397214257343,852,42889,46,56,59 +10462,462 bottles of beer on the wall,Option 1,0.51641171915289,37,36520,76,3,21 +10463,463 bottles of beer on the wall,Option 1,0.5330098092244,366,5617,11,29,54 +10464,464 bottles of beer on the wall,Option 1,0.48579485178263,972,20268,70,91,72 +10465,465 bottles of beer on the wall,Option 1,0.88459145179232,169,49656,62,31,95 +10466,466 bottles of beer on the wall,Option 1,0.27047502681169,974,37531,63,98,68 +10467,467 bottles of beer on the wall,Option 1,0.41628622888414,389,43579,89,23,60 +10468,468 bottles of beer on the wall,Option 1,0.82779662722153,332,20692,50,28,57 +10469,469 bottles of beer on the wall,Option 1,0.70954406247918,490,47399,57,81,14 +10470,470 bottles of beer on the wall,Option 1,0.92123286515531,567,33351,22,98,86 +10471,471 bottles of beer on the wall,Option 1,0.12892824091433,123,7334,0,31,68 +10472,472 bottles of beer on the wall,Option 1,0.22435044833661,570,32382,22,95,74 +10473,473 bottles of beer on the wall,Option 1,0.54821905705529,871,18921,6,94,44 +10474,474 bottles of beer on the wall,Option 1,0.23450684651476,507,31401,81,72,16 +10475,475 bottles of beer on the wall,Option 1,0.07117847123703,180,25282,58,96,16 +10476,476 bottles of beer on the wall,Option 1,0.49323983792832,949,10498,11,82,84 +10477,477 bottles of beer on the wall,Option 1,0.58254413054443,588,40694,82,40,79 +10478,478 bottles of beer on the wall,Option 1,0.83353380106088,269,41193,66,92,15 +10479,479 bottles of beer on the wall,Option 1,0.69655849351387,334,45349,22,14,93 +10480,480 bottles of beer on the wall,Option 1,0.870674671545,80,18601,22,35,86 +10481,481 bottles of beer on the wall,Option 1,0.17769934897203,913,4216,47,16,36 +10482,482 bottles of beer on the wall,Option 1,0.62717400520442,518,35637,37,18,86 +10483,483 bottles of beer on the wall,Option 1,0.86194469587036,1,28857,4,43,96 +10484,484 bottles of beer on the wall,Option 1,0.44877002129739,724,7230,96,6,85 +10485,485 bottles of beer on the wall,Option 1,0.50334470556273,743,10148,74,28,80 +10486,486 bottles of beer on the wall,Option 1,0.90470263450625,278,20167,8,10,91 +10487,487 bottles of beer on the wall,Option 1,0.0564905135224064,243,34667,74,23,33 +10488,488 bottles of beer on the wall,Option 1,0.90503595858115,966,33336,51,73,40 +10489,489 bottles of beer on the wall,Option 1,0.53766181996914,79,44104,70,11,12 +10490,490 bottles of beer on the wall,Option 1,0.61526762722771,441,46213,85,55,10 +10491,491 bottles of beer on the wall,Option 1,0.68691758796894,182,38795,93,78,62 +10492,492 bottles of beer on the wall,Option 1,0.0052189598815604,231,18114,29,30,62 +10493,493 bottles of beer on the wall,Option 1,0.87267877760933,213,31756,7,35,21 +10494,494 bottles of beer on the wall,Option 1,0.49640192161146,534,47281,25,29,34 +10495,495 bottles of beer on the wall,Option 1,0.71941438537063,152,34329,30,10,39 +10496,496 bottles of beer on the wall,Option 1,0.65859091312558,965,11892,18,37,78 +10497,497 bottles of beer on the wall,Option 1,0.72376093534927,598,21067,34,67,48 +10498,498 bottles of beer on the wall,Option 1,0.98639214503876,299,43697,84,21,11 +10499,499 bottles of beer on the wall,Option 1,0.13237802085111,838,146,80,23,45 +10500,500 bottles of beer on the wall,Option 1,0.20127655621677,156,44782,60,99,19 +0,this is dummy datass,Option 1,42,42,42,42,3,44 +1,more dummy datass,Option 2,42,42,42,422,3,44 +;;;; +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/refreshlibinfo.js b/sas/mocks/sasjs/services/public/refreshlibinfo.js new file mode 100644 index 0000000..cedfd44 --- /dev/null +++ b/sas/mocks/sasjs/services/public/refreshlibinfo.js @@ -0,0 +1,39 @@ +_webout = `{"SYSDATE" : "29SEP22" +,"SYSTIME" : "12:02" +, "libinfo": +[ + { + "ENGINE": "BASE", + "LIBNAME": "Data Controller(DC996664)", + "PATHS": "(\\"/tmp/mihajlo/DC996664\\")", + "PERMS": "", + "OWNERS": "BUILTIN\Administrators", + "SCHEMAS": "", + "LIBID": "A59LNVZG.B500000K", + "LIBSIZE": " 13MB", + "TABLE_CNT": 32 + } +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/refreshlibinfo" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "A connection to the LASR Analytic Server on 'SAS.demo.sas.com', port 10011, could not be made. Make sure that the host and port are correctly specified, that you are attempting to connect to a LASR Analytic Server of the correct vintage, and that the server is still running." +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD816037A1CAC140C2B00000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "14432" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-29T12:02:44.445000" +,"MEMSIZE" : "93GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/startupservice.js b/sas/mocks/sasjs/services/public/startupservice.js new file mode 100644 index 0000000..f2ee5fa --- /dev/null +++ b/sas/mocks/sasjs/services/public/startupservice.js @@ -0,0 +1,107 @@ +const path = require('path') + +let appLoc = path.join(..._program.split('services')[0].split('/')) +const sessionStoragePath = path.resolve(__dirname, '..', '..', 'drive', 'files', appLoc, 'mock-storage') +const licenceStore = path.resolve(sessionStoragePath, 'licence.json') +const usersStore = path.resolve(sessionStoragePath, 'users.json') + +let licence = {} +let users = {} + +licence = { + activationKey: '', + licenceKey: '' +} + +users = { + REGISTERCOUNT: 1, + ISREGISTERED: 1 +} + +try { + const licenceRaw = fs.readFileSync(licenceStore, {encoding:'utf8'}).toString() + licence = JSON.parse(licenceRaw) +} catch(err) { + +} + +try { + const usersRaw = fs.readFileSync(usersStore, {encoding:'utf8'}).toString() + users = JSON.parse(usersRaw) + + if (users.ISREGISTERED === 0) { + const newUsers = { + REGISTERCOUNT: users.REGISTERCOUNT, + ISREGISTERED: 1 + } + + try { + fs.writeFileSync(usersStore, JSON.stringify(newUsers)) + } catch (err) {} + } +} catch(err) { + +} + +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:29" +, "sasdatasets": +[ +{ +"LIBREF": "DC996664", +"DSN": "MPE_X_TEST" +}, +{ + "LIBREF": "DC996664", + "DSN": "MPE_DATADICTIONARY" +}, +{ + "LIBREF": "DC996664", + "DSN": "MPE_USERS" +}, +{ + "LIBREF": "DC996664", + "DSN": "MPE_TABLES" +} +] +, "saslibs": +[ +{ +"LIBREF": "DC996664" +} +] +, "globvars": +[ +{ +"DCLIB": "DC996664", +"SAS9LINEAGE_ENABLED": 1, +"ISREGISTERED": ${users.ISREGISTERED}, +"REGISTERCOUNT": ${users.REGISTERCOUNT}, +"DC_ADMIN_GROUP": "Data Management Business Approvers", +"LICENCE_KEY": "${licence.licenceKey}", +"ACTIVATION_KEY": "${licence.activationKey}", +"DC_RESTRICT_EDITRECORD": "NO" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/startupservice" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8056944A8F5C409C500000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:29:06.092000" +,"MEMSIZE" : "46GB" +}` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/validatefilter.js b/sas/mocks/sasjs/services/public/validatefilter.js new file mode 100644 index 0000000..950f395 --- /dev/null +++ b/sas/mocks/sasjs/services/public/validatefilter.js @@ -0,0 +1,66 @@ +const path = require('path') + +let iwantFileText = '' +// let filterQuery1 = `AND,AND,0,SOME_CHAR,=,"'this is dummy data'"` +// let filterQuery2 = `AND,AND,0,SOME_NUM,=,42` +// let filterQuery3 = `AND,AND,0,SOME_TIME,=,00:00:42` +// let filterQuery4 = `AND,AND,0,SOME_TIME,=,42` +// let filterQuery5 = `AND,AND,0,SOME_DATE,=,42` +// let filterQuery6 = `AND,AND,0,SOME_DATE,=,42` +// let filterQuery7 = `AND,AND,0,SOME_DATETIME,=,42` +// let filterQuery8 = `AND,AND,0,SOME_DATETIME,=,42` +// let filterQuery9 = `AND,AND,0,SOME_DATE,IN,(0)` +// let filterQuery10 = `AND,AND,0,SOME_BESTNUM,BETWEEN,0 AND 10` + +let appLoc = path.join(..._program.split('services')[0].split('/')) +const sessionStoragePath = path.resolve(__dirname, '..', '..', 'drive', 'files', appLoc, 'mock-storage') + +if (!fs.existsSync(sessionStoragePath)){ + fs.mkdirSync(sessionStoragePath); +} + +if (_WEBIN_FILENAME1.includes('filterquery')) iwantFileText = _WEBIN_FILEREF1.toString() +if (_WEBIN_FILENAME2.includes('filterquery')) iwantFileText = _WEBIN_FILEREF2.toString() + +if (iwantFileText.length > 0) { + const filterStore = path.resolve(sessionStoragePath, 'filter.txt') + const filterText = iwantFileText.split('\n')[1] + + try { + fs.writeFileSync(filterStore, filterText) + } catch (err) {} +} + +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:49" +, "result": +[ +{ +"FILTER_RK": 1, +"FILTER_HASH": "FFE9C1E5F7AEC3B71F315EF2FEFC2296", +"FILTER_TABLE": "DC996664.MPE_X_TEST" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/validatefilter" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057CAEDE35440BF960000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:49:48.696000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/viewdata.js b/sas/mocks/sasjs/services/public/viewdata.js new file mode 100644 index 0000000..5a1970a --- /dev/null +++ b/sas/mocks/sasjs/services/public/viewdata.js @@ -0,0 +1,3065 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "cls_rules": +[ + +] +, "cols": +[ +{ +"NAME": "PRIMARY_KEY_FIELD", +"LENGTH": 8, +"VARNUM": 1, +"LABEL": "PRIMARY_KEY_FIELD", +"FMTNAME": "", +"FORMAT": "8.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_BESTNUM", +"LENGTH": 8, +"VARNUM": 9, +"LABEL": "SOME_BESTNUM", +"FMTNAME": "BEST", +"FORMAT": "BEST.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_CHAR", +"LENGTH": 32767, +"VARNUM": 2, +"LABEL": "SOME_CHAR", +"FMTNAME": "", +"FORMAT": "$32767.", +"TYPE": "C", +"DDTYPE": "CHARACTER" +}, +{ +"NAME": "SOME_DATE", +"LENGTH": 8, +"VARNUM": 5, +"LABEL": "SOME_DATE", +"FMTNAME": "DATE", +"FORMAT": "DATE9.", +"TYPE": "N", +"DDTYPE": "DATE" +}, +{ +"NAME": "SOME_DATETIME", +"LENGTH": 8, +"VARNUM": 6, +"LABEL": "SOME_DATETIME", +"FMTNAME": "DATETIME", +"FORMAT": "DATETIME19.", +"TYPE": "N", +"DDTYPE": "DATETIME" +}, +{ +"NAME": "SOME_DROPDOWN", +"LENGTH": 128, +"VARNUM": 3, +"LABEL": "SOME_DROPDOWN", +"FMTNAME": "", +"FORMAT": "$128.", +"TYPE": "C", +"DDTYPE": "CHARACTER" +}, +{ +"NAME": "SOME_NUM", +"LENGTH": 8, +"VARNUM": 4, +"LABEL": "SOME_NUM", +"FMTNAME": "", +"FORMAT": "8.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_SHORTNUM", +"LENGTH": 4, +"VARNUM": 8, +"LABEL": "SOME_SHORTNUM", +"FMTNAME": "", +"FORMAT": "4.", +"TYPE": "N", +"DDTYPE": "NUMERIC" +}, +{ +"NAME": "SOME_TIME", +"LENGTH": 8, +"VARNUM": 7, +"LABEL": "SOME_TIME", +"FMTNAME": "TIME", +"FORMAT": "TIME8.", +"TYPE": "N", +"DDTYPE": "TIME" +} +] +, "dsmeta": +[ +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Name", +"VALUE": "DC996664.MPE_X_TEST" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observations", +"VALUE": "496" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Member Type", +"VALUE": "DATA" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Variables", +"VALUE": "9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Engine", +"VALUE": "V9" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Indexes", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Created", +"VALUE": "09/26/2022 08:24:39" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Integrity Constraints", +"VALUE": "1" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Last Modified", +"VALUE": "09/26/2022 08:47:46" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Observation Length", +"VALUE": "32947" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Protection", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Deleted Observations", +"VALUE": "2" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Set Type", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Compressed", +"VALUE": "CHAR" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Label", +"VALUE": " ." +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Reuse Space", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Data Representation", +"VALUE": "WINDOWS_64" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Point to Observations", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Encoding", +"VALUE": "wlatin1 Western (Windows)" +}, +{ +"ODS_TABLE": "ATTRIBUTES", +"NAME": "Sorted", +"VALUE": "NO" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Data Set Page Size", +"VALUE": "262144" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Pages", +"VALUE": "3" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Index File Page Size", +"VALUE": "4096" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Index File Pages", +"VALUE": "4" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Number of Data Set Repairs", +"VALUE": "0" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "ExtendObsCounter", +"VALUE": "YES" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Filename", +"VALUE": "C:\DataController\DC996664\mpe_x_test.sas7bdat" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Release Created", +"VALUE": "9.0401M7" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Host Created", +"VALUE": "Linunx" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "Owner Name", +"VALUE": "BUILTIN\Administrators" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size", +"VALUE": " 1MB" +}, +{ +"ODS_TABLE": "ENGINEHOST", +"NAME": "File Size (bytes)", +"VALUE": "1048576" +} +] +, "query": +[ + +] +, "sasparams": +[ +{ +"TABLEURI": "OMSOBJ:PhysicalTable\A59LNVZG.BR000036", +"TABLENAME": "MPE_X_TEST", +"FILTER_TEXT": "", +"PK_FIELDS": "PRIMARY_KEY_FIELD", +"NOBS": 496, +"VARS": 9, +"MAXROWS": 250 +} +] +, "viewdata": +[ +{ +"PRIMARY_KEY_FIELD": 2, +"SOME_CHAR": "even more dummy data", +"SOME_DROPDOWN": "Option 3", +"SOME_NUM": 42, +"SOME_DATE": "12FEB1960", +"SOME_DATETIME": " 01JAN1960:00:00:42", +"SOME_TIME": " 0:02:22", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 3, +"SOME_CHAR": "It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:", +"SOME_DROPDOWN": "Option 2", +"SOME_NUM": 1613.001, +"SOME_DATE": "27FEB1961", +"SOME_DATETIME": " 01JAN1960:00:07:03", +"SOME_TIME": " 0:00:44", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 4, +"SOME_CHAR": "if you can fill the unforgiving minute", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 1613.00112346, +"SOME_DATE": "02AUG1971", +"SOME_DATETIME": " 29MAY1973:06:12:03", +"SOME_TIME": " 0:06:52", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 1010, +"SOME_CHAR": "10 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.367786711253, +"SOME_DATE": "05MAR1961", +"SOME_DATETIME": " 01JAN1960:08:16:44", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 1, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1011, +"SOME_CHAR": "11 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.869333049687, +"SOME_DATE": "20JAN1961", +"SOME_DATETIME": " 01JAN1960:01:25:19", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 54 +}, +{ +"PRIMARY_KEY_FIELD": 1012, +"SOME_CHAR": "12 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.543277906507, +"SOME_DATE": "06OCT1961", +"SOME_DATETIME": " 01JAN1960:02:57:35", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 62 +}, +{ +"PRIMARY_KEY_FIELD": 1013, +"SOME_CHAR": "13 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.5051939867, +"SOME_DATE": "20FEB1962", +"SOME_DATETIME": " 01JAN1960:06:47:55", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 1014, +"SOME_CHAR": "14 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0130502507151, +"SOME_DATE": "13JAN1960", +"SOME_DATETIME": " 01JAN1960:03:48:13", +"SOME_TIME": " 0:00:14", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 57 +}, +{ +"PRIMARY_KEY_FIELD": 1015, +"SOME_CHAR": "15 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.582270800873, +"SOME_DATE": "12JUL1962", +"SOME_DATETIME": " 01JAN1960:12:05:18", +"SOME_TIME": " 0:00:54", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 80 +}, +{ +"PRIMARY_KEY_FIELD": 1016, +"SOME_CHAR": "16 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.138272497867, +"SOME_DATE": "29AUG1960", +"SOME_DATETIME": " 01JAN1960:02:48:01", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 1017, +"SOME_CHAR": "17 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.892701324025, +"SOME_DATE": "14SEP1961", +"SOME_DATETIME": " 01JAN1960:07:03:58", +"SOME_TIME": " 0:01:37", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1018, +"SOME_CHAR": "18 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.185278856747, +"SOME_DATE": "08MAR1961", +"SOME_DATETIME": " 01JAN1960:00:22:48", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 1019, +"SOME_CHAR": "19 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0737551018008, +"SOME_DATE": "24JAN1961", +"SOME_DATETIME": " 01JAN1960:03:14:33", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 1020, +"SOME_CHAR": "20 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.712856993877, +"SOME_DATE": "08FEB1961", +"SOME_DATETIME": " 01JAN1960:01:50:23", +"SOME_TIME": " 0:01:40", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 1021, +"SOME_CHAR": "21 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.67061384426, +"SOME_DATE": "09MAR1961", +"SOME_DATETIME": " 01JAN1960:04:52:55", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 1022, +"SOME_CHAR": "22 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.142321579225, +"SOME_DATE": "22JUL1962", +"SOME_DATETIME": " 01JAN1960:07:25:01", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 66, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1023, +"SOME_CHAR": "23 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.125984806626, +"SOME_DATE": "01SEP1962", +"SOME_DATETIME": " 01JAN1960:09:32:34", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1024, +"SOME_CHAR": "24 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.389946863702, +"SOME_DATE": "06DEC1961", +"SOME_DATETIME": " 01JAN1960:06:53:51", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 1025, +"SOME_CHAR": "25 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0310356193367, +"SOME_DATE": "01MAR1960", +"SOME_DATETIME": " 01JAN1960:02:58:07", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 1026, +"SOME_CHAR": "26 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905788423915, +"SOME_DATE": "04OCT1960", +"SOME_DATETIME": " 01JAN1960:11:17:28", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 82, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 1027, +"SOME_CHAR": "27 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.592067585602, +"SOME_DATE": "15JUL1962", +"SOME_DATETIME": " 01JAN1960:03:35:41", +"SOME_TIME": " 0:00:22", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 73 +}, +{ +"PRIMARY_KEY_FIELD": 1028, +"SOME_CHAR": "28 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.658003004574, +"SOME_DATE": "08OCT1960", +"SOME_DATETIME": " 01JAN1960:13:13:30", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 40 +}, +{ +"PRIMARY_KEY_FIELD": 1029, +"SOME_CHAR": "29 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.807042593978, +"SOME_DATE": "26DEC1960", +"SOME_DATETIME": " 01JAN1960:11:57:14", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 12 +}, +{ +"PRIMARY_KEY_FIELD": 1030, +"SOME_CHAR": "30 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.880145040751, +"SOME_DATE": "15MAY1961", +"SOME_DATETIME": " 01JAN1960:10:11:05", +"SOME_TIME": " 0:00:25", +"SOME_SHORTNUM": 70, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 1031, +"SOME_CHAR": "31 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.41501947046, +"SOME_DATE": "27JAN1962", +"SOME_DATETIME": " 01JAN1960:11:27:09", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 94, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 1032, +"SOME_CHAR": "32 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.974340120319, +"SOME_DATE": "09JAN1962", +"SOME_DATETIME": " 01JAN1960:07:44:35", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 3 +}, +{ +"PRIMARY_KEY_FIELD": 1033, +"SOME_CHAR": "33 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.203559569178, +"SOME_DATE": "07SEP1960", +"SOME_DATETIME": " 01JAN1960:11:52:19", +"SOME_TIME": " 0:00:42", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 1034, +"SOME_CHAR": "34 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.679243555609, +"SOME_DATE": "21APR1960", +"SOME_DATETIME": " 01JAN1960:07:17:04", +"SOME_TIME": " 0:01:14", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 1035, +"SOME_CHAR": "35 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.949411697197, +"SOME_DATE": "19JAN1960", +"SOME_DATETIME": " 01JAN1960:10:15:38", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 1036, +"SOME_CHAR": "36 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.544613491066, +"SOME_DATE": "26OCT1960", +"SOME_DATETIME": " 01JAN1960:03:55:27", +"SOME_TIME": " 0:01:24", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 1037, +"SOME_CHAR": "37 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.458775893999, +"SOME_DATE": "21NOV1960", +"SOME_DATETIME": " 01JAN1960:13:34:37", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1038, +"SOME_CHAR": "38 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.153719423876, +"SOME_DATE": "06MAY1961", +"SOME_DATETIME": " 01JAN1960:06:14:13", +"SOME_TIME": " 0:00:29", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1039, +"SOME_CHAR": "39 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.493500256209, +"SOME_DATE": "05JUN1960", +"SOME_DATETIME": " 01JAN1960:06:59:42", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 55 +}, +{ +"PRIMARY_KEY_FIELD": 1040, +"SOME_CHAR": "40 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.124728858995, +"SOME_DATE": "09MAR1961", +"SOME_DATETIME": " 01JAN1960:03:03:06", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 1041, +"SOME_CHAR": "41 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.279442200102, +"SOME_DATE": "06JUL1962", +"SOME_DATETIME": " 01JAN1960:05:29:26", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1042, +"SOME_CHAR": "42 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.703077549908, +"SOME_DATE": "11AUG1960", +"SOME_DATETIME": " 01JAN1960:12:11:24", +"SOME_TIME": " 0:00:38", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 1043, +"SOME_CHAR": "43 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0701107536769, +"SOME_DATE": "29JAN1961", +"SOME_DATETIME": " 01JAN1960:03:44:09", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 1044, +"SOME_CHAR": "44 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.642329292671, +"SOME_DATE": "15JAN1962", +"SOME_DATETIME": " 01JAN1960:00:57:07", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 37 +}, +{ +"PRIMARY_KEY_FIELD": 1045, +"SOME_CHAR": "45 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.720644774251, +"SOME_DATE": "14OCT1961", +"SOME_DATETIME": " 01JAN1960:12:25:32", +"SOME_TIME": " 0:00:07", +"SOME_SHORTNUM": 58, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1046, +"SOME_CHAR": "46 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0431997366451, +"SOME_DATE": "12SEP1960", +"SOME_DATETIME": " 01JAN1960:05:12:57", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 1047, +"SOME_CHAR": "47 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.370407136795, +"SOME_DATE": "01JUL1960", +"SOME_DATETIME": " 01JAN1960:02:44:37", +"SOME_TIME": " 0:00:06", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 26 +}, +{ +"PRIMARY_KEY_FIELD": 1048, +"SOME_CHAR": "48 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.654417035009, +"SOME_DATE": "04MAY1961", +"SOME_DATETIME": " 01JAN1960:01:23:07", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 13 +}, +{ +"PRIMARY_KEY_FIELD": 1049, +"SOME_CHAR": "49 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.130021256455, +"SOME_DATE": "06JAN1961", +"SOME_DATETIME": " 01JAN1960:05:27:29", +"SOME_TIME": " 0:01:21", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1050, +"SOME_CHAR": "50 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.00584097253431, +"SOME_DATE": "23JUL1960", +"SOME_DATETIME": " 01JAN1960:00:04:24", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 15, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1051, +"SOME_CHAR": "51 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.723938258702, +"SOME_DATE": "09JUN1960", +"SOME_DATETIME": " 01JAN1960:03:15:09", +"SOME_TIME": " 0:00:04", +"SOME_SHORTNUM": 42, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 1052, +"SOME_CHAR": "52 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.83190037116, +"SOME_DATE": "13AUG1960", +"SOME_DATETIME": " 01JAN1960:07:38:35", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 1053, +"SOME_CHAR": "53 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.503082887504, +"SOME_DATE": "22JUN1961", +"SOME_DATETIME": " 01JAN1960:11:25:29", +"SOME_TIME": " 0:00:53", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 75 +}, +{ +"PRIMARY_KEY_FIELD": 1054, +"SOME_CHAR": "54 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.714804551431, +"SOME_DATE": "26AUG1960", +"SOME_DATETIME": " 01JAN1960:10:10:09", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 1055, +"SOME_CHAR": "55 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.855794578724, +"SOME_DATE": "19OCT1960", +"SOME_DATETIME": " 01JAN1960:02:17:32", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 1056, +"SOME_CHAR": "56 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.970046330695, +"SOME_DATE": "11JUL1962", +"SOME_DATETIME": " 01JAN1960:11:18:41", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 1057, +"SOME_CHAR": "57 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.938039942616, +"SOME_DATE": "26JUN1961", +"SOME_DATETIME": " 01JAN1960:13:15:13", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 57, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 1058, +"SOME_CHAR": "58 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.848449948639, +"SOME_DATE": "02JUN1960", +"SOME_DATETIME": " 01JAN1960:01:14:51", +"SOME_TIME": " 0:00:00", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1059, +"SOME_CHAR": "59 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.141570762797, +"SOME_DATE": "28JUL1961", +"SOME_DATETIME": " 01JAN1960:06:33:16", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1060, +"SOME_CHAR": "60 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.282674512958, +"SOME_DATE": "27MAR1962", +"SOME_DATETIME": " 01JAN1960:00:25:37", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 1061, +"SOME_CHAR": "61 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.372728008019, +"SOME_DATE": "04JAN1962", +"SOME_DATETIME": " 01JAN1960:05:07:43", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 1062, +"SOME_CHAR": "62 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.951733731642, +"SOME_DATE": "29AUG1961", +"SOME_DATETIME": " 01JAN1960:02:40:05", +"SOME_TIME": " 0:00:05", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 1063, +"SOME_CHAR": "63 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.096749868289, +"SOME_DATE": "17FEB1962", +"SOME_DATETIME": " 01JAN1960:07:30:41", +"SOME_TIME": " 0:00:29", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 1064, +"SOME_CHAR": "64 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.054067135348, +"SOME_DATE": "26MAY1961", +"SOME_DATETIME": " 01JAN1960:13:13:43", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 45 +}, +{ +"PRIMARY_KEY_FIELD": 1065, +"SOME_CHAR": "65 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.646163646433, +"SOME_DATE": "27JAN1962", +"SOME_DATETIME": " 01JAN1960:02:56:41", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 38 +}, +{ +"PRIMARY_KEY_FIELD": 1066, +"SOME_CHAR": "66 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905301198319, +"SOME_DATE": "02OCT1960", +"SOME_DATETIME": " 01JAN1960:03:35:49", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 39 +}, +{ +"PRIMARY_KEY_FIELD": 1067, +"SOME_CHAR": "67 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.977525881015, +"SOME_DATE": "19JUL1962", +"SOME_DATETIME": " 01JAN1960:05:53:20", +"SOME_TIME": " 0:00:28", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 1068, +"SOME_CHAR": "68 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.216555316102, +"SOME_DATE": "13MAY1960", +"SOME_DATETIME": " 01JAN1960:01:44:02", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 23 +}, +{ +"PRIMARY_KEY_FIELD": 1069, +"SOME_CHAR": "69 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.224835279502, +"SOME_DATE": "09MAY1961", +"SOME_DATETIME": " 01JAN1960:00:04:33", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 1070, +"SOME_CHAR": "70 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.138628336666, +"SOME_DATE": "18MAY1962", +"SOME_DATETIME": " 01JAN1960:03:32:00", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 89 +}, +{ +"PRIMARY_KEY_FIELD": 1071, +"SOME_CHAR": "71 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.933733141485, +"SOME_DATE": "16MAY1961", +"SOME_DATETIME": " 01JAN1960:13:46:54", +"SOME_TIME": " 0:00:47", +"SOME_SHORTNUM": 27, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 1072, +"SOME_CHAR": "72 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0352235506453, +"SOME_DATE": "06JUN1961", +"SOME_DATETIME": " 01JAN1960:09:09:20", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 7, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 1073, +"SOME_CHAR": "73 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.320666269549, +"SOME_DATE": "13MAR1960", +"SOME_DATETIME": " 01JAN1960:10:38:11", +"SOME_TIME": " 0:01:08", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 1074, +"SOME_CHAR": "74 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.461086170497, +"SOME_DATE": "31AUG1961", +"SOME_DATETIME": " 01JAN1960:09:35:41", +"SOME_TIME": " 0:01:08", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 68 +}, +{ +"PRIMARY_KEY_FIELD": 1075, +"SOME_CHAR": "75 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.452774562152, +"SOME_DATE": "16JAN1962", +"SOME_DATETIME": " 01JAN1960:06:49:27", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 96, +"SOME_BESTNUM": 63 +}, +{ +"PRIMARY_KEY_FIELD": 1076, +"SOME_CHAR": "76 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.358124405778, +"SOME_DATE": "16MAY1960", +"SOME_DATETIME": " 01JAN1960:00:56:40", +"SOME_TIME": " 0:01:13", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 24 +}, +{ +"PRIMARY_KEY_FIELD": 1077, +"SOME_CHAR": "77 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.893992133389, +"SOME_DATE": "21JAN1961", +"SOME_DATETIME": " 01JAN1960:09:16:31", +"SOME_TIME": " 0:01:15", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 69 +}, +{ +"PRIMARY_KEY_FIELD": 1078, +"SOME_CHAR": "78 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.244572706634, +"SOME_DATE": "22DEC1960", +"SOME_DATETIME": " 01JAN1960:03:11:14", +"SOME_TIME": " 0:01:37", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1079, +"SOME_CHAR": "79 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.968302946523, +"SOME_DATE": "14AUG1961", +"SOME_DATETIME": " 01JAN1960:04:45:43", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 60 +}, +{ +"PRIMARY_KEY_FIELD": 1080, +"SOME_CHAR": "80 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.130354136755, +"SOME_DATE": "28FEB1962", +"SOME_DATETIME": " 01JAN1960:02:14:50", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 87 +}, +{ +"PRIMARY_KEY_FIELD": 1081, +"SOME_CHAR": "81 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.765697965289, +"SOME_DATE": "03AUG1961", +"SOME_DATETIME": " 01JAN1960:06:49:50", +"SOME_TIME": " 0:01:31", +"SOME_SHORTNUM": 58, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 1082, +"SOME_CHAR": "82 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.185562967409, +"SOME_DATE": "16DEC1960", +"SOME_DATETIME": " 01JAN1960:06:27:21", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 1, +"SOME_BESTNUM": 72 +}, +{ +"PRIMARY_KEY_FIELD": 1083, +"SOME_CHAR": "83 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.478217864166, +"SOME_DATE": "16APR1961", +"SOME_DATETIME": " 01JAN1960:08:05:23", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 0, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 1084, +"SOME_CHAR": "84 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.167027213223, +"SOME_DATE": "21JUN1962", +"SOME_DATETIME": " 01JAN1960:13:43:20", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 6 +}, +{ +"PRIMARY_KEY_FIELD": 1085, +"SOME_CHAR": "85 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.606824918933, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:11:05:11", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 68 +}, +{ +"PRIMARY_KEY_FIELD": 1086, +"SOME_CHAR": "86 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0936049917217, +"SOME_DATE": "20JUL1962", +"SOME_DATETIME": " 01JAN1960:07:16:09", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 37 +}, +{ +"PRIMARY_KEY_FIELD": 1087, +"SOME_CHAR": "87 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.653824917811, +"SOME_DATE": "24APR1960", +"SOME_DATETIME": " 01JAN1960:02:06:54", +"SOME_TIME": " 0:00:59", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 1088, +"SOME_CHAR": "88 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.884615856169, +"SOME_DATE": "19NOV1961", +"SOME_DATETIME": " 01JAN1960:05:35:27", +"SOME_TIME": " 0:01:01", +"SOME_SHORTNUM": 87, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 1089, +"SOME_CHAR": "89 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.157820831592, +"SOME_DATE": "03MAR1961", +"SOME_DATETIME": " 01JAN1960:09:02:02", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 1090, +"SOME_CHAR": "90 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.422575375262, +"SOME_DATE": "19MAR1960", +"SOME_DATETIME": " 01JAN1960:12:14:04", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 57, +"SOME_BESTNUM": 64 +}, +{ +"PRIMARY_KEY_FIELD": 1091, +"SOME_CHAR": "91 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.659894335391, +"SOME_DATE": "17SEP1961", +"SOME_DATETIME": " 01JAN1960:03:03:13", +"SOME_TIME": " 0:01:00", +"SOME_SHORTNUM": 41, +"SOME_BESTNUM": 28 +}, +{ +"PRIMARY_KEY_FIELD": 1092, +"SOME_CHAR": "92 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.629350168924, +"SOME_DATE": "18OCT1961", +"SOME_DATETIME": " 01JAN1960:00:21:13", +"SOME_TIME": " 0:01:11", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 1093, +"SOME_CHAR": "93 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.437884498591, +"SOME_DATE": "24JUN1961", +"SOME_DATETIME": " 01JAN1960:10:20:39", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 78 +}, +{ +"PRIMARY_KEY_FIELD": 1094, +"SOME_CHAR": "94 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.983858496875, +"SOME_DATE": "25MAY1962", +"SOME_DATETIME": " 01JAN1960:02:59:06", +"SOME_TIME": " 0:00:59", +"SOME_SHORTNUM": 48, +"SOME_BESTNUM": 98 +}, +{ +"PRIMARY_KEY_FIELD": 1095, +"SOME_CHAR": "95 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0892523769705, +"SOME_DATE": "16JUN1961", +"SOME_DATETIME": " 01JAN1960:04:54:20", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 1096, +"SOME_CHAR": "96 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.457820515362, +"SOME_DATE": "20JAN1960", +"SOME_DATETIME": " 01JAN1960:10:36:00", +"SOME_TIME": " 0:00:41", +"SOME_SHORTNUM": 14, +"SOME_BESTNUM": 17 +}, +{ +"PRIMARY_KEY_FIELD": 1097, +"SOME_CHAR": "97 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.586327158653, +"SOME_DATE": "20APR1962", +"SOME_DATETIME": " 01JAN1960:11:14:11", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 66, +"SOME_BESTNUM": 84 +}, +{ +"PRIMARY_KEY_FIELD": 1098, +"SOME_CHAR": "98 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.299423205806, +"SOME_DATE": "04JUL1960", +"SOME_DATETIME": " 01JAN1960:08:15:41", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 1099, +"SOME_CHAR": "99 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0981378052841, +"SOME_DATE": "05FEB1960", +"SOME_DATETIME": " 01JAN1960:11:10:11", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 23, +"SOME_BESTNUM": 65 +}, +{ +"PRIMARY_KEY_FIELD": 10100, +"SOME_CHAR": "100 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.982972265213, +"SOME_DATE": "01FEB1960", +"SOME_DATETIME": " 01JAN1960:05:45:06", +"SOME_TIME": " 0:01:16", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 10101, +"SOME_CHAR": "101 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.454079491298, +"SOME_DATE": "03AUG1962", +"SOME_DATETIME": " 01JAN1960:09:27:03", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 42, +"SOME_BESTNUM": 44 +}, +{ +"PRIMARY_KEY_FIELD": 10102, +"SOME_CHAR": "102 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.845217436946, +"SOME_DATE": "02OCT1960", +"SOME_DATETIME": " 01JAN1960:03:08:47", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10103, +"SOME_CHAR": "103 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.590491960566, +"SOME_DATE": "30JUL1960", +"SOME_DATETIME": " 01JAN1960:13:09:58", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 68, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 10104, +"SOME_CHAR": "104 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.708338867737, +"SOME_DATE": "24JUL1960", +"SOME_DATETIME": " 01JAN1960:05:49:50", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10105, +"SOME_CHAR": "105 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.318355025872, +"SOME_DATE": "14SEP1961", +"SOME_DATETIME": " 01JAN1960:02:28:34", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10106, +"SOME_CHAR": "106 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.972975597239, +"SOME_DATE": "08AUG1961", +"SOME_DATETIME": " 01JAN1960:04:30:41", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10107, +"SOME_CHAR": "107 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.509077321509, +"SOME_DATE": "23SEP1960", +"SOME_DATETIME": " 01JAN1960:05:20:31", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 92, +"SOME_BESTNUM": 73 +}, +{ +"PRIMARY_KEY_FIELD": 10108, +"SOME_CHAR": "108 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.605017692598, +"SOME_DATE": "18MAR1961", +"SOME_DATETIME": " 01JAN1960:02:16:28", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 21 +}, +{ +"PRIMARY_KEY_FIELD": 10109, +"SOME_CHAR": "109 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.361268181522, +"SOME_DATE": "02JAN1962", +"SOME_DATETIME": " 01JAN1960:11:03:06", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 10110, +"SOME_CHAR": "110 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.92257953711, +"SOME_DATE": "30JUN1960", +"SOME_DATETIME": " 01JAN1960:07:37:19", +"SOME_TIME": " 0:00:53", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10111, +"SOME_CHAR": "111 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.576207744226, +"SOME_DATE": "02JAN1960", +"SOME_DATETIME": " 01JAN1960:02:58:52", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 94 +}, +{ +"PRIMARY_KEY_FIELD": 10112, +"SOME_CHAR": "112 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.722135797945, +"SOME_DATE": "03JAN1961", +"SOME_DATETIME": " 01JAN1960:06:46:21", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10113, +"SOME_CHAR": "113 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.683960923312, +"SOME_DATE": "26MAY1962", +"SOME_DATETIME": " 01JAN1960:02:09:46", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 88, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10114, +"SOME_CHAR": "114 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0627542203584, +"SOME_DATE": "30AUG1960", +"SOME_DATETIME": " 01JAN1960:10:55:01", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 10115, +"SOME_CHAR": "115 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.146239363191, +"SOME_DATE": "02FEB1962", +"SOME_DATETIME": " 01JAN1960:08:38:32", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10116, +"SOME_CHAR": "116 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.88700955449, +"SOME_DATE": "06APR1961", +"SOME_DATETIME": " 01JAN1960:08:19:07", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 100 +}, +{ +"PRIMARY_KEY_FIELD": 10117, +"SOME_CHAR": "117 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.586251998128, +"SOME_DATE": "11FEB1962", +"SOME_DATETIME": " 01JAN1960:09:18:09", +"SOME_TIME": " 0:01:24", +"SOME_SHORTNUM": 17, +"SOME_BESTNUM": 65 +}, +{ +"PRIMARY_KEY_FIELD": 10118, +"SOME_CHAR": "118 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.119509128444, +"SOME_DATE": "29MAR1960", +"SOME_DATETIME": " 01JAN1960:05:00:30", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 74, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 10119, +"SOME_CHAR": "119 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.25274958287, +"SOME_DATE": "14MAR1960", +"SOME_DATETIME": " 01JAN1960:11:15:20", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10120, +"SOME_CHAR": "120 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.200962597132, +"SOME_DATE": "18NOV1960", +"SOME_DATETIME": " 01JAN1960:10:17:59", +"SOME_TIME": " 0:00:25", +"SOME_SHORTNUM": 72, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10121, +"SOME_CHAR": "121 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.517157181407, +"SOME_DATE": "27NOV1961", +"SOME_DATETIME": " 01JAN1960:09:53:43", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10122, +"SOME_CHAR": "122 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.625352653966, +"SOME_DATE": "15DEC1960", +"SOME_DATETIME": " 01JAN1960:05:14:23", +"SOME_TIME": " 0:01:17", +"SOME_SHORTNUM": 55, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10123, +"SOME_CHAR": "123 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0397578571177, +"SOME_DATE": "08SEP1961", +"SOME_DATETIME": " 01JAN1960:00:37:02", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 21, +"SOME_BESTNUM": 21 +}, +{ +"PRIMARY_KEY_FIELD": 10124, +"SOME_CHAR": "124 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.152996921983, +"SOME_DATE": "20FEB1962", +"SOME_DATETIME": " 01JAN1960:08:46:06", +"SOME_TIME": " 0:00:49", +"SOME_SHORTNUM": 77, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10125, +"SOME_CHAR": "125 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.55944163518, +"SOME_DATE": "28APR1962", +"SOME_DATETIME": " 01JAN1960:05:02:05", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10126, +"SOME_CHAR": "126 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0545679247261, +"SOME_DATE": "12APR1960", +"SOME_DATETIME": " 01JAN1960:03:28:48", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 78, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10127, +"SOME_CHAR": "127 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.371348928367, +"SOME_DATE": "12OCT1961", +"SOME_DATETIME": " 01JAN1960:02:16:07", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 88 +}, +{ +"PRIMARY_KEY_FIELD": 10128, +"SOME_CHAR": "128 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.647298235282, +"SOME_DATE": "03APR1960", +"SOME_DATETIME": " 01JAN1960:00:32:14", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 10129, +"SOME_CHAR": "129 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.830022884919, +"SOME_DATE": "05JAN1960", +"SOME_DATETIME": " 01JAN1960:13:45:11", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10130, +"SOME_CHAR": "130 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.265660790385, +"SOME_DATE": "10JUL1961", +"SOME_DATETIME": " 01JAN1960:05:20:20", +"SOME_TIME": " 0:00:44", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10131, +"SOME_CHAR": "131 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.351538887877, +"SOME_DATE": "10APR1961", +"SOME_DATETIME": " 01JAN1960:02:34:28", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 33, +"SOME_BESTNUM": 47 +}, +{ +"PRIMARY_KEY_FIELD": 10132, +"SOME_CHAR": "132 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.584812691708, +"SOME_DATE": "04JAN1961", +"SOME_DATETIME": " 01JAN1960:00:58:07", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 27, +"SOME_BESTNUM": 23 +}, +{ +"PRIMARY_KEY_FIELD": 10133, +"SOME_CHAR": "133 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.359766102563, +"SOME_DATE": "01APR1962", +"SOME_DATETIME": " 01JAN1960:04:32:07", +"SOME_TIME": " 0:00:12", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 79 +}, +{ +"PRIMARY_KEY_FIELD": 10134, +"SOME_CHAR": "134 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.668257887321, +"SOME_DATE": "23NOV1961", +"SOME_DATETIME": " 01JAN1960:12:09:29", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 24 +}, +{ +"PRIMARY_KEY_FIELD": 10135, +"SOME_CHAR": "135 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.673810465575, +"SOME_DATE": "21MAY1961", +"SOME_DATETIME": " 01JAN1960:08:17:36", +"SOME_TIME": " 0:01:25", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10136, +"SOME_CHAR": "136 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.610945592919, +"SOME_DATE": "20DEC1961", +"SOME_DATETIME": " 01JAN1960:06:15:06", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 62 +}, +{ +"PRIMARY_KEY_FIELD": 10137, +"SOME_CHAR": "137 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.903748751573, +"SOME_DATE": "13MAR1960", +"SOME_DATETIME": " 01JAN1960:01:34:57", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10138, +"SOME_CHAR": "138 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.807945651844, +"SOME_DATE": "04OCT1961", +"SOME_DATETIME": " 01JAN1960:11:45:56", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10139, +"SOME_CHAR": "139 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.383073866546, +"SOME_DATE": "06APR1960", +"SOME_DATETIME": " 01JAN1960:07:42:17", +"SOME_TIME": " 0:01:31", +"SOME_SHORTNUM": 35, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10140, +"SOME_CHAR": "140 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.56504530905, +"SOME_DATE": "20FEB1960", +"SOME_DATETIME": " 01JAN1960:00:07:16", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 79, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 10141, +"SOME_CHAR": "141 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.887459293887, +"SOME_DATE": "01MAR1962", +"SOME_DATETIME": " 01JAN1960:00:34:22", +"SOME_TIME": " 0:00:19", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10142, +"SOME_CHAR": "142 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.404861313945, +"SOME_DATE": "05FEB1961", +"SOME_DATETIME": " 01JAN1960:10:57:41", +"SOME_TIME": " 0:00:31", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10143, +"SOME_CHAR": "143 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.460108042443, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:10:35:18", +"SOME_TIME": " 0:00:13", +"SOME_SHORTNUM": 5, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 10144, +"SOME_CHAR": "144 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.809737510891, +"SOME_DATE": "26JAN1961", +"SOME_DATETIME": " 01JAN1960:08:06:34", +"SOME_TIME": " 0:00:40", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 51 +}, +{ +"PRIMARY_KEY_FIELD": 10145, +"SOME_CHAR": "145 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.993591509756, +"SOME_DATE": "15MAR1961", +"SOME_DATETIME": " 01JAN1960:12:49:53", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 64, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10146, +"SOME_CHAR": "146 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0452116918961, +"SOME_DATE": "28APR1960", +"SOME_DATETIME": " 01JAN1960:06:18:21", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10147, +"SOME_CHAR": "147 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.828117129779, +"SOME_DATE": "17SEP1960", +"SOME_DATETIME": " 01JAN1960:03:32:05", +"SOME_TIME": " 0:00:17", +"SOME_SHORTNUM": 62, +"SOME_BESTNUM": 66 +}, +{ +"PRIMARY_KEY_FIELD": 10148, +"SOME_CHAR": "148 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.108167296326, +"SOME_DATE": "27JUL1962", +"SOME_DATETIME": " 01JAN1960:07:27:20", +"SOME_TIME": " 0:00:50", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10149, +"SOME_CHAR": "149 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.380526406868, +"SOME_DATE": "14NOV1961", +"SOME_DATETIME": " 01JAN1960:00:53:41", +"SOME_TIME": " 0:01:26", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10150, +"SOME_CHAR": "150 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.755726019738, +"SOME_DATE": "09SEP1962", +"SOME_DATETIME": " 01JAN1960:05:18:45", +"SOME_TIME": " 0:00:32", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10151, +"SOME_CHAR": "151 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.144336483043, +"SOME_DATE": "05SEP1962", +"SOME_DATETIME": " 01JAN1960:02:58:32", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 60, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10152, +"SOME_CHAR": "152 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0478734295107, +"SOME_DATE": "14JUL1960", +"SOME_DATETIME": " 01JAN1960:05:46:43", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 31 +}, +{ +"PRIMARY_KEY_FIELD": 10153, +"SOME_CHAR": "153 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.99183906661, +"SOME_DATE": "26APR1962", +"SOME_DATETIME": " 01JAN1960:04:48:41", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 75 +}, +{ +"PRIMARY_KEY_FIELD": 10154, +"SOME_CHAR": "154 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.915963809898, +"SOME_DATE": "04SEP1960", +"SOME_DATETIME": " 01JAN1960:01:48:59", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 15 +}, +{ +"PRIMARY_KEY_FIELD": 10155, +"SOME_CHAR": "155 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.368240488865, +"SOME_DATE": "24JAN1962", +"SOME_DATETIME": " 01JAN1960:08:59:46", +"SOME_TIME": " 0:00:14", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 100 +}, +{ +"PRIMARY_KEY_FIELD": 10156, +"SOME_CHAR": "156 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.261119415174, +"SOME_DATE": "31DEC1961", +"SOME_DATETIME": " 01JAN1960:00:43:42", +"SOME_TIME": " 0:00:30", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10157, +"SOME_CHAR": "157 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.889038999513, +"SOME_DATE": "28NOV1960", +"SOME_DATETIME": " 01JAN1960:03:19:35", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10158, +"SOME_CHAR": "158 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.131941327887, +"SOME_DATE": "27AUG1961", +"SOME_DATETIME": " 01JAN1960:07:26:49", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10159, +"SOME_CHAR": "159 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.626175243233, +"SOME_DATE": "23JUN1960", +"SOME_DATETIME": " 01JAN1960:02:32:40", +"SOME_TIME": " 0:00:21", +"SOME_SHORTNUM": 48, +"SOME_BESTNUM": 61 +}, +{ +"PRIMARY_KEY_FIELD": 10160, +"SOME_CHAR": "160 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.570262782076, +"SOME_DATE": "27NOV1961", +"SOME_DATETIME": " 01JAN1960:12:11:27", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 1 +}, +{ +"PRIMARY_KEY_FIELD": 10161, +"SOME_CHAR": "161 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.85756031324, +"SOME_DATE": "28SEP1960", +"SOME_DATETIME": " 01JAN1960:13:40:34", +"SOME_TIME": " 0:00:27", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 10162, +"SOME_CHAR": "162 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.182688185099, +"SOME_DATE": "17FEB1960", +"SOME_DATETIME": " 01JAN1960:02:58:44", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10163, +"SOME_CHAR": "163 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.234210872666, +"SOME_DATE": "27APR1961", +"SOME_DATETIME": " 01JAN1960:02:55:22", +"SOME_TIME": " 0:01:28", +"SOME_SHORTNUM": 20, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10164, +"SOME_CHAR": "164 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.356953425965, +"SOME_DATE": "10JUN1960", +"SOME_DATETIME": " 01JAN1960:10:48:35", +"SOME_TIME": " 0:00:54", +"SOME_SHORTNUM": 32, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10165, +"SOME_CHAR": "165 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.913664674812, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:10:33:26", +"SOME_TIME": " 0:01:10", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 6 +}, +{ +"PRIMARY_KEY_FIELD": 10166, +"SOME_CHAR": "166 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.999055517837, +"SOME_DATE": "29MAR1962", +"SOME_DATETIME": " 01JAN1960:11:58:00", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 36 +}, +{ +"PRIMARY_KEY_FIELD": 10167, +"SOME_CHAR": "167 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.522591932454, +"SOME_DATE": "03MAR1960", +"SOME_DATETIME": " 01JAN1960:13:08:34", +"SOME_TIME": " 0:01:17", +"SOME_SHORTNUM": 73, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10168, +"SOME_CHAR": "168 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.376125323761, +"SOME_DATE": "31MAR1961", +"SOME_DATETIME": " 01JAN1960:02:55:13", +"SOME_TIME": " 0:01:19", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 41 +}, +{ +"PRIMARY_KEY_FIELD": 10169, +"SOME_CHAR": "169 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.326772676467, +"SOME_DATE": "19JUN1962", +"SOME_DATETIME": " 01JAN1960:11:57:02", +"SOME_TIME": " 0:00:33", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10170, +"SOME_CHAR": "170 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.782820686597, +"SOME_DATE": "07AUG1961", +"SOME_DATETIME": " 01JAN1960:09:55:03", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 96, +"SOME_BESTNUM": 19 +}, +{ +"PRIMARY_KEY_FIELD": 10171, +"SOME_CHAR": "171 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.863840596221, +"SOME_DATE": "18JAN1961", +"SOME_DATETIME": " 01JAN1960:04:31:08", +"SOME_TIME": " 0:01:12", +"SOME_SHORTNUM": 97, +"SOME_BESTNUM": 52 +}, +{ +"PRIMARY_KEY_FIELD": 10172, +"SOME_CHAR": "172 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.789710712987, +"SOME_DATE": "01OCT1960", +"SOME_DATETIME": " 01JAN1960:11:06:53", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 77 +}, +{ +"PRIMARY_KEY_FIELD": 10173, +"SOME_CHAR": "173 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.802511338518, +"SOME_DATE": "21MAY1960", +"SOME_DATETIME": " 01JAN1960:06:53:54", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 24, +"SOME_BESTNUM": 52 +}, +{ +"PRIMARY_KEY_FIELD": 10174, +"SOME_CHAR": "174 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.753009963666, +"SOME_DATE": "26JAN1961", +"SOME_DATETIME": " 01JAN1960:07:06:38", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 10, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 10175, +"SOME_CHAR": "175 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.716320670543, +"SOME_DATE": "15AUG1962", +"SOME_DATETIME": " 01JAN1960:04:48:32", +"SOME_TIME": " 0:01:15", +"SOME_SHORTNUM": 80, +"SOME_BESTNUM": 50 +}, +{ +"PRIMARY_KEY_FIELD": 10176, +"SOME_CHAR": "176 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.791488602195, +"SOME_DATE": "26MAY1960", +"SOME_DATETIME": " 01JAN1960:12:09:38", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 4, +"SOME_BESTNUM": 35 +}, +{ +"PRIMARY_KEY_FIELD": 10177, +"SOME_CHAR": "177 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0925364206045, +"SOME_DATE": "18APR1960", +"SOME_DATETIME": " 01JAN1960:01:35:06", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 99 +}, +{ +"PRIMARY_KEY_FIELD": 10178, +"SOME_CHAR": "178 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.117532277069, +"SOME_DATE": "21SEP1961", +"SOME_DATETIME": " 01JAN1960:05:49:58", +"SOME_TIME": " 0:00:30", +"SOME_SHORTNUM": 9, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10179, +"SOME_CHAR": "179 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.768050647233, +"SOME_DATE": "25APR1961", +"SOME_DATETIME": " 01JAN1960:04:38:18", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 40 +}, +{ +"PRIMARY_KEY_FIELD": 10180, +"SOME_CHAR": "180 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.726473274979, +"SOME_DATE": "04JAN1960", +"SOME_DATETIME": " 01JAN1960:00:11:32", +"SOME_TIME": " 0:01:38", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 63 +}, +{ +"PRIMARY_KEY_FIELD": 10181, +"SOME_CHAR": "181 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.611879586527, +"SOME_DATE": "15MAR1962", +"SOME_DATETIME": " 01JAN1960:04:18:35", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 74, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 10182, +"SOME_CHAR": "182 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.378131004226, +"SOME_DATE": "05AUG1962", +"SOME_DATETIME": " 01JAN1960:04:46:05", +"SOME_TIME": " 0:00:45", +"SOME_SHORTNUM": 40, +"SOME_BESTNUM": 70 +}, +{ +"PRIMARY_KEY_FIELD": 10183, +"SOME_CHAR": "183 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.772194760745, +"SOME_DATE": "29NOV1960", +"SOME_DATETIME": " 01JAN1960:05:09:32", +"SOME_TIME": " 0:00:47", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 13 +}, +{ +"PRIMARY_KEY_FIELD": 10184, +"SOME_CHAR": "184 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0812941533892, +"SOME_DATE": "28JUN1961", +"SOME_DATETIME": " 01JAN1960:11:39:08", +"SOME_TIME": " 0:01:13", +"SOME_SHORTNUM": 69, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10185, +"SOME_CHAR": "185 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.312568983209, +"SOME_DATE": "27FEB1962", +"SOME_DATETIME": " 01JAN1960:11:13:19", +"SOME_TIME": " 0:01:19", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 81 +}, +{ +"PRIMARY_KEY_FIELD": 10186, +"SOME_CHAR": "186 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.17449143863, +"SOME_DATE": "03MAR1962", +"SOME_DATETIME": " 01JAN1960:13:34:59", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 75, +"SOME_BESTNUM": 11 +}, +{ +"PRIMARY_KEY_FIELD": 10187, +"SOME_CHAR": "187 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.967759952865, +"SOME_DATE": "14OCT1960", +"SOME_DATETIME": " 01JAN1960:13:48:30", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10188, +"SOME_CHAR": "188 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.891128778407, +"SOME_DATE": "05MAR1960", +"SOME_DATETIME": " 01JAN1960:05:28:49", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 7 +}, +{ +"PRIMARY_KEY_FIELD": 10189, +"SOME_CHAR": "189 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0667286301342, +"SOME_DATE": "17MAR1960", +"SOME_DATETIME": " 01JAN1960:07:56:56", +"SOME_TIME": " 0:00:10", +"SOME_SHORTNUM": 62, +"SOME_BESTNUM": 87 +}, +{ +"PRIMARY_KEY_FIELD": 10190, +"SOME_CHAR": "190 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.940826008069, +"SOME_DATE": "27MAY1960", +"SOME_DATETIME": " 01JAN1960:11:42:13", +"SOME_TIME": " 0:00:34", +"SOME_SHORTNUM": 45, +"SOME_BESTNUM": 53 +}, +{ +"PRIMARY_KEY_FIELD": 10191, +"SOME_CHAR": "191 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.310336881462, +"SOME_DATE": "16APR1962", +"SOME_DATETIME": " 01JAN1960:08:35:10", +"SOME_TIME": " 0:00:16", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 17 +}, +{ +"PRIMARY_KEY_FIELD": 10192, +"SOME_CHAR": "192 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.187635322654, +"SOME_DATE": "03DEC1960", +"SOME_DATETIME": " 01JAN1960:11:15:21", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 83 +}, +{ +"PRIMARY_KEY_FIELD": 10193, +"SOME_CHAR": "193 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.962409494427, +"SOME_DATE": "18OCT1960", +"SOME_DATETIME": " 01JAN1960:04:17:51", +"SOME_TIME": " 0:00:49", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10194, +"SOME_CHAR": "194 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.818376173181, +"SOME_DATE": "23FEB1961", +"SOME_DATETIME": " 01JAN1960:11:08:28", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 39, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10195, +"SOME_CHAR": "195 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.249898561393, +"SOME_DATE": "01NOV1961", +"SOME_DATETIME": " 01JAN1960:04:15:44", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10196, +"SOME_CHAR": "196 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.303004053097, +"SOME_DATE": "24JAN1961", +"SOME_DATETIME": " 01JAN1960:06:32:50", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 49 +}, +{ +"PRIMARY_KEY_FIELD": 10197, +"SOME_CHAR": "197 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.724311870394, +"SOME_DATE": "10SEP1960", +"SOME_DATETIME": " 01JAN1960:09:12:28", +"SOME_TIME": " 0:00:08", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 61 +}, +{ +"PRIMARY_KEY_FIELD": 10198, +"SOME_CHAR": "198 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.281540174634, +"SOME_DATE": "17SEP1962", +"SOME_DATETIME": " 01JAN1960:01:33:10", +"SOME_TIME": " 0:00:35", +"SOME_SHORTNUM": 70, +"SOME_BESTNUM": 58 +}, +{ +"PRIMARY_KEY_FIELD": 10199, +"SOME_CHAR": "199 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.919220488015, +"SOME_DATE": "08MAY1960", +"SOME_DATETIME": " 01JAN1960:09:33:28", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 54, +"SOME_BESTNUM": 0 +}, +{ +"PRIMARY_KEY_FIELD": 10200, +"SOME_CHAR": "200 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.505939372585, +"SOME_DATE": "17APR1960", +"SOME_DATETIME": " 01JAN1960:05:14:10", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 83, +"SOME_BESTNUM": 97 +}, +{ +"PRIMARY_KEY_FIELD": 10201, +"SOME_CHAR": "201 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.143907736123, +"SOME_DATE": "04AUG1962", +"SOME_DATETIME": " 01JAN1960:04:44:27", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 26, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10202, +"SOME_CHAR": "202 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.221468285295, +"SOME_DATE": "02SEP1961", +"SOME_DATETIME": " 01JAN1960:06:49:19", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 49, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10203, +"SOME_CHAR": "203 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.258218495761, +"SOME_DATE": "25OCT1961", +"SOME_DATETIME": " 01JAN1960:09:37:09", +"SOME_TIME": " 0:00:01", +"SOME_SHORTNUM": 6, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10204, +"SOME_CHAR": "204 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0766677759013, +"SOME_DATE": "11APR1961", +"SOME_DATETIME": " 01JAN1960:07:32:18", +"SOME_TIME": " 0:00:26", +"SOME_SHORTNUM": 99, +"SOME_BESTNUM": 30 +}, +{ +"PRIMARY_KEY_FIELD": 10205, +"SOME_CHAR": "205 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.993368008171, +"SOME_DATE": "25NOV1961", +"SOME_DATETIME": " 01JAN1960:04:29:28", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 11, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10206, +"SOME_CHAR": "206 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.872760605473, +"SOME_DATE": "30JUL1961", +"SOME_DATETIME": " 01JAN1960:07:00:29", +"SOME_TIME": " 0:01:20", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 10207, +"SOME_CHAR": "207 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.789409748646, +"SOME_DATE": "07JAN1960", +"SOME_DATETIME": " 01JAN1960:13:04:56", +"SOME_TIME": " 0:00:26", +"SOME_SHORTNUM": 63, +"SOME_BESTNUM": 27 +}, +{ +"PRIMARY_KEY_FIELD": 10208, +"SOME_CHAR": "208 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.34292900066, +"SOME_DATE": "15JAN1960", +"SOME_DATETIME": " 01JAN1960:08:44:18", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 82 +}, +{ +"PRIMARY_KEY_FIELD": 10209, +"SOME_CHAR": "209 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.853056217475, +"SOME_DATE": "20SEP1962", +"SOME_DATETIME": " 01JAN1960:00:37:31", +"SOME_TIME": " 0:01:26", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 14 +}, +{ +"PRIMARY_KEY_FIELD": 10210, +"SOME_CHAR": "210 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.1569773956, +"SOME_DATE": "17JUL1960", +"SOME_DATETIME": " 01JAN1960:12:40:44", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 91, +"SOME_BESTNUM": 4 +}, +{ +"PRIMARY_KEY_FIELD": 10211, +"SOME_CHAR": "211 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.28367675109, +"SOME_DATE": "25JUN1962", +"SOME_DATETIME": " 01JAN1960:03:47:07", +"SOME_TIME": " 0:00:42", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 59 +}, +{ +"PRIMARY_KEY_FIELD": 10212, +"SOME_CHAR": "212 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.319825820774, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:02:02:49", +"SOME_TIME": " 0:01:18", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 8 +}, +{ +"PRIMARY_KEY_FIELD": 10213, +"SOME_CHAR": "213 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.236386205645, +"SOME_DATE": "10OCT1961", +"SOME_DATETIME": " 01JAN1960:12:17:24", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 90, +"SOME_BESTNUM": 55 +}, +{ +"PRIMARY_KEY_FIELD": 10214, +"SOME_CHAR": "214 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.742101271051, +"SOME_DATE": "25JAN1960", +"SOME_DATETIME": " 01JAN1960:05:39:56", +"SOME_TIME": " 0:01:34", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 25 +}, +{ +"PRIMARY_KEY_FIELD": 10215, +"SOME_CHAR": "215 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.863742849726, +"SOME_DATE": "15MAR1960", +"SOME_DATETIME": " 01JAN1960:13:30:58", +"SOME_TIME": " 0:01:40", +"SOME_SHORTNUM": 86, +"SOME_BESTNUM": 85 +}, +{ +"PRIMARY_KEY_FIELD": 10216, +"SOME_CHAR": "216 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.750501612551, +"SOME_DATE": "29FEB1960", +"SOME_DATETIME": " 01JAN1960:12:48:41", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 20, +"SOME_BESTNUM": 42 +}, +{ +"PRIMARY_KEY_FIELD": 10217, +"SOME_CHAR": "217 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.665220306099, +"SOME_DATE": "21SEP1962", +"SOME_DATETIME": " 01JAN1960:11:47:48", +"SOME_TIME": " 0:00:11", +"SOME_SHORTNUM": 56, +"SOME_BESTNUM": 86 +}, +{ +"PRIMARY_KEY_FIELD": 10218, +"SOME_CHAR": "218 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.314111363755, +"SOME_DATE": "17OCT1961", +"SOME_DATETIME": " 01JAN1960:07:34:23", +"SOME_TIME": " 0:01:05", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10219, +"SOME_CHAR": "219 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.475602078007, +"SOME_DATE": "14MAY1961", +"SOME_DATETIME": " 01JAN1960:13:32:24", +"SOME_TIME": " 0:00:43", +"SOME_SHORTNUM": 95, +"SOME_BESTNUM": 39 +}, +{ +"PRIMARY_KEY_FIELD": 10220, +"SOME_CHAR": "220 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.292178807451, +"SOME_DATE": "14MAY1961", +"SOME_DATETIME": " 01JAN1960:03:16:05", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 34 +}, +{ +"PRIMARY_KEY_FIELD": 10221, +"SOME_CHAR": "221 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.342086964446, +"SOME_DATE": "21FEB1962", +"SOME_DATETIME": " 01JAN1960:13:35:14", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 28, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10222, +"SOME_CHAR": "222 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.361870947928, +"SOME_DATE": "18JAN1960", +"SOME_DATETIME": " 01JAN1960:09:45:01", +"SOME_TIME": " 0:00:36", +"SOME_SHORTNUM": 32, +"SOME_BESTNUM": 96 +}, +{ +"PRIMARY_KEY_FIELD": 10223, +"SOME_CHAR": "223 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.571696416741, +"SOME_DATE": "12SEP1960", +"SOME_DATETIME": " 01JAN1960:11:04:22", +"SOME_TIME": " 0:00:46", +"SOME_SHORTNUM": 25, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10224, +"SOME_CHAR": "224 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.819183359304, +"SOME_DATE": "22FEB1960", +"SOME_DATETIME": " 01JAN1960:00:11:18", +"SOME_TIME": " 0:00:48", +"SOME_SHORTNUM": 93, +"SOME_BESTNUM": 9 +}, +{ +"PRIMARY_KEY_FIELD": 10225, +"SOME_CHAR": "225 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0242283884549, +"SOME_DATE": "26MAR1960", +"SOME_DATETIME": " 01JAN1960:11:41:08", +"SOME_TIME": " 0:01:23", +"SOME_SHORTNUM": 16, +"SOME_BESTNUM": 80 +}, +{ +"PRIMARY_KEY_FIELD": 10226, +"SOME_CHAR": "226 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.418458293387, +"SOME_DATE": "29OCT1960", +"SOME_DATETIME": " 01JAN1960:06:51:07", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 21, +"SOME_BESTNUM": 94 +}, +{ +"PRIMARY_KEY_FIELD": 10227, +"SOME_CHAR": "227 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.855226562757, +"SOME_DATE": "26JAN1960", +"SOME_DATETIME": " 01JAN1960:01:22:42", +"SOME_TIME": " 0:00:39", +"SOME_SHORTNUM": 16, +"SOME_BESTNUM": 92 +}, +{ +"PRIMARY_KEY_FIELD": 10228, +"SOME_CHAR": "228 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.612432046613, +"SOME_DATE": "30JUL1960", +"SOME_DATETIME": " 01JAN1960:08:13:43", +"SOME_TIME": " 0:00:51", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 47 +}, +{ +"PRIMARY_KEY_FIELD": 10229, +"SOME_CHAR": "229 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.0565994717444, +"SOME_DATE": "14JUN1962", +"SOME_DATETIME": " 01JAN1960:12:06:18", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 89, +"SOME_BESTNUM": 43 +}, +{ +"PRIMARY_KEY_FIELD": 10230, +"SOME_CHAR": "230 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.234995038824, +"SOME_DATE": "05MAY1961", +"SOME_DATETIME": " 01JAN1960:01:11:48", +"SOME_TIME": " 0:01:02", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10231, +"SOME_CHAR": "231 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.905498261054, +"SOME_DATE": "04FEB1961", +"SOME_DATETIME": " 01JAN1960:01:50:23", +"SOME_TIME": " 0:01:29", +"SOME_SHORTNUM": 33, +"SOME_BESTNUM": 46 +}, +{ +"PRIMARY_KEY_FIELD": 10232, +"SOME_CHAR": "232 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.489890096006, +"SOME_DATE": "14JAN1962", +"SOME_DATETIME": " 01JAN1960:07:07:05", +"SOME_TIME": " 0:00:56", +"SOME_SHORTNUM": 51, +"SOME_BESTNUM": 95 +}, +{ +"PRIMARY_KEY_FIELD": 10233, +"SOME_CHAR": "233 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.458665252877, +"SOME_DATE": "06AUG1960", +"SOME_DATETIME": " 01JAN1960:12:28:55", +"SOME_TIME": " 0:01:09", +"SOME_SHORTNUM": 85, +"SOME_BESTNUM": 54 +}, +{ +"PRIMARY_KEY_FIELD": 10234, +"SOME_CHAR": "234 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.85541833977, +"SOME_DATE": "01OCT1961", +"SOME_DATETIME": " 01JAN1960:06:53:06", +"SOME_TIME": " 0:00:23", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 89 +}, +{ +"PRIMARY_KEY_FIELD": 10235, +"SOME_CHAR": "235 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.857599226226, +"SOME_DATE": "30OCT1961", +"SOME_DATETIME": " 01JAN1960:06:13:30", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 67, +"SOME_BESTNUM": 99 +}, +{ +"PRIMARY_KEY_FIELD": 10236, +"SOME_CHAR": "236 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.844420214111, +"SOME_DATE": "11APR1960", +"SOME_DATETIME": " 01JAN1960:00:27:45", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10237, +"SOME_CHAR": "237 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.474337428098, +"SOME_DATE": "13JAN1961", +"SOME_DATETIME": " 01JAN1960:06:48:00", +"SOME_TIME": " 0:00:58", +"SOME_SHORTNUM": 22, +"SOME_BESTNUM": 29 +}, +{ +"PRIMARY_KEY_FIELD": 10238, +"SOME_CHAR": "238 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.326561977773, +"SOME_DATE": "31MAY1961", +"SOME_DATETIME": " 01JAN1960:12:12:34", +"SOME_TIME": " 0:00:03", +"SOME_SHORTNUM": 94, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10239, +"SOME_CHAR": "239 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.921823682693, +"SOME_DATE": "13DEC1961", +"SOME_DATETIME": " 01JAN1960:01:20:43", +"SOME_TIME": " 0:01:11", +"SOME_SHORTNUM": 46, +"SOME_BESTNUM": 48 +}, +{ +"PRIMARY_KEY_FIELD": 10240, +"SOME_CHAR": "240 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.121250483264, +"SOME_DATE": "18DEC1960", +"SOME_DATETIME": " 01JAN1960:02:34:37", +"SOME_TIME": " 0:00:22", +"SOME_SHORTNUM": 2, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10241, +"SOME_CHAR": "241 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.949745169352, +"SOME_DATE": "07JUN1961", +"SOME_DATETIME": " 01JAN1960:06:48:37", +"SOME_TIME": " 0:00:34", +"SOME_SHORTNUM": 3, +"SOME_BESTNUM": 67 +}, +{ +"PRIMARY_KEY_FIELD": 10242, +"SOME_CHAR": "242 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.255982018661, +"SOME_DATE": "13MAR1962", +"SOME_DATETIME": " 01JAN1960:07:37:42", +"SOME_TIME": " 0:01:04", +"SOME_SHORTNUM": 76, +"SOME_BESTNUM": 70 +}, +{ +"PRIMARY_KEY_FIELD": 10243, +"SOME_CHAR": "243 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.759833389781, +"SOME_DATE": "28JUN1960", +"SOME_DATETIME": " 01JAN1960:08:19:49", +"SOME_TIME": " 0:01:01", +"SOME_SHORTNUM": 29, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10244, +"SOME_CHAR": "244 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.700597827183, +"SOME_DATE": "24JUL1960", +"SOME_DATETIME": " 01JAN1960:05:10:15", +"SOME_TIME": " 0:00:38", +"SOME_SHORTNUM": 53, +"SOME_BESTNUM": 10 +}, +{ +"PRIMARY_KEY_FIELD": 10245, +"SOME_CHAR": "245 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.221195794745, +"SOME_DATE": "05SEP1960", +"SOME_DATETIME": " 01JAN1960:08:59:36", +"SOME_TIME": " 0:01:07", +"SOME_SHORTNUM": 44, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10246, +"SOME_CHAR": "246 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.200741445739, +"SOME_DATE": "24MAR1960", +"SOME_DATETIME": " 01JAN1960:02:29:02", +"SOME_TIME": " 0:00:09", +"SOME_SHORTNUM": 37, +"SOME_BESTNUM": 88 +}, +{ +"PRIMARY_KEY_FIELD": 10247, +"SOME_CHAR": "247 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.287490293517, +"SOME_DATE": "24JUL1961", +"SOME_DATETIME": " 01JAN1960:02:55:57", +"SOME_TIME": " 0:00:57", +"SOME_SHORTNUM": 30, +"SOME_BESTNUM": 33 +}, +{ +"PRIMARY_KEY_FIELD": 10248, +"SOME_CHAR": "248 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.561167126783, +"SOME_DATE": "25JUN1960", +"SOME_DATETIME": " 01JAN1960:02:01:02", +"SOME_TIME": " 0:01:36", +"SOME_SHORTNUM": 49, +"SOME_BESTNUM": 90 +}, +{ +"PRIMARY_KEY_FIELD": 10249, +"SOME_CHAR": "249 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.349366858299, +"SOME_DATE": "28FEB1961", +"SOME_DATETIME": " 01JAN1960:04:26:52", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 81, +"SOME_BESTNUM": 25 +}, +{ +"PRIMARY_KEY_FIELD": 10250, +"SOME_CHAR": "250 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.253183987575, +"SOME_DATE": "04FEB1961", +"SOME_DATETIME": " 01JAN1960:03:37:40", +"SOME_TIME": " 0:01:33", +"SOME_SHORTNUM": 38, +"SOME_BESTNUM": 32 +}, +{ +"PRIMARY_KEY_FIELD": 10251, +"SOME_CHAR": "251 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.747167228603, +"SOME_DATE": "14APR1960", +"SOME_DATETIME": " 01JAN1960:10:00:45", +"SOME_TIME": " 0:01:35", +"SOME_SHORTNUM": 12, +"SOME_BESTNUM": 91 +}, +{ +"PRIMARY_KEY_FIELD": 10252, +"SOME_CHAR": "252 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.27761360038, +"SOME_DATE": "13SEP1961", +"SOME_DATETIME": " 01JAN1960:09:09:05", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 43, +"SOME_BESTNUM": 56 +}, +{ +"PRIMARY_KEY_FIELD": 10253, +"SOME_CHAR": "253 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.10966447094, +"SOME_DATE": "04APR1962", +"SOME_DATETIME": " 01JAN1960:00:26:22", +"SOME_TIME": " 0:01:22", +"SOME_SHORTNUM": 47, +"SOME_BESTNUM": 71 +}, +{ +"PRIMARY_KEY_FIELD": 10254, +"SOME_CHAR": "254 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.205800468198, +"SOME_DATE": "30MAY1961", +"SOME_DATETIME": " 01JAN1960:13:20:29", +"SOME_TIME": " 0:00:52", +"SOME_SHORTNUM": 84, +"SOME_BESTNUM": 12 +}, +{ +"PRIMARY_KEY_FIELD": 10255, +"SOME_CHAR": "255 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.253791187077, +"SOME_DATE": "12JUN1961", +"SOME_DATETIME": " 01JAN1960:05:43:23", +"SOME_TIME": " 0:00:24", +"SOME_SHORTNUM": 50, +"SOME_BESTNUM": 93 +}, +{ +"PRIMARY_KEY_FIELD": 10256, +"SOME_CHAR": "256 bottles of beer on the wall", +"SOME_DROPDOWN": "Option 1", +"SOME_NUM": 0.916653747632, +"SOME_DATE": "06DEC1960", +"SOME_DATETIME": " 01JAN1960:09:22:08", +"SOME_TIME": " 0:01:32", +"SOME_SHORTNUM": 65, +"SOME_BESTNUM": 18 +} +] +, "$viewdata":{"vars":{ +"PRIMARY_KEY_FIELD" :{"format":"best." ,"label":"PRIMARY_KEY_FIELD" ,"length":"8" ,"type":"num" } +,"SOME_CHAR" :{"format":"$32767." ,"label":"SOME_CHAR" ,"length":"32767" ,"type":"char" } +,"SOME_DROPDOWN" :{"format":"$128." ,"label":"SOME_DROPDOWN" ,"length":"128" ,"type":"char" } +,"SOME_NUM" :{"format":"best." ,"label":"SOME_NUM" ,"length":"8" ,"type":"num" } +,"SOME_DATE" :{"format":"DATE9." ,"label":"SOME_DATE" ,"length":"8" ,"type":"num" } +,"SOME_DATETIME" :{"format":"DATETIME19." ,"label":"SOME_DATETIME" ,"length":"8" ,"type":"num" } +,"SOME_TIME" :{"format":"TIME8." ,"label":"SOME_TIME" ,"length":"8" ,"type":"num" } +,"SOME_SHORTNUM" :{"format":"best." ,"label":"SOME_SHORTNUM" ,"length":"4" ,"type":"num" } +,"SOME_BESTNUM" :{"format":"BEST." ,"label":"SOME_BESTNUM" ,"length":"8" ,"type":"num" } +}} +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewdata" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057BBE1CAC140BA860000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:49.746000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/viewlibs.js b/sas/mocks/sasjs/services/public/viewlibs.js new file mode 100644 index 0000000..e8fdf0a --- /dev/null +++ b/sas/mocks/sasjs/services/public/viewlibs.js @@ -0,0 +1,34 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "saslibs": +[ +{ +"LIBRARYID": "A59LNVZG.B500000K", +"LIBRARYNAME": "Data Controller(DC996664)", +"LIBRARYREF": "DC996664", +"ENGINE": "BASE" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewlibs" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057B8E6D91740B9650000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:36.451000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/public/viewtables.js b/sas/mocks/sasjs/services/public/viewtables.js new file mode 100644 index 0000000..14d4edd --- /dev/null +++ b/sas/mocks/sasjs/services/public/viewtables.js @@ -0,0 +1,35 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:48" +, "mptables": +[ +{ +"MEMNAME": "MPE_X_TEST" +} +] +, "libinfo": +[ + +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/public/viewtables" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057BAACBC6A40B9E70000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:48:43.748000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/usernav/usergroupsbymember.js b/sas/mocks/sasjs/services/usernav/usergroupsbymember.js new file mode 100644 index 0000000..0975a7a --- /dev/null +++ b/sas/mocks/sasjs/services/usernav/usergroupsbymember.js @@ -0,0 +1,29 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:48" +, "groups": +[ +{"GROUPNAME":"AllUsers" ,"GROUPDESC":"Group contains all users" ,"URI":1 } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/sasdemo/services/usernav/usergroupsbymember" +,"AUTOEXEC" : "%2Fhome%2Fsasdemo%2Fsasjs_root%2Fsessions%2F20221006144844-38321-1665067724415%2Fautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B8933732F40000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717969" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "sasdemo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:49:17.028492" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/usernav/usermembers.js b/sas/mocks/sasjs/services/usernav/usermembers.js new file mode 100644 index 0000000..72fa2d9 --- /dev/null +++ b/sas/mocks/sasjs/services/usernav/usermembers.js @@ -0,0 +1,30 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:47" +, "users": +[ +{"URI":"1" ,"NAME":"sasdemo" ,"DISPLAYNAME":"Super Admin" ,"ISADMIN":1 } +,{"URI":"2" ,"NAME":"secretuser" ,"DISPLAYNAME":"Super Admin" ,"ISADMIN":1 } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/sasdemo/services/usernav/usermembers" +,"AUTOEXEC" : "%2Fhome%2Fsasdemo%2Fsasjs_root%2Fsessions%2F20221006144758-81942-1665067678253%2Fautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B887B444240000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717923" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "sasdemo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:48:50.472250" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/usernav/usermembersbygroup.js b/sas/mocks/sasjs/services/usernav/usermembersbygroup.js new file mode 100644 index 0000000..bc9dfd0 --- /dev/null +++ b/sas/mocks/sasjs/services/usernav/usermembersbygroup.js @@ -0,0 +1,30 @@ +_webout = `{"SYSDATE" : "06OCT22" +,"SYSTIME" : "14:46" +, "sasmembers": +[ +{"DISPLAYNAME":"Super Admin" ,"ID":1 ,"ISADMIN":1 ,"USERNAME":"sasdemo" } +,{"DISPLAYNAME":"Super Admin" ,"ID":2 ,"ISADMIN":1 ,"USERNAME":"secretuser" } +] +,"_DEBUG" : "" +,"_PROGRAM" : "/30.SASApps/app/sasdemo/services/usernav/usermembersbygroup" +,"AUTOEXEC" : "%2Fhome%2Fsasdemo%2Fsasjs_root%2Fsessions%2F20221006144618-97395-1665067578326%2Fautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "utf-8" +,"SYSERRORTEXT" : "" +,"SYSHOSTINFOLONG" : "" +,"SYSHOSTNAME" : "sas.4gl.io" +,"SYSPROCESSID" : "41DD83B86EF4A74C0000000000000000" +,"SYSPROCESSMODE" : "Stored Program" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "717900" +,"SYSSCPL" : "LINUX" +,"syssite" : "123" +,"SYSTCPIPHOSTNAME" : "https://sas.4gl.io:5002" +,"SYSUSERID" : "sasdemo" +,"SYSVLONG" : "05.00.00.02.001146" +,"SYSWARNINGTEXT" : "" +,"END_DTTM" : "2022-10-06T14:48:11.167868" +,"MEMSIZE" : "0KB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/usernav/usermembersbyrole.js b/sas/mocks/sasjs/services/usernav/usermembersbyrole.js new file mode 100644 index 0000000..1ed1952 --- /dev/null +++ b/sas/mocks/sasjs/services/usernav/usermembersbyrole.js @@ -0,0 +1,47 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "sasgroups": +[ +{ +"URIMEM": "OMSOBJ:IdentityGroup\A59LNVZG.A5000002", +"MEMBERNAME": "PUBLIC", +"MEMBERTYPE": "UserGroup", +"MEMBERUPDATED": "19Aug2020:06:21:05", +"MEMBERCREATED": "19Aug2020:06:21:05", +"EMAIL": "" +} +] +, "sasmembers": +[ +{ +"URIMEM": "OMSOBJ:Person\A59LNVZG.AP000003", +"MEMBERNAME": "sasdemo", +"MEMBERTYPE": "User", +"MEMBERUPDATED": "19Aug2020:06:22:00", +"MEMBERCREATED": "19Aug2020:06:22:00", +"EMAIL": "" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/usermembersbyrole" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057E21AB02140C3090000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:20.946000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/mocks/sasjs/services/usernav/userroles.js b/sas/mocks/sasjs/services/usernav/userroles.js new file mode 100644 index 0000000..afc8037 --- /dev/null +++ b/sas/mocks/sasjs/services/usernav/userroles.js @@ -0,0 +1,258 @@ +_webout = `{"SYSDATE" : "26SEP22" +,"SYSTIME" : "08:51" +, "roles": +[ +{ +"ROLEURI": "A59LNVZG.A5000009", +"ROLENAME": "Add-In for Microsoft Office: Advanced", +"ROLEDESC": "Provides all capabilities in the SAS Add-In for Microsoft Office." +}, +{ +"ROLEURI": "A59LNVZG.A500000A", +"ROLENAME": "Add-In for Microsoft Office: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000B", +"ROLENAME": "Add-In for Microsoft Office: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in PivotTables and provides other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001E", +"ROLENAME": "BI Dashboard: Administration", +"ROLEDESC": "Provides SAS BI Dashboard administration capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000K", +"ROLENAME": "Comments: Administrator", +"ROLEDESC": "" +}, +{ +"ROLEURI": "A59LNVZG.A5000010", +"ROLENAME": "Data Management: Lineage", +"ROLEDESC": "Provides default access to the SAS Lineage application." +}, +{ +"ROLEURI": "A59LNVZG.A500001H", +"ROLENAME": "Decision Manager Common: Administration", +"ROLEDESC": "Decision Manager Common Administrative role" +}, +{ +"ROLEURI": "A59LNVZG.A500000C", +"ROLENAME": "Enterprise Guide: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Enterprise Guide." +}, +{ +"ROLEURI": "A59LNVZG.A500000D", +"ROLENAME": "Enterprise Guide: Analysis", +"ROLEDESC": "Provides basic data analysis, reporting, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000E", +"ROLENAME": "Enterprise Guide: OLAP", +"ROLEDESC": "Supports viewing OLAP cubes in the OLAP Analyzer and provides other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000F", +"ROLENAME": "Enterprise Guide: Programming", +"ROLEDESC": "Provides SAS programming, stored process authoring, and other capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A5000020", +"ROLENAME": "Factory Miner: Admin", +"ROLEDESC": "Provides Factory Miner Admin capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001Z", +"ROLENAME": "Factory Miner: User", +"ROLEDESC": "Provides Factory Miner User capabilities to create projects and run models." +}, +{ +"ROLEURI": "A59LNVZG.A500000S", +"ROLENAME": "Fonts Administrator", +"ROLEDESC": "Font Administrator can reload fonts to update the fonts metadata." +}, +{ +"ROLEURI": "A59LNVZG.A500001L", +"ROLENAME": "Forecast Server: Administrator", +"ROLEDESC": "Provides capabilities for a Forecasting Administrator." +}, +{ +"ROLEURI": "A59LNVZG.A500001J", +"ROLENAME": "Forecast Server: Analyst", +"ROLEDESC": "Provides capabiliites for a Forecasting Analyst." +}, +{ +"ROLEURI": "A59LNVZG.A500001I", +"ROLENAME": "Forecast Server: Browser", +"ROLEDESC": "Provides basic forecasting viewing and reporting capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001K", +"ROLENAME": "Forecast Server: Forecaster", +"ROLEDESC": "Provides capabilities for a Forecaster." +}, +{ +"ROLEURI": "A59LNVZG.A5000011", +"ROLENAME": "Home: Administration", +"ROLEDESC": "Provides all capabilities for the home page (hub)." +}, +{ +"ROLEURI": "A59LNVZG.A5000012", +"ROLENAME": "Home: Usage", +"ROLEDESC": "Provides all non-administrative capabilities for the home page (hub)." +}, +{ +"ROLEURI": "A59LNVZG.A500000L", +"ROLENAME": "Job Execution: Job Administrator", +"ROLEDESC": "Provides all capabilities for the Job Execution Service, a component of the Web Infra Platform Services." +}, +{ +"ROLEURI": "A59LNVZG.A500000N", +"ROLENAME": "Job Execution: Job Designer", +"ROLEDESC": "Provides job and task definition capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000O", +"ROLENAME": "Job Execution: Job Scheduler", +"ROLEDESC": "Provides job scheduling capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000M", +"ROLENAME": "Job Execution: Job Submitter", +"ROLEDESC": "Provides normal job submission capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500000Z", +"ROLENAME": "Lineage: Administration", +"ROLEDESC": "Provides all functionality related to administrative activities for the SAS Lineage application." +}, +{ +"ROLEURI": "A59LNVZG.A5000006", +"ROLENAME": "META: Operators Role", +"ROLEDESC": "Supports adding repositories and operating the metadata server [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A5000004", +"ROLENAME": "META: Unrestricted Users Role", +"ROLEDESC": "Provides all capabilities in SAS Management Console and provides access to all metadata [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A5000005", +"ROLENAME": "META: User and Group Administrators Role", +"ROLEDESC": "Supports management of users, groups, and roles other than the unrestricted role [implicit]." +}, +{ +"ROLEURI": "A59LNVZG.A500000G", +"ROLENAME": "Management Console: Advanced", +"ROLEDESC": "Provides access to all plug-ins in SAS Management Console." +}, +{ +"ROLEURI": "A59LNVZG.A500000H", +"ROLENAME": "Management Console: Content Management", +"ROLEDESC": "Provides access to the Folders tab, User Manager, Library Manager, and Authorization Manager." +}, +{ +"ROLEURI": "A59LNVZG.A500001N", +"ROLENAME": "SAS Studio: Report Consumer", +"ROLEDESC": "Provides access to view or run existing SAS Studio reports without general access to SAS programming environment." +}, +{ +"ROLEURI": "A59LNVZG.A500001M", +"ROLENAME": "SAS Studio: Usage", +"ROLEDESC": "Provides access to the SAS programming environment." +}, +{ +"ROLEURI": "A59LNVZG.A500000R", +"ROLENAME": "Theme Designer: Administration", +"ROLEDESC": "Provides Theme Designer administration capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001X", +"ROLENAME": "Time Series Studio: Administrator", +"ROLEDESC": "Enables administrator access to the product and features, including access to all product content regardless of ownership." +}, +{ +"ROLEURI": "A59LNVZG.A500001Y", +"ROLENAME": "Time Series Studio: User", +"ROLEDESC": "Enables normal user access to the product and features." +}, +{ +"ROLEURI": "A59LNVZG.A5000017", +"ROLENAME": "Visual Analytics: Administration", +"ROLEDESC": "Provides administrative capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A5000015", +"ROLENAME": "Visual Analytics: Analysis", +"ROLEDESC": "If SAS Visual Statistics is licensed, provides the Build Analytical Model capability." +}, +{ +"ROLEURI": "A59LNVZG.A5000018", +"ROLENAME": "Visual Analytics: Basic", +"ROLEDESC": "Provides functionality for guest access (if applicable) and entry-level users." +}, +{ +"ROLEURI": "A59LNVZG.A5000016", +"ROLENAME": "Visual Analytics: Data Building", +"ROLEDESC": "Provides data preparation capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A5000014", +"ROLENAME": "Visual Analytics: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities in the Visual Analytics suite." +}, +{ +"ROLEURI": "A59LNVZG.A500001B", +"ROLENAME": "Web Report Studio: Advanced", +"ROLEDESC": "Provides all capabilities in SAS Web Report Studio except the manage report distribution capability." +}, +{ +"ROLEURI": "A59LNVZG.A500001A", +"ROLENAME": "Web Report Studio: Report Creation", +"ROLEDESC": "Provides report creation capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A5000019", +"ROLENAME": "Web Report Studio: Report Viewing", +"ROLEDESC": "Provides report viewing capabilities." +}, +{ +"ROLEURI": "A59LNVZG.A500001R", +"ROLENAME": "mdlmgradminusage", +"ROLEDESC": "Provides ability to perform all Model Manager tasks" +}, +{ +"ROLEURI": "A59LNVZG.A500001S", +"ROLENAME": "mdlmgradvusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for administrative tasks" +}, +{ +"ROLEURI": "A59LNVZG.A500001T", +"ROLENAME": "mdlmgrusage", +"ROLEDESC": "Provides the ability to perform all SAS Model Manager tasks, except for advanced or administrative tasks" +} +] +,"_DEBUG" : "" +,"_METAUSER": "sasdemo@SAS" +,"_METAPERSON": "sasdemo" +,"_PROGRAM" : "/Projects/app/dc/services/usernav/userroles" +,"AUTOEXEC" : "D%3A%5Copt%5Csasinside%5CConfig%5CLev1%5CSASApp%5CStoredProcessServer%5Cautoexec.sas" +,"MF_GETUSER" : "sasdemo" +,"SYSCC" : "0" +,"SYSENCODING" : "wlatin1" +,"SYSERRORTEXT" : "" +,"SYSHOSTNAME" : "SAS" +,"SYSPROCESSID" : "41DD8057DF99CAC140C2300000000000" +,"SYSPROCESSMODE" : "SAS Stored Process Server" +,"SYSPROCESSNAME" : "" +,"SYSJOBID" : "27448" +,"SYSSCPL" : "Linunx" +,"SYSSITE" : "123" +,"SYSUSERID" : "sassrv" +,"SYSVLONG" : "9.04.01M7P080520" +,"SYSWARNINGTEXT" : "ENCODING option ignored for files opened with RECFM=N." +,"END_DTTM" : "2022-09-26T08:51:10.892000" +,"MEMSIZE" : "46GB" +} +` \ No newline at end of file diff --git a/sas/package-lock.json b/sas/package-lock.json new file mode 100644 index 0000000..5aeb31e --- /dev/null +++ b/sas/package-lock.json @@ -0,0 +1,3203 @@ +{ + "name": "dc-sas", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "dc-sas", + "dependencies": { + "@sasjs/cli": "4.3.0", + "@sasjs/core": "^4.46.3" + } + }, + "node_modules/@coolaj86/urequest": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@coolaj86/urequest/-/urequest-1.3.7.tgz", + "integrity": "sha512-PPrVYra9aWvZjSCKl/x1pJ9ZpXda1652oJrPBYy5rQumJJMkmTBN3ux+sK2xAUwVvv2wnewDlaQaHLxLwSHnIA==" + }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@sasjs/adapter": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.4.tgz", + "integrity": "sha512-hPLNPXqunbIXZY+rsRxwfiLehk8x9a0IG2/96geJqrgP4Xi705X2WqkTaCpJ+Lr9gFGk4PttdprokCl1yoHVNw==", + "hasInstallScript": true, + "dependencies": { + "@sasjs/utils": "2.52.0", + "axios": "0.27.2", + "axios-cookiejar-support": "1.0.1", + "form-data": "4.0.0", + "https": "1.0.0", + "tough-cookie": "4.0.0" + } + }, + "node_modules/@sasjs/adapter/node_modules/@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "hasInstallScript": true, + "dependencies": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "node_modules/@sasjs/adapter/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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/@sasjs/cli": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.3.0.tgz", + "integrity": "sha512-LDObBUigusiBvq7SzkL49W5zel2YfjcmetdrftEnEdpWeVkVYYby77gJiW9iXdhrdVT+Hgrdubs6tA+RT0LskA==", + "hasInstallScript": true, + "dependencies": { + "@sasjs/adapter": "4.3.4", + "@sasjs/core": "4.45.4", + "@sasjs/lint": "2.3.0", + "@sasjs/utils": "3.3.0", + "adm-zip": "0.5.9", + "chalk": "4.1.2", + "dotenv": "10.0.0", + "esm": "3.2.25", + "find": "0.3.0", + "js-base64": "3.7.2", + "jsdom": "21.1.0", + "jwt-decode": "3.1.2", + "lodash.groupby": "4.6.0", + "lodash.uniqby": "4.7.0", + "node-graphviz": "0.1.1", + "node-powershell": "5.0.1", + "ora": "5.4.1", + "rimraf": "3.0.2", + "shelljs": "0.8.5", + "ssl-root-cas": "1.3.1", + "xml": "1.0.1", + "yargs": "17.6.2" + }, + "bin": { + "sasjs": "build/index.js" + } + }, + "node_modules/@sasjs/cli/node_modules/@sasjs/core": { + "version": "4.45.4", + "resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.45.4.tgz", + "integrity": "sha512-zf0foZHXNUb7hTHQAbGcQbHhiwX7qNK9g3PTT5XkjR8aDgcYeBpSxu1bEj7GTVvOmv49YF/3xrVZNh5J+38+DA==" + }, + "node_modules/@sasjs/core": { + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.46.3.tgz", + "integrity": "sha512-Grwydm5GxBsYk238PZw41XPjXVVQ9vWcvfZ06L2P0bQbvK0sGn7l69JA7H5MGr3QcaLpiD4Kg70cAh7PgE+JOw==" + }, + "node_modules/@sasjs/lint": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/lint/-/lint-2.3.0.tgz", + "integrity": "sha512-ac3l4RUf3+87tmi2VCebibxQNIdiyzJuRGErka/BKXu+F4pBhUG1Y8t0lNISLDk6fm5uJXHpYrR5zck8J5tCtQ==", + "hasInstallScript": true, + "dependencies": { + "@sasjs/utils": "2.52.0", + "ignore": "5.2.4" + } + }, + "node_modules/@sasjs/lint/node_modules/@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "hasInstallScript": true, + "dependencies": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "node_modules/@sasjs/lint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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/@sasjs/utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-3.3.0.tgz", + "integrity": "sha512-ZJ+c2d/rEoF340Ay3TZrXO4c2ain7AvSzkRuKG2H2qxwIlQQTk/9Rbknmy0mo3Y/QRScBYl0Fw5xSZ8SMHjljg==", + "hasInstallScript": true, + "dependencies": { + "@fast-csv/format": "4.3.5", + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "node_modules/@sasjs/utils/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" + }, + "node_modules/@types/prompts": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.13.tgz", + "integrity": "sha512-jwMOIGy49VruR/gYehhJYgpVzB+EVpEE7t7j9m1oTo4HMpOe7KmsyqdBuoxAzA5B4caUgx0cKrWr7wUEqMXJ7Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "peer": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "node_modules/accumulate-stream": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/accumulate-stream/-/accumulate-stream-5.0.0.tgz", + "integrity": "sha512-a1pAtAy+LFCAQ6EpAwDeHERf99nadIXa8UApaddabeF18IsL8cD67WL67E/cRJf4EkZyR9z4F+9g+OCl3Cqi4w==", + "dependencies": { + "bytes": "^3.1.0", + "ms": "^2.1.3" + } + }, + "node_modules/accumulate-stream/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "dependencies": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@types/tough-cookie": ">=2.3.3", + "axios": ">=0.16.2", + "tough-cookie": ">=2.3.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "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==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/child-shell": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/child-shell/-/child-shell-5.0.0.tgz", + "integrity": "sha512-mNki2AmChI8IQM+MQlbh1/+wuqWtosqMrWRv3+RVY19M2IX0cOlGCfaC6DXRgqwnLASsFsZcvUhSJoOVc12mHQ==", + "dependencies": { + "accumulate-stream": "^5.0.0", + "debug": "^4.3.2", + "kind-of": "^6.0.3", + "nanoid": "^3.1.30", + "p-queue": "6.6.2", + "p-timeout": "4.1.0", + "trim-buffer": "^5.0.0" + } + }, + "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==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", + "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "dependencies": { + "colors": "1.0.3" + }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==" + }, + "node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "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==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/consola": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.0.tgz", + "integrity": "sha512-vlcSGgdYS26mPf7qNi+dCisbhiyDnrN1zaRbw3CSuc2wGOMEGGPsp46PdRG5gqXwgtJfjxDkxRNAgRPr1B77vQ==" + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "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==" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "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==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/find": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "dependencies": { + "traverse-chain": "~0.1.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "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/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==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "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-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "node_modules/jsdom": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.0.tgz", + "integrity": "sha512-m0lzlP7qOtthD918nenK3hdItSd2I+V3W9IrBcB36sqDwG+KnUs66IF5GY7laGWUnlM9vTsD0W1QwSEBYWWcJg==", + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsdom/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.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==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-graphviz": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/node-graphviz/-/node-graphviz-0.1.1.tgz", + "integrity": "sha512-riY8/pFGSD1ipmyzqCwuN2M6W02ELfuLDjhJvTrQCUS/15tyU8ExkC96mlQrNLBK8Ws0z8PdH+ChBT6DuPFWWA==" + }, + "node_modules/node-powershell": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/node-powershell/-/node-powershell-5.0.1.tgz", + "integrity": "sha512-3Dcr0jTmwS9vGMTBgVmmGSTNw9byWT4djNYQF4BqI54DAX0GiW5oPPUPgChLimoIG0Eu0QgkUFSMq+xtT5xUsQ==", + "dependencies": { + "child-shell": "^5.0.0", + "is-wsl": "^2.2.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.6.tgz", + "integrity": "sha512-vSZ4miHQ4FojLjmz2+ux4B0/XA16jfwt/LBzIUftDpRd8tujHFkXjMyLwjS08fIZCzesj2z7gJukOKJwqebJAQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", + "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "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==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssl-root-cas": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ssl-root-cas/-/ssl-root-cas-1.3.1.tgz", + "integrity": "sha512-KR8J210Wfvjh+iNE9jcQEgbG0VG2713PHreItx6aNCPnkFO8XChz1cJ4iuCGeBj0+8wukLmgHgJqX+O5kRjPkQ==", + "dependencies": { + "@coolaj86/urequest": "^1.3.6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/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==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==" + }, + "node_modules/trim-buffer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/trim-buffer/-/trim-buffer-5.0.0.tgz", + "integrity": "sha512-PqdsRmhir3lUwraK/O6sdZ9QcmtUK0c6F1utX/WNquJsL4Jpdck+DSe9Mqy8Wk7uAQD/SlVn6cyGF5bj6VF33Q==" + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@coolaj86/urequest": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@coolaj86/urequest/-/urequest-1.3.7.tgz", + "integrity": "sha512-PPrVYra9aWvZjSCKl/x1pJ9ZpXda1652oJrPBYy5rQumJJMkmTBN3ux+sK2xAUwVvv2wnewDlaQaHLxLwSHnIA==" + }, + "@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "requires": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "@sasjs/adapter": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.4.tgz", + "integrity": "sha512-hPLNPXqunbIXZY+rsRxwfiLehk8x9a0IG2/96geJqrgP4Xi705X2WqkTaCpJ+Lr9gFGk4PttdprokCl1yoHVNw==", + "requires": { + "@sasjs/utils": "2.52.0", + "axios": "0.27.2", + "axios-cookiejar-support": "1.0.1", + "form-data": "4.0.0", + "https": "1.0.0", + "tough-cookie": "4.0.0" + }, + "dependencies": { + "@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "requires": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@sasjs/cli": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.3.0.tgz", + "integrity": "sha512-LDObBUigusiBvq7SzkL49W5zel2YfjcmetdrftEnEdpWeVkVYYby77gJiW9iXdhrdVT+Hgrdubs6tA+RT0LskA==", + "requires": { + "@sasjs/adapter": "4.3.4", + "@sasjs/core": "4.45.4", + "@sasjs/lint": "2.3.0", + "@sasjs/utils": "3.3.0", + "adm-zip": "0.5.9", + "chalk": "4.1.2", + "dotenv": "10.0.0", + "esm": "3.2.25", + "find": "0.3.0", + "js-base64": "3.7.2", + "jsdom": "21.1.0", + "jwt-decode": "3.1.2", + "lodash.groupby": "4.6.0", + "lodash.uniqby": "4.7.0", + "node-graphviz": "0.1.1", + "node-powershell": "5.0.1", + "ora": "5.4.1", + "rimraf": "3.0.2", + "shelljs": "0.8.5", + "ssl-root-cas": "1.3.1", + "xml": "1.0.1", + "yargs": "17.6.2" + }, + "dependencies": { + "@sasjs/core": { + "version": "4.45.4", + "resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.45.4.tgz", + "integrity": "sha512-zf0foZHXNUb7hTHQAbGcQbHhiwX7qNK9g3PTT5XkjR8aDgcYeBpSxu1bEj7GTVvOmv49YF/3xrVZNh5J+38+DA==" + } + } + }, + "@sasjs/core": { + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.46.3.tgz", + "integrity": "sha512-Grwydm5GxBsYk238PZw41XPjXVVQ9vWcvfZ06L2P0bQbvK0sGn7l69JA7H5MGr3QcaLpiD4Kg70cAh7PgE+JOw==" + }, + "@sasjs/lint": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/lint/-/lint-2.3.0.tgz", + "integrity": "sha512-ac3l4RUf3+87tmi2VCebibxQNIdiyzJuRGErka/BKXu+F4pBhUG1Y8t0lNISLDk6fm5uJXHpYrR5zck8J5tCtQ==", + "requires": { + "@sasjs/utils": "2.52.0", + "ignore": "5.2.4" + }, + "dependencies": { + "@sasjs/utils": { + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.52.0.tgz", + "integrity": "sha512-UbmYCdfCvjRpmoKRnbmKEcE2YZJh9zHjjGyuZ5BIDxThDtOsGZUOiZrW1J7WcrzjAwQiRBzYoV7xF5MiZqtgiQ==", + "requires": { + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "csv-stringify": "5.6.5", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@sasjs/utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-3.3.0.tgz", + "integrity": "sha512-ZJ+c2d/rEoF340Ay3TZrXO4c2ain7AvSzkRuKG2H2qxwIlQQTk/9Rbknmy0mo3Y/QRScBYl0Fw5xSZ8SMHjljg==", + "requires": { + "@fast-csv/format": "4.3.5", + "@types/fs-extra": "9.0.13", + "@types/prompts": "2.0.13", + "chalk": "4.1.1", + "cli-table": "0.3.6", + "consola": "2.15.0", + "find": "0.3.0", + "fs-extra": "10.0.0", + "jwt-decode": "3.1.2", + "prompts": "2.4.1", + "rimraf": "3.0.2", + "valid-url": "1.0.9" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.18.53", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" + }, + "@types/prompts": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.13.tgz", + "integrity": "sha512-jwMOIGy49VruR/gYehhJYgpVzB+EVpEE7t7j9m1oTo4HMpOe7KmsyqdBuoxAzA5B4caUgx0cKrWr7wUEqMXJ7Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "peer": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "accumulate-stream": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/accumulate-stream/-/accumulate-stream-5.0.0.tgz", + "integrity": "sha512-a1pAtAy+LFCAQ6EpAwDeHERf99nadIXa8UApaddabeF18IsL8cD67WL67E/cRJf4EkZyR9z4F+9g+OCl3Cqi4w==", + "requires": { + "bytes": "^3.1.0", + "ms": "^2.1.3" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" + }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "requires": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "child-shell": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/child-shell/-/child-shell-5.0.0.tgz", + "integrity": "sha512-mNki2AmChI8IQM+MQlbh1/+wuqWtosqMrWRv3+RVY19M2IX0cOlGCfaC6DXRgqwnLASsFsZcvUhSJoOVc12mHQ==", + "requires": { + "accumulate-stream": "^5.0.0", + "debug": "^4.3.2", + "kind-of": "^6.0.3", + "nanoid": "^3.1.30", + "p-queue": "6.6.2", + "p-timeout": "4.1.0", + "trim-buffer": "^5.0.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==" + }, + "cli-table": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.6.tgz", + "integrity": "sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==", + "requires": { + "colors": "1.0.3" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "consola": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.0.tgz", + "integrity": "sha512-vlcSGgdYS26mPf7qNi+dCisbhiyDnrN1zaRbw3CSuc2wGOMEGGPsp46PdRG5gqXwgtJfjxDkxRNAgRPr1B77vQ==" + }, + "cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==" + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "requires": { + "webidl-conversions": "^7.0.0" + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "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==" + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + } + }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "find": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "requires": { + "traverse-chain": "~0.1.0" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "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==" + }, + "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==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "jsdom": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.0.tgz", + "integrity": "sha512-m0lzlP7qOtthD918nenK3hdItSd2I+V3W9IrBcB36sqDwG+KnUs66IF5GY7laGWUnlM9vTsD0W1QwSEBYWWcJg==", + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + } + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, + "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==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==" + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + }, + "node-graphviz": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/node-graphviz/-/node-graphviz-0.1.1.tgz", + "integrity": "sha512-riY8/pFGSD1ipmyzqCwuN2M6W02ELfuLDjhJvTrQCUS/15tyU8ExkC96mlQrNLBK8Ws0z8PdH+ChBT6DuPFWWA==" + }, + "node-powershell": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/node-powershell/-/node-powershell-5.0.1.tgz", + "integrity": "sha512-3Dcr0jTmwS9vGMTBgVmmGSTNw9byWT4djNYQF4BqI54DAX0GiW5oPPUPgChLimoIG0Eu0QgkUFSMq+xtT5xUsQ==", + "requires": { + "child-shell": "^5.0.0", + "is-wsl": "^2.2.0" + } + }, + "nwsapi": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.6.tgz", + "integrity": "sha512-vSZ4miHQ4FojLjmz2+ux4B0/XA16jfwt/LBzIUftDpRd8tujHFkXjMyLwjS08fIZCzesj2z7gJukOKJwqebJAQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" + }, + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "requires": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "dependencies": { + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "requires": { + "p-finally": "^1.0.0" + } + } + } + }, + "p-timeout": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", + "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==" + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" + }, + "prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "ssl-root-cas": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ssl-root-cas/-/ssl-root-cas-1.3.1.tgz", + "integrity": "sha512-KR8J210Wfvjh+iNE9jcQEgbG0VG2713PHreItx6aNCPnkFO8XChz1cJ4iuCGeBj0+8wukLmgHgJqX+O5kRjPkQ==", + "requires": { + "@coolaj86/urequest": "^1.3.6" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "dependencies": { + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==" + }, + "trim-buffer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/trim-buffer/-/trim-buffer-5.0.0.tgz", + "integrity": "sha512-PqdsRmhir3lUwraK/O6sdZ9QcmtUK0c6F1utX/WNquJsL4Jpdck+DSe9Mqy8Wk7uAQD/SlVn6cyGF5bj6VF33Q==" + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} + }, + "xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } +} diff --git a/sas/package.json b/sas/package.json new file mode 100644 index 0000000..cfb98ab --- /dev/null +++ b/sas/package.json @@ -0,0 +1,33 @@ +{ + "name": "dc-sas", + "description": "dc-sas", + "scripts": { + "cpfavicon": "cp sasjs/utils/favicon.ico ../client/dist/favicon.ico", + "build": "cd ../client && npm run build", + "deploy:server": "rsync -avhe ssh ../client/dist/* --delete allbow@sas.4gl.io:/opt/sas/sas9/config/Lev1/Web/WebServer/htdocs/allbow/server", + "sas9": "rsync -avhe ssh ./dist/* --delete ${npm_config_account}@sas.4gl.io:/opt/sas/sas9/config/Lev1/Web/WebServer/htdocs/${npm_config_account}/dc", + "sas9cbd": "npm run sas9a && npm run sas9b && npm run sas9c && npm run sas9d && npm run sas9e && npm run sas9f && npm run sas9g", + "sas9a": "./sasjs/utils/delete_metafolder.sh", + "sas9b": "sasjs cbd -t sas9", + "sas9c": "sasjs request services/admin/buildtermsas9 -t sas9 ", + "sas9d": "./sasjs/utils/export_spk.sh", + "sas9e": "sasjs request services/admin/makedata -d deploy/makeDataSas9.json -t sas9 ", + "sas9f": "sasjs request services/admin/refreshtablelineage -t sas9 ", + "sas9g": "sasjs request services/admin/refreshcatalog -t sas9", + "4gl": "npm run cpfavicon && sasjs cbd -t 4gl && sasjs request services/admin/makedata -d deploy/makeData4GL.json -l sasjsresults/makedata_4gl.log -o sasjsresults/makedata_4gl.json -t 4gl", + "server": "npm run cpfavicon && sasjs cbd -t server && npm run serverdata", + "server-mihajlo": "npm run cpfavicon && sasjs cbd -t server-mihajlo && npm run serverdata-mihajlo", + "serverdata-mihajlo": "sasjs request services/admin/makedata -d deploy/makeDataServer.json -l sasjsresults/makedata_server.log -o sasjsresults/makedata_server.json -t server-mihajlo", + "serverdata": "sasjs request services/admin/makedata -d deploy/makeDataServer.json -l sasjsresults/makedata_server.log -o sasjsresults/makedata_server.json -t server", + "viya": "npm run viyacbd && sasjs test", + "viyacbd": "sasjs folder delete /Public/app/viya && sasjs cbd -t viya && npm run viyadata", + "viyadata": "sasjs request services/admin/makedata -d deploy/makeDataViya.json -l sasjsresults/makedata.log -o sasjsresults/output.json", + "v4data": "sasjs request services/admin/makedata -d deploy/makeDataV4.json -l sasjsresults/makedatav4.log -o sasjsresults/outputv4.json -t v4", + "sasdocs": "sasjs doc && ./sasjs/utils/deploydocs.sh" + }, + "private": true, + "dependencies": { + "@sasjs/cli": "4.3.0", + "@sasjs/core": "^4.46.3" + } +} diff --git a/sas/sasjs/.sasjslint b/sas/sasjs/.sasjslint new file mode 100644 index 0000000..15a6260 --- /dev/null +++ b/sas/sasjs/.sasjslint @@ -0,0 +1,13 @@ +{ + "noEncodedPasswords": true, + "hasDoxygenHeader": true, + "hasMacroNameInMend": true, + "hasMacroParentheses": true, + "indentationMultiple": 2, + "lowerCaseFileNames": true, + "maxLineLength": 107, + "noNestedMacros": true, + "noSpacesInFileNames": true, + "noTabIndentation": true, + "noTrailingSpaces": true +} \ No newline at end of file diff --git a/sas/sasjs/binaryfiles/dcsquare.png b/sas/sasjs/binaryfiles/dcsquare.png new file mode 100644 index 0000000..753e218 Binary files /dev/null and b/sas/sasjs/binaryfiles/dcsquare.png differ diff --git a/sas/sasjs/db/datactrl/mpe_audit.ddl b/sas/sasjs/db/datactrl/mpe_audit.ddl new file mode 100644 index 0000000..13a2da2 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_audit.ddl @@ -0,0 +1,32 @@ +/** + @file + @brief DDL for MPE_AUDIT + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_audit( + load_ref char(36) label='unique load reference', + processed_dttm num format=E8601DT26.6 label='Processed at timestamp', + libref char(8) label='Library Reference (8 chars)', + dsn char(32) label='Dataset Name (32 chars)', + key_hash char(32) label= + 'MD5 Hash of primary key values (pipe seperated)', + move_type char(1) label='Either (A)ppended, (D)eleted or (M)odified', + is_pk num label='Is Primary Key Field? (1/0)', + is_diff num label= + 'Did value change? (1/0/-1). Always -1 for appends and deletes.', + tgtvar_type char(1) label='Either (C)haracter or (N)umeric', + tgtvar_nm char(32) label='Target variable name (32 chars)', + oldval_num num format=best32. label='Old (numeric) value', + newval_num num format=best32. label='New (numeric) value', + oldval_char char(32765) label='Old (character) value', + newval_char char(32765) label='New (character) value', + constraint pk_mpe_audit + primary key(load_ref,libref,dsn,key_hash,tgtvar_nm) +); diff --git a/sas/sasjs/db/datactrl/mpe_config.ddl b/sas/sasjs/db/datactrl/mpe_config.ddl new file mode 100644 index 0000000..f320511 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_config.ddl @@ -0,0 +1,20 @@ +/** + @file + @brief Provides configuration by scope, name & value + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_config( + tx_from num not null format=datetime19.3 + ,tx_to num not null format=datetime19.3 + ,var_scope varchar(10) not null + ,var_name varchar(32) not null + ,var_value varchar(5000) + ,var_active num + ,var_desc varchar(300) + ,constraint pk_mpe_config + primary key(tx_from, var_scope, var_name)); diff --git a/sas/sasjs/db/datactrl/mpe_datacatalog_libs.ddl b/sas/sasjs/db/datactrl/mpe_datacatalog_libs.ddl new file mode 100644 index 0000000..20171b5 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datacatalog_libs.ddl @@ -0,0 +1,23 @@ +/** + @file mpe_datacatalog_libs.ddl + @brief ddl file + @details + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_datacatalog_libs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Ref', + engine char(32) label='Library Engine', + libname char(256) format=$256. label='Library Name', + paths char(8192) label='Library Paths', + perms char(500) label='Library Permissions (if BASE)', + owners char(500) label='Library Owners (if BASE)', + schemas char(500) label='Library Schemas (if DB)', + libid char(17) label='LibraryId', + constraint pk_mpe_datacatalog_libs + primary key(libref,tx_to)); diff --git a/sas/sasjs/db/datactrl/mpe_datacatalog_tabs.ddl b/sas/sasjs/db/datactrl/mpe_datacatalog_tabs.ddl new file mode 100644 index 0000000..7d5763b --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datacatalog_tabs.ddl @@ -0,0 +1,24 @@ +/** + @file mpe_datacatalog_TABS.ddl + @brief ddl file + @details + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_datacatalog_TABS( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + memtype char(8) label='Member Type', + dbms_memtype char(32) label='DBMS Member Type', + memlabel char(512) label='Data Set Label', + typemem char(8) label='Data Set Type', + nvar num label='Number of Variables', + compress char(8) label='Compression Routine', + pk_fields char(512) label='Primary Key Fields (identified by being in a constraint that is both Unique and Not Null)', + constraint pk_mpe_datacatalog_TABS + primary key(libref,dsn,tx_to)); diff --git a/sas/sasjs/db/datactrl/mpe_datacatalog_vars.ddl b/sas/sasjs/db/datactrl/mpe_datacatalog_vars.ddl new file mode 100644 index 0000000..c43f5c0 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datacatalog_vars.ddl @@ -0,0 +1,27 @@ +/** + @file + @brief DDL for MPE_DATACATALOG_VARS + @details + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_datacatalog_vars( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Table Name', + memtype char(8) label='Member Type', + name char(64) label='Column Name', + type char(16) label='Column Type', + length num label='Column Length', + varnum num label='Column Number in Table', + label char(512) label='Column Label', + format char(49) label='Column Format', + idxusage char(9) label='Column Index Type', + notnull char(3) label='Not NULL?', + pk_ind num label="Primary Key Indicator (1=Primary Key field)", + constraint pk_mpe_datacatalog_vars + primary key(libref,dsn,name,tx_to)); diff --git a/sas/sasjs/db/datactrl/mpe_datadictionary.ddl b/sas/sasjs/db/datactrl/mpe_datadictionary.ddl new file mode 100644 index 0000000..9f9fe3d --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datadictionary.ddl @@ -0,0 +1,69 @@ +/** + @file mpe_datadictionary.ddl + @brief ddl file + @details + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + + +create table &curlib..mpe_datadictionary + ( + TX_FROM float format=datetime19., + DD_TYPE char(16), + DD_SOURCE char(1024), + DD_SHORTDESC char(256), + DD_LONGDESC char(32767), + DD_OWNER char(128), + DD_RESPONSIBLE char(128), + DD_SENSITIVITY char(64), + TX_TO float not null format=datetime19., + constraint pk_mpe_datadictionary + primary key(tx_from, dd_type,dd_source)); + +insert into &syslast set + tx_from=0 + ,DD_TYPE='LIBRARY' + ,DD_SOURCE="&mpelib" + ,DD_SHORTDESC="Data Controller Control Tables" + ,DD_LONGDESC="# The Data Controller Library" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,DD_TYPE='TABLE' + ,DD_SOURCE="&mpelib..MPE_TABLES" + ,DD_SHORTDESC="Configuration of new tables for Data Controller" + ,DD_LONGDESC="# MPE_TABLES - adding new tabels to Data Controller" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,DD_TYPE='COLUMN' + ,DD_SOURCE="&mpelib..MPE_TABLES.DSN" + ,DD_SHORTDESC="Dataset Name to be edited" + ,DD_LONGDESC="_DSN_ - must be UPCASE" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,DD_TYPE='DIRECTORY' + ,DD_SOURCE="/some/directory" + ,DD_SHORTDESC="Directory for some purpose" + ,DD_LONGDESC="This directory is great. It's great directory. It trumps all other directories." + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; diff --git a/sas/sasjs/db/datactrl/mpe_dataloads.ddl b/sas/sasjs/db/datactrl/mpe_dataloads.ddl new file mode 100644 index 0000000..ed02813 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_dataloads.ddl @@ -0,0 +1,26 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_dataloads( + libref varchar(8) not null, + dsn varchar(32) not null, + etlsource varchar(100) not null, + loadtype varchar(20) not null, + changed_records int, + new_records int, + deleted_records int, + duration num, + user_nm varchar(50) not null, + processed_dttm num format=datetime19.3, + mac_ver varchar(5), + constraint pk_mpe_dataloads + primary key(processed_dttm, libref,dsn,etlsource)); diff --git a/sas/sasjs/db/datactrl/mpe_datastatus_libs.ddl b/sas/sasjs/db/datactrl/mpe_datastatus_libs.ddl new file mode 100644 index 0000000..b4516dc --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datastatus_libs.ddl @@ -0,0 +1,18 @@ +/** + @file mpe_datastatus_libs.ddl + @brief ddl file + @details + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_datastatus_libs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + libsize num format=SIZEKMG. label='Size of file', + table_cnt num label='Number of Tables', + constraint pk_mpe_datastatus_libs + primary key(libref,tx_to)); diff --git a/sas/sasjs/db/datactrl/mpe_datastatus_tabs.ddl b/sas/sasjs/db/datactrl/mpe_datastatus_tabs.ddl new file mode 100644 index 0000000..af99604 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_datastatus_tabs.ddl @@ -0,0 +1,21 @@ +/** + @file mpe_datastatus_tabs.ddl + @brief ddl file + @details + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_datastatus_tabs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + filesize num format=SIZEKMG. label='Size of file', + crdate num format=DATETIME. informat=DATETIME. label='Date Created', + modate num format=DATETIME. informat=DATETIME. label='Date Modified', + nobs num label='Number of Physical (Actual, inc. deleted) Observations', + constraint pk_mpe_datastatus_tabs + primary key(libref,dsn,tx_to)); diff --git a/sas/sasjs/db/datactrl/mpe_excel_config.ddl b/sas/sasjs/db/datactrl/mpe_excel_config.ddl new file mode 100644 index 0000000..8375f4b --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_excel_config.ddl @@ -0,0 +1,19 @@ +/** + @file + @brief DDL for MPE_EXCEL_CONFIG (pk: tx_from,xl_libref,xl_table,xl_column) + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_excel_config( + tx_from num, + xl_libref char(8), + xl_table char(32), + xl_column char(32), + xl_rule char(32), + xl_active num, + tx_to num not null, + constraint pk_mpe_excel_config + primary key(tx_from,xl_libref,xl_table,xl_column)); diff --git a/sas/sasjs/db/datactrl/mpe_filteranytable.ddl b/sas/sasjs/db/datactrl/mpe_filteranytable.ddl new file mode 100644 index 0000000..4e8c6fb --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_filteranytable.ddl @@ -0,0 +1,18 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd +**/ + +create table &curlib..mpe_filteranytable( + filter_rk num not null, + filter_hash char(32) not null, + filter_table char(41) not null, + processed_dttm num not null format=datetime19., + constraint pk_mpe_filteranytable + primary key(filter_rk)); + diff --git a/sas/sasjs/db/datactrl/mpe_filtersource.ddl b/sas/sasjs/db/datactrl/mpe_filtersource.ddl new file mode 100644 index 0000000..ed83f1f --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_filtersource.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd +**/ + +create table &curlib..mpe_filtersource( + filter_hash char(32) not null, + filter_line num not null, + group_logic char(3) not null, + subgroup_logic char(3) not null, + subgroup_id num not null, + variable_nm varchar(32) not null, + operator_nm varchar(12) not null, + raw_value varchar(4000) not null, + processed_dttm num not null format=datetime19., + constraint pk_mpe_filteranytable + primary key(filter_hash,filter_line)); diff --git a/sas/sasjs/db/datactrl/mpe_groups.ddl b/sas/sasjs/db/datactrl/mpe_groups.ddl new file mode 100644 index 0000000..e0dd8e4 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_groups.ddl @@ -0,0 +1,17 @@ +/** + @file + @brief DDL for MPE_GROUPS (pk: tx_from,group_name,user_name) + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +create table &curlib..mpe_groups( + tx_from num not null, + group_name char(100) not null, + group_desc char(256), + user_name char(50) not null, + tx_to num not null, + constraint pk_mpe_groups + primary key(tx_from,group_name,user_name)); diff --git a/sas/sasjs/db/datactrl/mpe_lineage_cols.ddl b/sas/sasjs/db/datactrl/mpe_lineage_cols.ddl new file mode 100644 index 0000000..f2f492b --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_lineage_cols.ddl @@ -0,0 +1,34 @@ +/** + @file mpe_lineage_cols.ddl + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_lineage_cols + ( + col_id char(32), + direction char(1), + jobname char(256), + sourcetablename char(256), + sourcecolname char(256), + sourcecoluri char(256), + map_type char(256), + map_transform char(256), + targettablename char(256), + targetcolname char(256), + targetcoluri char(256), + Derived_Rule char(500), + level int, + modified_dttm float, + modified_by char(64), + constraint pk_mpe_lineage_cols primary key + ( + col_id,direction,sourcecoluri,targetcoluri,map_type,map_transform + ) + ); diff --git a/sas/sasjs/db/datactrl/mpe_lineage_tabs.ddl b/sas/sasjs/db/datactrl/mpe_lineage_tabs.ddl new file mode 100644 index 0000000..3905a6e --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_lineage_tabs.ddl @@ -0,0 +1,31 @@ +/** + @file mpe_lineage_tabs.ddl + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..MPE_LINEAGE_TABS + ( + tx_from num not null, + jobid char(17), + jobname char(128), + srctableid char(17), + srctabletype char(16), + srctablename char(64), + srclibref char(8), + tgttableid char(17), + tgttabletype char(16), + tgttablename char(64), + tgtlibref char(8), + tx_to num not null, + constraint pk_MPE_LINEAGE_TABS primary key + ( + tx_to,jobid,srctableid,tgttableid + ) + ); diff --git a/sas/sasjs/db/datactrl/mpe_loads.ddl b/sas/sasjs/db/datactrl/mpe_loads.ddl new file mode 100644 index 0000000..a17ebdc --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_loads.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_loads( + csv_dir char(255), + user_nm char(50) , + status char(15) , + duration num , + processed_dttm num format=datetime19.3, + reason_txt char(2048) , + approvals char(64), + constraint pk_mpe_loads + primary key(csv_dir)); diff --git a/sas/sasjs/db/datactrl/mpe_lockanytable.ddl b/sas/sasjs/db/datactrl/mpe_lockanytable.ddl new file mode 100644 index 0000000..807048a --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_lockanytable.ddl @@ -0,0 +1,23 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_lockanytable( + lock_status_cd varchar(10) not null, + lock_lib varchar(8) not null , + lock_ds varchar(32) not null, + lock_user_nm varchar(100) not null , + lock_ref varchar(200), + lock_pid varchar(10), + lock_start_dttm num format=datetime19.3, + lock_end_dttm num format=datetime19.3, + constraint pk_mpe_lockanytable + primary key(lock_lib,lock_ds)); diff --git a/sas/sasjs/db/datactrl/mpe_maxkeyvalues.ddl b/sas/sasjs/db/datactrl/mpe_maxkeyvalues.ddl new file mode 100644 index 0000000..b75261b --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_maxkeyvalues.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_maxkeyvalues( + keytable varchar(41) label='Base table in libref.dataset format', + keycolumn char(32) format=$32. + label='The Surrogate / Retained key field containing the key values.', + max_key num label= + 'Integer value representing current max RK or SK value in the KEYTABLE', + processed_dttm num format=E8601DT26.6 + label='Datetime this value was last updated', + constraint pk_mpe_maxkeyvalues + primary key(keytable)); diff --git a/sas/sasjs/db/datactrl/mpe_review.ddl b/sas/sasjs/db/datactrl/mpe_review.ddl new file mode 100644 index 0000000..a7d20b9 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_review.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_review( + table_id varchar(32) not null, + base_table varchar(41) not null, + review_status_id varchar(10) not null, + reviewed_by_nm varchar(100) not null, + reviewed_on_dttm date not null, + review_reason_txt varchar(400), + constraint pk_mpe_review + primary key(table_id, reviewed_by_nm)); + diff --git a/sas/sasjs/db/datactrl/mpe_security.ddl b/sas/sasjs/db/datactrl/mpe_security.ddl new file mode 100644 index 0000000..f661e81 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_security.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + + +proc sql; +create table &curlib..mpe_security( + tx_from num not null, + libref char(8) not null, + dsn char(32) not null, + access_level char(10) not null, + sas_group char(100) not null, + tx_to num not null, + constraint pk_mpe_security + primary key(libref,dsn,access_level,sas_group,tx_from)); diff --git a/sas/sasjs/db/datactrl/mpe_selectbox.ddl b/sas/sasjs/db/datactrl/mpe_selectbox.ddl new file mode 100644 index 0000000..a1d2c26 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_selectbox.ddl @@ -0,0 +1,118 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_selectbox( + selectbox_rk int not null, /* surrogate key */ + ver_from_dttm num not null, /* timestamp for versioning */ + select_lib varchar(17) not null, /* libref (big enough for uri)*/ + select_ds varchar(32) not null, + base_column varchar(36) not null, /* variable name against which to apply selectbox */ + selectbox_value varchar(500) not null, /* selectbox value */ + selectbox_order int , /* optional ordering (1 comes before 2) */ + selectbox_type varchar(32) , /* column type (blank for default, else + sas or js to indicate relevant system functions*/ + ver_to_dttm num not null /* timestamp for versioning */ + ); + +create unique index pk_mpe_selectbox on &syslast(ver_from_dttm, selectbox_rk); + +insert into &syslast set + selectbox_rk=1 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_LOCKANYTABLE" + ,base_column="LOCK_STATUS_CD" + ,selectbox_value='LOCKED' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=2 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_LOCKANYTABLE" + ,base_column="LOCK_STATUS_CD" + ,selectbox_value='UNLOCKED' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=3 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='EDIT' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=4 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='APPROVE' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=5 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='SIGNOFF' + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=6 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='UPDATE' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=7 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='REPLACE' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=8 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='TXTEMPORAL' + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=9 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='BITEMPORAL' + ,selectbox_order=4 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &syslast set + selectbox_rk=10 + ,ver_from_dttm=0 + ,select_lib="&mpelib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='FORMAT_CAT' + ,selectbox_order=5 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + diff --git a/sas/sasjs/db/datactrl/mpe_signoffs.ddl b/sas/sasjs/db/datactrl/mpe_signoffs.ddl new file mode 100644 index 0000000..cb89861 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_signoffs.ddl @@ -0,0 +1,22 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_signoffs( + tech_from_dttm num not null, + signoff_table varchar(50) not null, + signoff_section_rk num not null, + signoff_version_rk num not null, + signoff_name varchar(100) not null, + tech_to_dttm num not null, + constraint pk_mpe_signoffs + primary key(tech_from_dttm, signoff_table, signoff_section_rk)); + diff --git a/sas/sasjs/db/datactrl/mpe_submit.ddl b/sas/sasjs/db/datactrl/mpe_submit.ddl new file mode 100644 index 0000000..7f3b345 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_submit.ddl @@ -0,0 +1,29 @@ +/** + @file + @brief ddl file + @details Captures the submit process lifecycle + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_submit( + table_id varchar(32) not null, + submit_status_cd varchar(10) not null, + base_lib char(8) not null, + base_ds char(32) not null, + submitted_by_nm varchar(100) not null, + submitted_on_dttm num not null format=datetime19.2, + submitted_reason_txt varchar(400), + input_obs num, + input_vars num, + num_of_approvals_required num not null, + num_of_approvals_remaining num not null, + reviewed_by_nm char(100), + reviewed_on_dttm num, + constraint pk_mpe_submit + primary key(table_id) +); + diff --git a/sas/sasjs/db/datactrl/mpe_tables.ddl b/sas/sasjs/db/datactrl/mpe_tables.ddl new file mode 100644 index 0000000..1da535d --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_tables.ddl @@ -0,0 +1,120 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_tables( + tx_from num not null format=datetime19.3, + tx_to num not null format=datetime19.3, + libref char(8) not null, + dsn char(32) not null, + num_of_approvals_required int, + loadtype char(12) , + buskey char(1000) , + var_txfrom char(32) , + var_txto char(32) , + var_busfrom char(32) , + var_busto char(32) , + var_processed char(32) , + close_vars varchar(500), + pre_edit_hook char(200), + post_edit_hook char(200), + pre_approve_hook char(200) , + post_approve_hook char(200) , + signoff_cols varchar(500), + signoff_hook varchar(200), + notes char(1000) , + rk_underlying char(1000) , + audit_libds char(41), + constraint pk_mpe_tables + primary key(tx_from, libref, dsn)); + +insert into &syslast + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_LOCKANYTABLE' + ,num_of_approvals_required=1 + ,loadtype='UPDATE' + ,buskey='LOCK_LIB LOCK_DS' + ,notes='Should not normally be edited, means a process failed and was left hung' + ; + +insert into &syslast + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_TABLES' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='LIBREF DSN' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,notes='This entry allows the MP Editor to edit itself!' + ; +insert into &syslast + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_SECURITY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='LIBREF DSN ACCESS_LEVEL SAS_GROUP' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,notes='Shows which metadata groups can edit which tables' + ; +insert into &syslast + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_SELECTBOX' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='SELECTBOX_RK' + ,var_txfrom='VER_FROM_DTTM' + ,var_txto='VER_TO_DTTM' + ,notes='Can configure dropdowns for the front end' + ,rk_underlying='SELECT_LIB SELECT_DS BASE_COLUMN SELECTBOX_VALUE' + ; +insert into &mpelib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_X_TEST' + ,num_of_approvals_required=1 + ,loadtype='UPDATE' + ,buskey='PRIMARY_KEY_FIELD' + ,notes='Test table for controller' + ; + insert into &mpelib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_VALIDATIONS' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='BASE_LIB BASE_DS BASE_COL RULE_TYPE' + ,notes='Configuration of data quality rules in Editor component' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &mpelib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&mpelib" + ,dsn='MPE_DATADICTIONARY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='DD_TYPE DD_SOURCE' + ,notes='Configuration of data dictionary' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; diff --git a/sas/sasjs/db/datactrl/mpe_users.ddl b/sas/sasjs/db/datactrl/mpe_users.ddl new file mode 100644 index 0000000..e4818ad --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_users.ddl @@ -0,0 +1,17 @@ +/** + @file mpe_users.ddl + @brief ddl file + @details used to capture the actual users of the app + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table &curlib..mpe_users( + user_id char(50) not null, + last_seen_dt num not null format=date9., + registered_dt num not null format=date9., + constraint pk_mpe_users + primary key(user_id)); diff --git a/sas/sasjs/db/datactrl/mpe_validations.ddl b/sas/sasjs/db/datactrl/mpe_validations.ddl new file mode 100644 index 0000000..de7bc89 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_validations.ddl @@ -0,0 +1,74 @@ +/** + @file mpe_validations.ddl + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + + +create table &curlib..MPE_VALIDATIONS + ( + TX_FROM float format=datetime19., + BASE_LIB varchar(8), + BASE_DS varchar(32), + BASE_COL varchar(32), + RULE_TYPE varchar(32), + RULE_VALUE varchar(128), + RULE_ACTIVE int , + TX_TO float not null format=datetime19., + constraint pk_mpe_validations + primary key(tx_from, base_lib,base_ds,base_col,rule_type)); + +insert into &syslast set + tx_from=0 + ,base_lib="&mpelib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,base_lib="&mpelib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,base_lib="&mpelib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='NOTNULL' + ,rule_value=' ' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,base_lib="&mpelib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='NOTNULL' + ,rule_value=' ' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &syslast set + tx_from=0 + ,base_lib="&mpelib" + ,base_ds="MPE_TABLES" + ,base_col="NUM_OF_APPROVALS_REQUIRED" + ,rule_type='MINVAL' + ,rule_value='1' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; diff --git a/sas/sasjs/db/datactrl/mpe_x_test.ddl b/sas/sasjs/db/datactrl/mpe_x_test.ddl new file mode 100644 index 0000000..56cd747 --- /dev/null +++ b/sas/sasjs/db/datactrl/mpe_x_test.ddl @@ -0,0 +1,24 @@ +/** + @file + @brief DDL for Test Table + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + + + create table &curlib..mpe_x_test( + primary_key_field num, + some_char char(32767) , + some_dropdown char(128), + some_num num , + some_date num format=date9., + some_datetime num format=datetime19. informat=ANYDTDTM19., + some_time num format=time8., + some_shortnum num length=4, + some_bestnum num format=best., + constraint pk_mpe_x_test + primary key(primary_key_field)); diff --git a/sas/sasjs/db/dcdemo/dim_product.ddl b/sas/sasjs/db/dcdemo/dim_product.ddl new file mode 100644 index 0000000..ec4f109 --- /dev/null +++ b/sas/sasjs/db/dcdemo/dim_product.ddl @@ -0,0 +1,42 @@ +/** + @file + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +proc sql; +create table &curlib..dim_product( + tx_from num not null format=datetime19.3, + tx_to num not null format=datetime19.3, + product_cd char(40) not null, + product_desc char(100) not null, + constraint pk + primary key(tx_from, product_cd)); + +insert into &syslast + set tx_from=&low_date,tx_to=&high_date + ,product_cd='WIDG' + ,product_desc='The most amazing widget'; +insert into &syslast + set tx_from=&low_date,tx_to=&high_date + ,product_cd='FLFY' + ,product_desc='A fluffy bear'; +insert into &syslast + set tx_from=&low_date,tx_to=&high_date + ,product_cd='DRNE' + ,product_desc='Technological Drone Marvel'; +insert into &syslast + set tx_from=&low_date,tx_to=&high_date + ,product_cd='BGGY' + ,product_desc='Powerful Sand Buggy'; +insert into &syslast + set tx_from=&low_date,tx_to=&high_date + ,product_cd='RBOT' + ,product_desc='Deadly Robot'; diff --git a/sas/sasjs/db/migrations/20200121_mpe_groups.sas b/sas/sasjs/db/migrations/20200121_mpe_groups.sas new file mode 100644 index 0000000..dda23a8 --- /dev/null +++ b/sas/sasjs/db/migrations/20200121_mpe_groups.sas @@ -0,0 +1,26 @@ +/** + @file +**/ + +proc sql; +create table &curlib..mpe_groups( + tx_from num not null, + group_name char(100) not null, + group_desc char(256), + user_name char(50) not null, + tx_to num not null, + constraint pk + primary key(tx_from,group_name,user_name)); + +insert into &syslast set + tx_from=0 + ,group_name="DC Demo Group" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="allbow" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &syslast set + tx_from=0 + ,group_name="DC Demo Group" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="mobeen@saspw" + ,tx_to='31DEC5999:23:59:59'dt; \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20200131_mpe_security.sas b/sas/sasjs/db/migrations/20200131_mpe_security.sas new file mode 100644 index 0000000..3c43b5e --- /dev/null +++ b/sas/sasjs/db/migrations/20200131_mpe_security.sas @@ -0,0 +1,25 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + +proc sql; +create table backup as select * from dc.mpe_security; + +proc sql; +alter table dc.mpe_security + add libref char(8), dsn char(32); +update dc.mpe_security + set libref=put(scan(base_table,1,'.'),$8.) + , dsn=put(scan(base_table,2,'.'),$8.); +drop index pk from dc.mpe_security; +alter table dc.mpe_security drop base_table; +create unique index PK on dc.mpe_security + (libref,dsn,access_level,sas_group,tx_from); + +/** + THERE IS NOW A MANUAL STEP - open MPE_TABLES + and change the MPE_SECURITY entry: + - FROM: BASE_TABLE ACCESS_LEVEL SAS_GROUP + - TO: LIBREF DSN ACCESS_LEVEL SAS_GROUP +**/ diff --git a/sas/sasjs/db/migrations/20200208_mpe_config.sas b/sas/sasjs/db/migrations/20200208_mpe_config.sas new file mode 100644 index 0000000..4ccd8ff --- /dev/null +++ b/sas/sasjs/db/migrations/20200208_mpe_config.sas @@ -0,0 +1,21 @@ +/** + @file +**/ +/* NOT NECESSARY aNY MORE + +libname DC "/YOUR/DC/LIB"; + +proc sql; +create table backup as select * from dc.mpe_config; +*/ + +/* close out the unnecessary record +proc sql; +update DC.MPE_CONFIG + set tx_to=%sysfunc(datetime()) + where var_name="DC_STAGING_AREA"; +*/ + +/* +proc sql; drop table backup; +*/ \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20200224_mpe_requests.sas b/sas/sasjs/db/migrations/20200224_mpe_requests.sas new file mode 100644 index 0000000..477ae70 --- /dev/null +++ b/sas/sasjs/db/migrations/20200224_mpe_requests.sas @@ -0,0 +1,18 @@ +/** + @file +**/ + + +libname DC "/YOUR/DC/LIB"; + + /* no PK defined as it is a transaction table */ +proc sql; + create table dc.mpe_requests( + request_dttm num not null format=datetime19., + request_user char(64) not null, + request_service char(64) not null, + request_params char(128) + ); + +/* ALSO - make sure there is a DIRECT libname assigned in the +data_controller_settings stp */ \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20200227_mpe_selectbox.sas b/sas/sasjs/db/migrations/20200227_mpe_selectbox.sas new file mode 100644 index 0000000..01deb46 --- /dev/null +++ b/sas/sasjs/db/migrations/20200227_mpe_selectbox.sas @@ -0,0 +1,44 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + +proc sql; +create table backup as select * from dc.mpe_selectbox; + +/* find the contraint name (need to drop the constraint before the column) */ +proc sql; +create table CONSTRAINT_COLUMN_USAGE as + select upcase(column_name) as column_name + ,constraint_name + from dictionary.CONSTRAINT_COLUMN_USAGE + where table_catalog='DC' and upcase(table_name)="MPE_SELECTBOX"; +create table TABLE_CONSTRAINTS as + select * + from dictionary.TABLE_CONSTRAINTS + where table_catalog='DC' and upcase(table_name)="MPE_SELECTBOX"; +create table final as select a.column_name + ,b.* +from CONSTRAINT_COLUMN_USAGE a +left join TABLE_CONSTRAINTS b +on a.CONSTRAINT_NAME=b.CONSTRAINT_NAME; +data _null_; + set final; + if upcase(column_name)='BASE_LIBDS' then call symputx('name',CONSTRAINT_NAME); +run; + +proc sql; +alter table dc.mpe_selectbox add select_lib char(17), select_ds char(32); +update dc.mpe_selectbox + set select_lib=put(scan(base_libds,1,'.'),$8.) + , select_ds=put(scan(base_libds,2,'.'),$32.); +alter table dc.mpe_selectbox drop constraint &name; +alter table dc.mpe_selectbox drop base_libds; + + +/** + THERE IS NOW A MANUAL STEP - open MPE_TABLES + and change the MPE_SELECTBOX entry in the RK_UNDERLYING column: + - FROM: BASE_LIBDS BASE_COLUMN SELECTBOX_VALUE + - TO: SELECT_LIB SELECT_DS BASE_COLUMN SELECTBOX_VALUE +**/ diff --git a/sas/sasjs/db/migrations/20200319_dd_validations.sas b/sas/sasjs/db/migrations/20200319_dd_validations.sas new file mode 100644 index 0000000..0511962 --- /dev/null +++ b/sas/sasjs/db/migrations/20200319_dd_validations.sas @@ -0,0 +1,32 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + +proc sql; +create table DC.MPE_VALIDATIONS +( + TX_FROM float format=datetime19., + BASE_LIB varchar(8), + BASE_DS varchar(32), + BASE_COL varchar(32), + RULE_TYPE varchar(32), + RULE_VALUE varchar(128), + RULE_ACTIVE int , + TX_TO float not null format=datetime19., + constraint pk + primary key(tx_from, base_lib,base_ds,base_col,rule_type)); + +create table DC.mpe_datadictionary +( + TX_FROM float format=datetime19., + DD_TYPE char(16), + DD_SOURCE char(2048), + DD_SHORTDESC char(256), + DD_LONGDESC char(32767), + DD_OWNER char(128), + DD_RESPONSIBLE char(128), + DD_SENSITIVITY char(64), + TX_TO float not null format=datetime19., + constraint pk + primary key(tx_from, dd_type,dd_source)); \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20200428_datacatalog.sas b/sas/sasjs/db/migrations/20200428_datacatalog.sas new file mode 100644 index 0000000..c0e7a13 --- /dev/null +++ b/sas/sasjs/db/migrations/20200428_datacatalog.sas @@ -0,0 +1,74 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; +proc sql; +create table dc.mpe_datacatalog_libs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Ref', + engine char(32) label='Library Engine', + libname char(256) format=$256. label='Library Name', + paths char(8192) label='Library Paths', + perms char(500) label='Library Permissions (if BASE)', + owners char(500) label='Library Owners (if BASE)', + schemas char(500) label='Library Schemas (if DB)', + libid char(17) label='LibraryId', + constraint pk + primary key(libref,tx_to)); + +create table dc.mpe_datacatalog_TABS( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + memtype char(8) label='Member Type', + dbms_memtype char(32) label='DBMS Member Type', + memlabel char(512) label='Data Set Label', + typemem char(8) label='Data Set Type', + nvar num label='Number of Variables', + compress char(8) label='Compression Routine', + pk_fields char(512) + label='Primary Key Fields (identified by being in a constraint that is both Unique and Not Null)', + constraint pk + primary key(libref,dsn,tx_to)); + + +create table dc.mpe_datacatalog_vars( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Table Name', + memtype char(8) label='Member Type', + name char(64) label='Column Name', + type char(16) label='Column Type', + length num label='Column Length', + varnum num label='Column Number in Table', + label char(512) label='Column Label', + format char(49) label='Column Format', + idxusage char(9) label='Column Index Type', + notnull char(3) label='Not NULL?', + pk_ind num label="Primary Key Indicator (1=Primary Key field)", + constraint pk + primary key(libref,dsn,name,tx_to)); + + create table dc.mpe_datastatus_libs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + libsize num format=SIZEKMG. label='Size of file', + table_cnt num label='Number of Tables', + constraint pk + primary key(libref,tx_to)); + + create table dc.mpe_datastatus_tabs( + TX_FROM float format=datetime19., + TX_TO float format=datetime19., + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + filesize num format=SIZEKMG. label='Size of file', + crdate num format=DATETIME. informat=DATETIME. label='Date Created', + modate num format=DATETIME. informat=DATETIME. label='Date Modified', + nobs num label='Number of Physical (Actual, inc. deleted) Observations', + constraint pk + primary key(libref,dsn,tx_to)); \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20200529_lineagetabs.sas b/sas/sasjs/db/migrations/20200529_lineagetabs.sas new file mode 100644 index 0000000..e75630c --- /dev/null +++ b/sas/sasjs/db/migrations/20200529_lineagetabs.sas @@ -0,0 +1,36 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + +/** + @file mpe_lineage_tabs.ddl + @brief ddl file + @details + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd +**/ + +proc sql; +create table dc.MPE_LINEAGE_TABS + ( + tx_from num not null, + jobid char(17), + jobname char(128), + srctableid char(17), + srctabletype char(16), + srctablename char(64), + srclibref char(8), + tgttableid char(17), + tgttabletype char(16), + tgttablename char(64), + tgtlibref char(8), + tx_to num not null, + constraint pk primary key + ( + tx_to,jobid,srctableid,tgttableid + ) + ); diff --git a/sas/sasjs/db/migrations/20200605v38_mpe_datadictionary.sas b/sas/sasjs/db/migrations/20200605v38_mpe_datadictionary.sas new file mode 100644 index 0000000..f213dac --- /dev/null +++ b/sas/sasjs/db/migrations/20200605v38_mpe_datadictionary.sas @@ -0,0 +1,13 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + + +proc sql; +alter table DC . MPE_DATADICTIONARY drop constraint pk ; +alter table dc.mpe_datadictionary modify DD_SOURCE char(1024); +alter table DC . MPE_DATADICTIONARY + add constraint pk_mpe_datadictionary PRIMARY KEY ( + TX_FROM, DD_SOURCE, DD_TYPE); + diff --git a/sas/sasjs/db/migrations/20201003_mpe_users.sas b/sas/sasjs/db/migrations/20201003_mpe_users.sas new file mode 100644 index 0000000..6fdb455 --- /dev/null +++ b/sas/sasjs/db/migrations/20201003_mpe_users.sas @@ -0,0 +1,14 @@ +/** + @file +**/ +libname DC "/YOUR/DC/LIB"; + + +proc sql; +create table dc.mpe_users( + user_id char(50) not null, + last_seen_dt num not null format=date9., + registered_dt num not null format=date9., + constraint pk_mpe_users + primary key(user_id)); + diff --git a/sas/sasjs/db/migrations/20210211_mpe_review.sas b/sas/sasjs/db/migrations/20210211_mpe_review.sas new file mode 100644 index 0000000..2224a67 --- /dev/null +++ b/sas/sasjs/db/migrations/20210211_mpe_review.sas @@ -0,0 +1,16 @@ +/** + @file +**/ + +libname DC "/YOUR/DC/LIB"; + +/* incorrect format was applied (date.) */ +proc datasets lib=DC; + MODIFY mpe_review; + FORMAT reviewed_on_dttm datetime19.; +quit; + +proc sql; +alter table dc.mpe_config add var_active num; + +update dc.mpe_config set var_active=1; \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20210410_v3.12_release.sas b/sas/sasjs/db/migrations/20210410_v3.12_release.sas new file mode 100644 index 0000000..c9f18f1 --- /dev/null +++ b/sas/sasjs/db/migrations/20210410_v3.12_release.sas @@ -0,0 +1,447 @@ +/** + @file + @brief migration script to move from v3.11 to v3.12 of data controller + + @details MANUAL STEP - add "AUDIT" as a new value in mpe_selectbox for the + mpe_security table (access_level column) + + +

SAS Macros

+ @li mm_assigndirectlib.sas + +**/ + +filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; +%inc mc; + +%let dclib=YOURDCLIB; +%let lib=&dclib; + +%mm_assigndirectlib(&dclib) + +proc sql; +create table &dclib..mpe_excel_config( + tx_from num, + xl_libref char(8), + xl_table char(32), + xl_column char(32), + xl_rule char(32), + xl_active num, + tx_to num not null, + constraint pk_mpe_excel_config + primary key(tx_from,xl_libref,xl_table,xl_column)); +create table &lib..mpe_row_level_security( + tx_from num not null format=datetime19.3, + tx_to num not null format=datetime19.3, + RLS_RK num not null, + RLS_SCOPE char(8) not null, + RLS_GROUP char(128) not null, + RLS_LIBREF char(8) not null, + RLS_TABLE char(32) not null, + RLS_GROUP_LOGIC char(3) not null, + RLS_SUBGROUP_LOGIC char(3) not null, + RLS_SUBGROUP_ID num not null, + RLS_VARIABLE_NM varchar(32) not null, + RLS_OPERATOR_NM varchar(12) not null, + RLS_RAW_VALUE varchar(4000) not null, + RLS_ACTIVE num not null, + constraint pk_mpe_row_level_security + primary key(tx_from, RLS_RK)); + +proc sql; + insert into &dclib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&dclib" + ,dsn='MPE_EXCEL_CONFIG' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='XL_LIBREF XL_TABLE XL_COLUMN' + ,notes='Configuration of the excel import rules' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_ROW_LEVEL_SECURITY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='RLS_RK' + ,notes='Configuration of Row Level Security' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,rk_underlying='RLS_SCOPE RLS_GROUP RLS_LIBREF RLS_TABLE RLS_GROUP_LOGIC ' + !!'RLS_SUBGROUP_LOGIC RLS_SUBGROUP_ID RLS_VARIABLE_NM RLS_OPERATOR_NM ' + !!'RLS_RAW_VALUE ' + ,POST_EDIT_HOOK='services/hooks/mpe_row_level_security_postedit' + ; + + +proc sql; +alter table &dclib..mpe_filteranytable drop filter_json; + +proc sql; +create table &dclib..mpe_filtersource( + filter_hash char(32) not null, + filter_line num not null, + group_logic char(3) not null, + subgroup_logic char(3) not null, + subgroup_id num not null, + variable_nm varchar(32) not null, + operator_nm varchar(12) not null, + raw_value varchar(4000) not null, + processed_dttm num not null format=datetime19., + constraint pk_mpe_filteranytable + primary key(filter_hash,filter_line)); + +proc sql; +select max(selectbox_rk) into: selectbox_rk from &dclib..mpe_filtersource; +insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+1 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="HARDSELECT_HOOK" + ,selectbox_order=7 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+2 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="SOFTSELECT_HOOK" + ,selectbox_order=7 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+3 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="ALL" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+4 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="EDIT" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+5 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="VIEW" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+6 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_GROUP_LOGIC" + ,selectbox_value="AND" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+7 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_GROUP_LOGIC" + ,selectbox_value="OR" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+8 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SUBGROUP_LOGIC" + ,selectbox_value="AND" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+9 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SUBGROUP_LOGIC" + ,selectbox_value="OR" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+10 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="=" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+11 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value=">" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+12 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="<" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+13 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="<=" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+14 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value=">=" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+15 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="BETWEEN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+16 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="NOT IN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+17 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="NE" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+18 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="CONTAINS" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+19 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_ACTIVE" + ,selectbox_value="1" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=&selectbox_rk+20 + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_ACTIVE" + ,selectbox_value="0" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + + + +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="RULE_ACTIVE" + ,rule_type='MINVAL' + ,rule_value="0" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="RULE_ACTIVE" + ,rule_type='MAXVAL' + ,rule_value="1" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_LIB" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_DS" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_COL" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_TABLE" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_COLUMN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXFROM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXTO" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSFROM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSTO" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_PROCESSED" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="SELECT_LIB" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="SELECT_DS" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="BASE_COLUMN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + + diff --git a/sas/sasjs/db/migrations/20210802_v3.13_release.sas b/sas/sasjs/db/migrations/20210802_v3.13_release.sas new file mode 100644 index 0000000..62775a0 --- /dev/null +++ b/sas/sasjs/db/migrations/20210802_v3.13_release.sas @@ -0,0 +1,31 @@ +/** + @file + @brief migration script to move from v3.12 to v3.13 of data controller + + +

SAS Macros

+ @li mm_assigndirectlib.sas + +**/ + +filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; +%inc mc; + +%let dclib=YOURDCLIB; +%let lib=&dclib; + +%mm_assigndirectlib(&dclib) + +proc sql; +update &dclib..MPE_VALIDATIONS set tx_to=%sysfunc(datetime()) + where base_lib="&dclib" + and base_ds="MPE_TABLES" + and base_col="DSN"; +insert into &dclib..MPE_VALIDATIONS set tx_from=%sysfunc(datetime()) + ,tx_to='31DEC5999:23:59:59'dt + ,base_lib="&dclib" + ,base_ds="MPE_TABLES" + ,base_col="DSN"; + ,rule_value="services/validations/mpe_tables.dsn" + ,rule_active=1 + ,rule_type='SOFTSELECT_HOOK'; \ No newline at end of file diff --git a/sas/sasjs/db/migrations/20211215_v4.0_release.sas b/sas/sasjs/db/migrations/20211215_v4.0_release.sas new file mode 100644 index 0000000..bfbe84b --- /dev/null +++ b/sas/sasjs/db/migrations/20211215_v4.0_release.sas @@ -0,0 +1,98 @@ +/** + @file + @brief migration script to move from v3.13 to v4.0 of data controller + + BREAKING CHANGE - deprecate filter_text + +

SAS Macros

+ @li mm_assigndirectlib.sas + +**/ + +filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; +%inc mc; + +%let dclib=YOURDCLIB; + +%mm_assigndirectlib(&dclib) + +/** + * Change 1 + * New audit table + */ +proc sql; +create table &dclib..mpe_audit( + load_ref char(36) label='unique load reference', + processed_dttm num format=E8601DT26.6 label='Processed at timestamp', + libref char(8) label='Library Reference (8 chars)', + dsn char(32) label='Dataset Name (32 chars)', + key_hash char(32) label= + 'MD5 Hash of primary key values (pipe seperated)', + move_type char(1) label='Either (A)ppended, (D)eleted or (M)odified', + is_pk num label='Is Primary Key Field? (1/0)', + is_diff num label= + 'Did value change? (1/0/-1). Always -1 for appends and deletes.', + tgtvar_type char(1) label='Either (C)haracter or (N)umeric', + tgtvar_nm char(32) label='Target variable name (32 chars)', + oldval_num num label='Old (numeric) value', + newval_num num label='New (numeric) value', + oldval_char char(32765) label='Old (character) value', + newval_char char(32765) label='New (character) value', + constraint pk_mpe_audit + primary key(load_ref,libref,dsn,key_hash,tgtvar_nm) +); + + + +/** + * Change 2 + * Filter_text is from the old filtering mechanism where the filter string + * would be stored in a single variable + */ +/* backup old filters */ +proc sql; +create table &dclib..bkp_filters as + select * from &dclib..mpe_filteranytable + where filter_text ne 'N/A'; + +/* create new table without the new column */ + +create table work.mpe_filteranytable( + filter_rk num not null, + filter_hash char(32) not null, + filter_table char(41) not null, + processed_dttm num not null format=datetime19., + constraint pk_mpe_filteranytable + primary key(filter_rk)); + +/* copy the old data across */ +insert into work.mpe_filteranytable + select filter_rk, filter_hash, filter_table, processed_dttm + from &dclib..mpe_filteranytable + where filter_text ='N/A'; + +/* drop the old table */ +proc delete data=&dclib..mpe_filteranytable; +run; + + +/* copy across the new one */ +proc append base=&dclib..mpe_filteranytable + data=work.mpe_filteranytable; +run; + +/* add new loadtype */ +proc sql noprint; +select max(selectbox_rk) into: maxrk + from &dclib..mpe_selectbox; +insert into &dclib..mpe_selectbox set + selectbox_rk=&maxrk+1 + ,ver_from_dttm=0 + ,select_lib="&dclib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='FORMAT_CAT' + ,selectbox_order=5 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + +/* now update the metadata to match with the removed column */ diff --git a/sas/sasjs/db/migrations/20220615_v5.0_release.sas b/sas/sasjs/db/migrations/20220615_v5.0_release.sas new file mode 100644 index 0000000..41c8756 --- /dev/null +++ b/sas/sasjs/db/migrations/20220615_v5.0_release.sas @@ -0,0 +1,69 @@ +/** + @file + @brief migration script to move from v4 to v5.0 of data controller + + BREAKING CHANGE - deprecate MPE_APPROVALS and MPE_REVIEW (now MPE_SUBMIT does + both) + +

SAS Macros

+ @li mm_assigndirectlib.sas + +**/ + +%let dclib=YOURDCLIB; + +libname &dclib "/your/dc/path"; + +/** + * Change 1 + * New MPE_SUBMIT table + */ +proc sql; +create table &dclib..mpe_submit( + table_id varchar(32) not null, + submit_status_cd varchar(10) not null, + base_lib char(8) not null, + base_ds char(32) not null, + submitted_by_nm varchar(100) not null, + submitted_on_dttm num not null format=datetime19.3, + submitted_reason_txt varchar(400), + input_obs num, + input_vars num, + num_of_approvals_required num not null, + num_of_approvals_remaining num not null, + reviewed_by_nm char(100), + reviewed_on_dttm num, + constraint pk_mpe_submit + primary key(table_id) +); + +/* change 2 - col level security */ +%let notnull=not null; +proc sql; +create table &dclib..mpe_column_level_security( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + CLS_SCOPE char(4) ¬null, + CLS_GROUP char(64) ¬null, + CLS_LIBREF char(8) ¬null, + CLS_TABLE char(32) ¬null, + CLS_VARIABLE_NM char(32) ¬null, + CLS_ACTIVE num ¬null, + CLS_HIDE num +);quit; +proc datasets lib=&dclib noprint; + modify mpe_column_level_security; + index create + pk_mpe_column_level_security= + (tx_to CLS_SCOPE CLS_GROUP CLS_LIBREF CLS_TABLE CLS_VARIABLE_NM) + /nomiss unique; +quit; + +/* change 3 - drop helpful_link and add audit_libds */ + +proc sql; +alter table &dclib..mpe_tables drop helpful_link; +alter table &dclib..mpe_tables add audit_libds char(41); + + +/* now update the metadata if running SAS 9 EBI */ diff --git a/sas/sasjs/doxy/Doxyfile b/sas/sasjs/doxy/Doxyfile new file mode 100644 index 0000000..043c596 --- /dev/null +++ b/sas/sasjs/doxy/Doxyfile @@ -0,0 +1,41 @@ +ALPHABETICAL_INDEX = NO +DISABLE_INDEX = YES +ENABLE_PREPROCESSING = NO +EXTENSION_MAPPING = sas=Java ddl=Java +EXTRACT_LOCAL_CLASSES = NO +FILE_PATTERNS = *.sas \ + *.ddl \ + *.dox +GENERATE_LATEX = NO +GENERATE_TREEVIEW = YES +HIDE_FRIEND_COMPOUNDS = YES +HIDE_IN_BODY_DOCS = YES +HIDE_SCOPE_NAMES = YES +HIDE_UNDOC_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +HTML_OUTPUT = $(DOXY_HTML_OUTPUT) +HTML_HEADER = $(HTML_HEADER) +HTML_EXTRA_FILES = $(HTML_EXTRA_FILES) +HTML_FOOTER = $(HTML_FOOTER) +HTML_EXTRA_STYLESHEET = $(HTML_EXTRA_STYLESHEET) +INHERIT_DOCS = NO +INLINE_INFO = NO +INPUT = $(DOXY_INPUT) +INPUT += sasjs/doxy/main.dox +LAYOUT_FILE = $(LAYOUT_FILE) +MAX_INITIALIZER_LINES = 0 +PROJECT_NAME = "Data Controller" +PROJECT_LOGO = $(PROJECT_LOGO) +PROJECT_BRIEF = "Data Controller Source Files" +RECURSIVE = YES +REPEAT_BRIEF = NO +SHOW_NAMESPACES = NO +SHOW_USED_FILES = NO +SOURCE_BROWSER = YES +SOURCE_TOOLTIPS = NO +STRICT_PROTO_MATCHING = YES +STRIP_CODE_COMMENTS = NO +SUBGROUPING = NO +TAB_SIZE = 2 +USE_MDFILE_AS_MAINPAGE = README.md +VERBATIM_HEADERS = NO diff --git a/sas/sasjs/doxy/DoxygenLayout.xml b/sas/sasjs/doxy/DoxygenLayout.xml new file mode 100644 index 0000000..6f8ea41 --- /dev/null +++ b/sas/sasjs/doxy/DoxygenLayout.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sas/sasjs/doxy/README.md b/sas/sasjs/doxy/README.md new file mode 100644 index 0000000..f7b834c --- /dev/null +++ b/sas/sasjs/doxy/README.md @@ -0,0 +1,11 @@ +# SAS Code Docs + +This site contains the SAS code used in Data Controller for SAS. The pages were generated using [`sasjs doc`](https://cli.sasjs.io/doc). + +You can download Data Controller from [here](https://4gl.uk/dcdeploy). + +The main website is [https://datacontroller.io](https://datacontroller.io) and the user guide is [here](https://docs.datacontroller.io). + +If you have questions or would like support, we can be contacted in our [Matrix Channel](https://matrix.to/#/%23dc:4gl.io). + + diff --git a/sas/sasjs/doxy/data_controller.png b/sas/sasjs/doxy/data_controller.png new file mode 100644 index 0000000..753e218 Binary files /dev/null and b/sas/sasjs/doxy/data_controller.png differ diff --git a/sas/sasjs/doxy/favicon.ico b/sas/sasjs/doxy/favicon.ico new file mode 100644 index 0000000..b888dfb Binary files /dev/null and b/sas/sasjs/doxy/favicon.ico differ diff --git a/sas/sasjs/doxy/main.dox b/sas/sasjs/doxy/main.dox new file mode 100644 index 0000000..f3a7b99 --- /dev/null +++ b/sas/sasjs/doxy/main.dox @@ -0,0 +1,124 @@ +/** \dir node_modules + * \brief Folder with Node Dependencies + */ + +/** \dir node_modules/@sasjs/ + * \brief SASjs-scoped area for NPM packages + */ + +/** \dir node_modules/@sasjs/core + * \brief SASjs Core library - available here: https://github.com/sasjs/core + */ + +/** \dir /sasjs + * \brief main directory for DC SAS content + * \details To use - add the subfolders to your `SASAUTOS` call path. + */ + +/** \dir sasjs/db + * \brief Directory for DDL and Datalines, split by Libref + */ + +/** \dir sasjs/db/datactrl + * \brief Main directory for DC Control Table DDL + */ + +/** \dir sasjs/macros + * \brief Data Controller Macros for all SAS Flavours + */ + +/** \dir sasjs/services + * \brief Data Controller Services for all SAS Flavours + */ + +/** \dir sasjs/services/admin + * \brief Services for Administrators only + */ + +/** \dir sasjs/services/approvers + * \brief Services for DC Approvers + */ + +/** \dir sasjs/services/auditors + * \brief Services for both Editors and Auditors + */ + +/** \dir sasjs/services/editors + * \brief Services for Editors + */ + +/** \dir sasjs/services/hooks + * \brief HOOK Scripts - these run before/after specific EDIT/APPROVE events. + */ + +/** \dir sasjs/services/public + * \brief All DC users need access to these services + */ + +/** \dir sasjs/services/validations + * \brief These services drive the dynamic cell validation for DC Control tables + */ + +/** \dir sasjs/targets + * \brief These folders contain services that are specific for particular flavours of SAS + */ + +/** \dir sasjs/targets/sas9 + * \brief Macros and Services that run only on the SAS 9 EBI instance of DC + */ + +/** \dir sasjs/targets/sas9/services_meta + * \brief Services that run only on the SAS 9 EBI instance of DC + */ + +/** \dir sasjs/targets/sas9/services_meta/admin + * \brief SAS 9 Admin Services + */ + +/** \dir sasjs/targets/sas9/services_meta/lineage + * \brief SAS 9 Lineage Generation services + */ + +/** \dir sasjs/targets/sas9/services_meta/metanav + * \brief SAS 9 Metadata Navigator services + */ + +/** \dir sasjs/targets/sas9/services_meta/usernav + * \brief SAS 9 User Navigator services + */ + +/** \dir sasjs/targets/server + * \brief Macros and Services that run only on the [SASjs Server](https://server.sasjs.io) instance of DC + */ + +/** \dir sasjs/targets/server/macros_server + * \brief Macros that run only on the [SASjs Server](https://server.sasjs.io) instance of DC + */ + +/** \dir sasjs/targets/server/services_server + * \brief Services that run only on the [SASjs Server](https://server.sasjs.io) instance of DC + */ + +/** \dir sasjs/targets/server/services_server/admin + * \brief SASjs Server Admin Services + */ + +/** \dir sasjs/targets/server/services_server/usernav + * \brief SASjs Server User Navigator Services + */ + +/** \dir sasjs/targets/viya + * \brief Macros and Services that run only on the Viya instance of DC + */ + +/** \dir sasjs/targets/viya/macros_viya + * \brief Macros that run only on the Viya instance of DC + */ + +/** \dir sasjs/targets/viya/services_viya + * \brief Services that run only on the Viya instance of DC + */ + +/** \dir sasjs/targets/viya/services_viya/admin + * \brief Viya admin services + */ diff --git a/sas/sasjs/doxy/new_footer.html b/sas/sasjs/doxy/new_footer.html new file mode 100644 index 0000000..1c49169 --- /dev/null +++ b/sas/sasjs/doxy/new_footer.html @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/sas/sasjs/doxy/new_header.html b/sas/sasjs/doxy/new_header.html new file mode 100644 index 0000000..101db70 --- /dev/null +++ b/sas/sasjs/doxy/new_header.html @@ -0,0 +1,90 @@ + + + + + + + + + + + $projectname: $title + + + $title + + + + + $treeview $search $mathjax + + + $extrastylesheet + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
+
+  $projectnumber + +
+ + + + +
$searchbox
+
+ + +
+ + + diff --git a/sas/sasjs/doxy/new_stylesheet.css b/sas/sasjs/doxy/new_stylesheet.css new file mode 100644 index 0000000..b7ec9a3 --- /dev/null +++ b/sas/sasjs/doxy/new_stylesheet.css @@ -0,0 +1,4 @@ +#projectlogo img { + border: 0px none; + max-height: 70px; +} diff --git a/sas/sasjs/macros/bitemporal_closeouts.sas b/sas/sasjs/macros/bitemporal_closeouts.sas new file mode 100755 index 0000000..4604f31 --- /dev/null +++ b/sas/sasjs/macros/bitemporal_closeouts.sas @@ -0,0 +1,204 @@ +/** + @file + @brief Closes out records + @details Closes out records from a temporal table by reference to a single + temporal range + business key. Only live records are closed out, so the + entire key should be provided in the input table EXCEPT the TECH_FROM. + All records matching the key (as per the input table) are closed out + on TECH_TO. + + Returns an updated base table and `&mpelib..mpe_dataloads` table + + Potential improvements - write the update statements as a text file and retain + for future reference! + + @param [in] now= (DEFINE) Allows consistent tracking of tech dates. Should be + a date literal, not a numeric constant, for DB compatibility. + @param [in] load_type= Set to UPDATE if non-temporal, else assumed + to be TXTEMPORAL. Note that BITEMPORAL is treated the same as TXTEMPORAL + given that BUS_FROM should be supplied in the PK. + @param [in] tech_from= (tx_from_dttm) Technical FROM datetime variable. + Required on BASE table only. + +

Global Variables

+ @li `dc_dttmtfmt` + + +

SAS Macros

+ @li mp_abort.sas + @li mf_existvar.sas + @li mf_getattrn.sas + @li mf_getuser.sas + @li mf_getvartype.sas + @li mp_lockanytable.sas + @li dc_assignlib.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm /* Technical TO datetime variable. + Req'd on BASE table only. */ + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=BASETABLE /* Name of BASE table. */ + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=APPENDTABLE /* Name of STAGING table. */ + ,PK= name sex /* Business key, space separated. */ + /* Should INCLUDE BUS_FROM field if relevant. */ + ,NOW=DEFINE + ,FILTER= /* supply a filter to limit the update */ + ,outdest= /* supply an unquoted filepath/filename.ext to get + a text file containing the update statements */ + ,loadtype= + ,loadtarget=YES /* if <> YES will return without changing anything */ +); +%put ENTERING &sysmacroname; +%local x var start; +%let start=%sysfunc(datetime()); +%dc_assignlib(WRITE,&base_lib) +%dc_assignlib(WRITE,&append_lib) + +%if &now=DEFINE %then %let now=&dc_dttmtfmt.; +%put &=now; +/** + * perform basic checks + */ +/* do tables exist? */ +%if not %sysfunc(exist(&base_lib..&base_dsn)) %then %do; + %mp_abort(msg=&base_lib..&base_dsn does not exist) +%end; +%else %if %sysfunc(exist(&append_lib..&append_dsn))=0 + and %sysfunc(exist(&append_lib..&append_dsn,VIEW))=0 %then %do; + %mp_abort(msg=&append_lib..&append_dsn does not exist) +%end; +/* do TX columns exist? */ +%if &loadtype ne UPDATE %then %do; + %if not %mf_existvar(&base_lib..&base_dsn,&tech_from) %then %do; + %mp_abort(msg=&tech_from does not exist on &base_lib..&base_dsn) + %end; + %else %if not %mf_existvar(&base_lib..&base_dsn,&tech_to) %then %do; + %mp_abort(msg=&tech_to does not exist on &base_lib..&base_dsn) + %end; +%end; +/* do PK columns exist? */ +%do x=1 %to %sysfunc(countw(&PK)); + %let var=%scan(&pk,&x,%str( )); + %if not %mf_existvar(&base_lib..&base_dsn,&var) %then %do; + %mp_abort(msg=&var does not exist on &base_lib..&base_dsn) + %end; + %else %if not %mf_existvar(&append_lib..&append_dsn,&var) %then %do; + %mp_abort(msg=&var does not exist on &append_lib..&append_dsn) + %end; +%end; +/* check uniqueness */ +proc sort data=&append_lib..&append_dsn + out=___closeout1 noduprecs dupout=___closeout1a; + by &pk; +run; +%if %mf_getattrn(___closeout1a,NLOBS)>0 %then + %put NOTE: dups on (&PK) in (&append_lib..&append_dsn); +/* is &NOW value within a tolerance? Should not allow renegade closeouts.. */ +%local gap; +%let gap=0; +data _null_; + now=&now; + gap=intck('HOURS',now,datetime()); + call symputx('gap',gap,'l'); +run; +%mf_abort( + iftrue=(&gap > 24), + msg=NOW variable (&now) is not within a 24hr tolerance +) + +/* have any warnings / errs occurred thus far? If so, abort */ +%mf_abort( + iftrue=(&syscc>0), + msg=Aborted due to SYSCC=&SYSCC status +) + +/** + * Create closeout statements. These are sent as individual SQL statements + * to ensure pass-through utilisation. The update_cnt variable monitors + * how many records were actually updated on the target table. + */ +%local update_cnt; +%let update_cnt=0; +filename tmp temp; +data _null_; + set ___closeout1; + file tmp; + if _n_=1 then put 'proc sql noprint;' ; + length string $32767.; + %if &loadtype=UPDATE %then %do; + put "delete from &base_lib..&base_dsn where 1"; + %end; + %else %do; + now=symget('now'); + put "update &base_lib..&base_dsn set &tech_to= " now @; + %if %mf_existvar(&base_lib..&base_dsn,PROCESSED_DTTM) %then %do; + put " ,PROCESSED_DTTM=" now @; + %end; + put " where " now " lt &tech_to "; + %end; + %do x=1 %to %sysfunc(countw(&PK)); + %let var=%scan(&pk,&x,%str( )); + %if %mf_getvartype(&base_lib..&base_dsn,&var)=C %then %do; + /* use single quotes to avoid ampersand resolution in data */ + string=" & &var='"!!trim(prxchange("s/'/''/",-1,&var))!!"'"; + %end; + %else %do; + string=cats(" & &var=",&var); + %end; + put string; + %end; + put "&filter ;"; + put '%let update_cnt=%eval(&update_cnt+&sqlobs);%put update_cnt=&update_cnt;'; +run; + +data _null_; + infile tmp; + input; + putlog _infile_; +run; + +%if &loadtarget ne YES %then %return; + +/* ensure we have a lock */ +%mp_lockanytable(LOCK, + lib=&base_lib,ds=&base_dsn + ,ref=bitemporal_closeouts + ,ctl_ds=&mpelib..mpe_lockanytable +) + +options source2; +%inc tmp; + +filename tmp clear; + +/** + * Update audit tracker + */ + +%local newobs; %let newobs=%mf_getattrn(work.___closeout1,NLOBS); +%local user; %let user=%mf_getuser(); +proc sql; +insert into &mpelib..mpe_dataloads + set libref=%upcase("&base_lib") + ,DSN=%upcase("&base_dsn") + ,ETLSOURCE="&append_lib..&append_dsn contained &newobs records" + ,LOADTYPE="CLOSEOUT" + ,DELETED_RECORDS=&update_cnt + ,NEW_RECORDS=0 + ,DURATION=%sysfunc(datetime())-&start + ,USER_NM="&user" + ,PROCESSED_DTTM=&now; +quit; + + +%mend bitemporal_closeouts; diff --git a/sas/sasjs/macros/bitemporal_dataloader.sas b/sas/sasjs/macros/bitemporal_dataloader.sas new file mode 100755 index 0000000..132bc29 --- /dev/null +++ b/sas/sasjs/macros/bitemporal_dataloader.sas @@ -0,0 +1,1447 @@ +/** + @file + @brief Routine supporting multiple load types + @details Generic loader for multiple load types (UPDATE, SCD2, BITEMPORAL). + + Handles all elements including metadata validation, PK checking, closeouts, + locking, logging, etc. + + The staging table must be prepared with a unique business key. For bitemporal + this means a snapshot at both technical AND business time. + +ASSUMPTIONS: + - Base table has relevant datetime vars: 2xTechnical, 2xBusiness, 1xProcessed + - Staging table omits Technical or Processed datetimes (has Business only) + - Base table has no column names containing the string "___TMP___" + - Base &tech_from variable is not nullable. This should always be the case + anyway whenbuilding permanent bitemporal datasets.. But the point is that + this field is used to identify new records after the initial left join + from staging to base table. + +NOTES: + - All queries against BiTemporal tables need two filter conditions, as such: + + where &bus_from LE [tstamp] LT &bus_to + AND &tx_from LE [tstamp] LT &tx_to + + One cannot use BETWEEN + One cannot use &xx_from LE [tstamp] LE &xx_from (equivalent to above). + Background: +http://stackoverflow.com/questions/20005950/best-practice-for-scd-date-pairs-closing-opening-timestamps + +Areas for optimisation + - loading temporal history (currently experimental) + + ## Supporting tables + + Supporting tables must exist in the library specified in the `dclib` param. + + ### MPE_DATALOADS + + This table is updated every time a successful load occurs, and includes + information such as: + + @li library + @li dataset + @li message (supplied in the ETLSOURCE param) + @li new rows + @li deleted rows + @li changed rows + @li timestamp + @li the user making the load + @li the version of (this) macro used to make the load + + + @param [in] APPEND_DSN= (APPENDTABLE) Name of STAGING table + @param [in] CONFIG_TABLE= (&dclib..MPE_CONFIG) The table containing library + engine specific config. The following scopes are supported: + @li DCBL_REDSH + @param [in] LOADTYPE= (BITEMPORAL) Supported types: + @li TXTEMPORAL - loads a buskey with version times + @li BUSTEMPORAL - loads buskey with bus + ver times + @li UPDATE - updates a buskey with NO history + @param [in] PROCESSED= (0) This column obtains a current timestamp for changed + records when loading the target table. Default is 0 (not set). If the + target table contains a variable called PROCESSED_DTTM, and processed=0, + then this column will be used for applying the current timestamp. + @param RK_MAXKEYTABLE= (mpe_maxkeyvalues) The maxkeytable to use (must exist + in DCLIB) + @param [in] PK= Business key, space separated. Should NOT include temporal + fields. + @param [in] RK_UNDERLYING= If supplied will generate an RK based on these + (space separated) business key fields. In this case only ONE PK field should + be supplied, which is assumed to be the RK. The RK field, plus underlying + fields, should all exist on the base table. The underlying fields should + exist on the staging table (the RK / PK field will be overwritten). + The staging table should also be unique on its PK. + + @param [in] dclib= (&dc_libref) The library containing DC configuration tables + @param [out] outds_del= (work.outds_del) Output table containing + deleted records + @param [out] outds_add= (work.outds_add) Output table containing + appended records + @param [out] outds_mod= (work.outds_mod) Output table containing + changed records + @param [out] outds_audit= (0) Load detailed changes to an audit table. Uses + the mp_storediffs.sas macro. Provide the base table here, to load. + +

Global Variables

+ The following global macro variables are used. These should be replaced by + macro parameters in future releases. + + @li `dc_dttmtfmt` + +

SAS Macros

+ @li bitemporal_closeouts.sas + @li dc_assignlib.sas + @li mf_existvar.sas + @li mf_fmtdttm.sas + @li mf_getattrn.sas + @li mf_getengine.sas + @li mf_getschema.sas + @li mf_getuniquename.sas + @li mf_getuser.sas + @li mf_getvarlist.sas + @li mf_verifymacvars.sas + @li mf_wordsinstr1butnotstr2.sas + @li mp_abort.sas + @li mp_dropmembers.sas + @li mp_lockanytable.sas + @li mp_lockfilecheck.sas + @li mp_retainedkey.sas + @li mp_storediffs.sas + + @version 9.3 + @author 4GL Apps Ltd. + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + + @warning multitemporal loads (bitemporal for multiple points in business time) + are in experimental stage + +**/ + +%macro bitemporal_dataloader( + bus_from= /* Business FROM datetime variable. Req'd on + STAGING & BASE tables.*/ + ,bus_to = /* Business TO datetime variable. Req'd on + STAGING & BASE tables. */ + ,bus_from_override= /* Provide a hard coded BUS_FROM datetime value.*/ + ,bus_to_override= /* provide a hard coded BUS_TO datetime value */ + ,tech_from= /* Technical FROM datetime variable. Req'd on + BASE table only. */ + ,tech_to = /* Technical TO datetime variable. Req'd on BASE + table only. */ + ,processed= 0 + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=BASETABLE /* Name of BASE table. */ + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=APPENDTABLE + ,high_date='01JAN5999:00:00:00'dt /* High date to close out records */ + ,PK= name sex + ,RK_UNDERLYING= + ,KEEPVARS= /* Provides option for removing unwanted vars from append table */ + ,RK_UPDATE_MAXKEYTABLE=NO /* If switching (or mix matching) with regular + SCD2 loader then set this switch to YES to + ensure the MAXKEYTABLE is updated with the + current maximum RK value for the target table + */ + ,CHECK_UNIQUENESS=YES /* Perform a check of the APPEND table to ensure it is + unique on its business key */ + ,ETLSOURCE=demo /* supply a value ($50.) to show as ETLSOURCE in + &dclib..DATALOADS */ + ,LOADTYPE=BITEMPORAL + ,RK_MAXKEYTABLE= mpe_maxkeyvalues + ,LOG=1 /* Switch to 0 to prevent records being added to + &mpelib..mpe_DATALOADS (ie when testing)*/ + ,DELETE_COL= _____DELETE__THIS__RECORD_____ + /* If this variable is found in the append dataset + then records are closed out (or deleted) in the + append table where that variable= "Yes" */ + ,LOADTARGET=YES /* set to anything but uppercase YES to switch off + target table load and generate temp tables only */ + ,CLOSE_VARS= +/*a problem with regular SCD2 or TXTEMPORAL loads is that there is + no facility to close out removed records (all records are + assumed new or changed). But how does one determine which + records are removed? Short of loading the entire table + each time? This parameter allows a set of variables + (this should be a subset of the PK) to be declared, and + the macro will determine which records in the base table + need to be closed out ahead of the load. + + For instance, given the following: + + Base Table Staging Table + DATE ENTITY AMOUNT DATE ENTITY AMOUNT + JAN ACME4 66 JAN ACME4 66 + FEB ACME4 99 FEB ACME4 99 + FEB ACME1 22 + + By supplying DATE in CLOSE_VARS and DATE ENTITY as the PK, + the "FEB PAG 22" record would get closed out. + */ + ,config_table=&dclib..MPE_CONFIG + ,dclib=&dc_libref + ,outds_del=work.outds_del + ,outds_add=work.outds_add + ,outds_mod=work.outds_mod + ,outds_audit=0 + ); + +/* when changing this macro, update the version num here */ +%local ver; +%let ver=32; +%put &sysmacroname entry vars:; +%put _local_; + +%dc_assignlib(WRITE,&base_lib) /* may not already be assigned */ + +/* return straight away if nothing to load */ +%let nobs= %mf_getattrn(&append_lib..&append_dsn,NLOBS); +%if &nobs=-1 %then %do; + proc sql noprint; select count(*) into: nobs from &append_lib..&append_dsn; +%end; +%if &nobs=0 %then %do; + %put NOTE:; %put NOTE-;%put NOTE-;%put NOTE-; + %put NOTE- Base dataset &append_lib..&append_dsn is empty. Nothing to upload!; + %put NOTE-;%put NOTE-;%put NOTE-; + %return; +%end; + +/* hard exit if err condition exists */ +%mp_abort(iftrue= (&syscc > 0) + ,mac=bitemporal_dataloader + ,msg=%str(Bitemporal transform / job aborted due to SYSCC=&SYSCC status;) +) + +%local engine_type; +%let engine_type=%mf_getengine(&base_lib); +%if (&engine_type=REDSHIFT or &engine_type=POSTGRES) and %length(&CLOSE_VARS)>0 +%then %do; + %put NOTE:; %put NOTE-;%put NOTE-;%put NOTE-; + %put NOTE- CLOSE_VARS functionality not yet supported in &engine_type; + %put NOTE-;%put NOTE-;%put NOTE-; + %return; +%end; + +/** + * The metadata functions (eg mf_existvar) will fail if the base table has a + * SAS lock. So, make a snapshot of the base table for further use. + * Also, make output tables (regardless). + */ +%local basecopy; +%let basecopy=%mf_getuniquename(prefix=basecopy); + +data &basecopy &outds_mod &outds_add &outds_del; + set &base_lib..&base_dsn; + stop; +run; +%mp_abort(iftrue= (&syscc > 0) + ,mac=&_program + ,msg=%str(syscc=&syscc after base table copy - aborting due to table lock) +) + + +%local cols idx_pk md5_col ; +%let md5_col=___TMP___md5; +%let check_uniqueness=%upcase(&check_uniqueness); +%let RK_UPDATE_MAXKEYTABLE=%upcase(&RK_UPDATE_MAXKEYTABLE); +%let high_date=%unquote(&high_date); +%let loadtype=%upcase(&loadtype); + +/* ensure irrelevant variables are cleared */ +%if &loadtype=BUSTEMPORAL %then %do; + %let tech_from=; + %let tech_to=; +%end; +%else %if &loadtype=TXTEMPORAL or &loadtype=UPDATE %then %do; + %let bus_from=; + %let bus_to=; +%end; + +/* ensure relevant variables are supplied */ +%mp_abort(iftrue=(&loadtype=BITEMPORAL & %mf_verifymacvars(bus_from bus_to)=0) + ,mac=bitemporal_dataloader + ,msg=%str(Missing BUS_FROM / BUS_TO) +) +%mp_abort(iftrue=(&loadtype=TXTEMPORAL & %mf_verifymacvars(tech_from tech_to)=0) + ,mac=bitemporal_dataloader + ,msg=%str(Missing TECH_FROM / TECH_TO) +) + +/** + * drop any tables (may be defined as views or vice versa preventing overwrite) + */ +%mp_dropmembers(append bitemp0_append bitemp_cols) + +/* SQL Server requires its own time values */ +/* 9.2 will only give picture format down to seconds. 9.3 allows + milliseconds by using lower S and defining the decimal in the format name..*/ +PROC FORMAT; + picture MyMSdt other='%0Y-%0m-%0dT%0H:%0M:%0S' (datatype=datetime); +RUN; +%local dbnow; +%let dbnow="%sysfunc(datetime(),%mf_fmtdttm())"dt; + +data _null_; + /* convert space separated macvar to comma separated for SQL processing */ + call symputx('PK_COMMA',tranwrd(compbl("&pk"),' ',','),'L'); + call symputx('PK_CNT',countw("&pk",' '),'L'); + now=&dbnow; + call symputx('NOW',now,'L'); + call symputx('SQLNOW',cats("'",put(now,MyMSdt.),"'"),'L'); + length etlsource $100; + etlsource=subpad(symget('etlsource'),1,100); + call symputx('etlsource',etlsource,'l'); +run; + +/** + * Even if no PROCESSED var provided, assume that any variable named + * PROCESSED_DTTM should be updated + */ +%if &processed=0 %then %do; + %if %mf_existvar(&basecopy,PROCESSED_DTTM) + %then %let processed=PROCESSED_DTTM; + %else %let processed=; +%end; + + +/* extract colnames for md5 creation / change tracking */ +proc contents noprint data=&base_lib..&base_dsn + out=work.bitemp_cols (keep=name type length varnum format:); +run; +proc sql noprint; +select name into: cols separated by ',' + from work.bitemp_cols + where upcase(name) not in + (%upcase("&bus_from","&bus_to" + ,"&tech_from","&tech_to" + ,"&processed","&delete_col")) ; +select case when type in (2,6) then cats('put(md5(trim(',name,')),$hex32.)') + /* multiply by 1 to strip precision errors (eg 0 != 0) */ + /* but ONLY if not missing, else will lose any special missing values */ + else cats('put(md5(trim(put(ifn(missing(' + ,name,'),',name,',',name,'*1),binary64.))),$hex32.)') end + into: stripcols separated by '||' + from work.bitemp_cols + where upcase(name) not in + (%upcase("&bus_from","&bus_to" + ,"&tech_from","&tech_to" + ,"&processed","&delete_col")) ; + +/* set default formats*/ +%let bus_from_fmt = datetime19.; +%let bus_to_fmt = datetime19.; +%let processed_fmt = datetime19.; + +%let tech_from_fmt = format=datetime19.; +%let tech_to_fmt = format=datetime19.; + + +%put &=stripcols; +%put &=pk; + +data _null_; + set work.bitemp_cols; + if type=2 or type=6 then do; + length fmt $49.; + if format='' then fmt=cats('$',length,'.'); + else fmt=cats(format,formatl,'.'); + end; + else do; + if format='' then fmt=cats(length,'.'); + else fmt=cats(format,formatl,'.',formatd); + end; + if upcase(name)="%upcase(&bus_from)" then + call symputx('bus_from_fmt',fmt,'L'); + else if upcase(name)="%upcase(&bus_to)" then + call symputx('bus_to_fmt',fmt,'L'); + else if upcase(name)="%upcase(&tech_from)" then + call symputx('tech_from_fmt',"format="!!fmt,'L'); + else if upcase(name)="%upcase(&tech_to)" then + call symputx('tech_to_fmt',"format="!!fmt,'L'); + else if upcase(name)="%upcase(&processed)" then + call symputx('processed_fmt',fmt,'L'); +run; + +%if %index(%quote(&cols),___TMP___) %then %do; + %let msg=%str(Table contains a variable name containing "___TMP___".%trim( + ) This may conflict with temp variable generation!!); + %mp_abort(msg=&msg,mac=bitemporal_dataloader); + %let syscc=5; + %return; +%end; + +/* if transaction dates appear on the APPEND table, need to remove them */ +%local drop_tx_dates /* used in append table */ + drop_tx_dates_noobs /* used to take the base table structure */; +%if %mf_existvar(&append_lib..&append_dsn, &tech_from) + %then %let drop_tx_dates=&tech_from; +%if %mf_existvar(&append_lib..&append_dsn, &tech_to) + %then %let drop_tx_dates=&drop_tx_dates &tech_to; +%if %length(%trim(&drop_tx_dates))>0 + %then %let drop_tx_dates=(drop=&drop_tx_dates); + +%if %mf_existvar(&basecopy, &tech_from) + %then %let drop_tx_dates_noobs=&tech_from; +%if %mf_existvar(&basecopy, &tech_to) + %then %let drop_tx_dates_noobs=&drop_tx_dates_noobs &tech_to; +%if %length(%trim(&drop_tx_dates_noobs))>0 + %then %let drop_tx_dates_noobs=(drop=&drop_tx_dates_noobs obs=0); +%else %let drop_tx_dates_noobs=(obs=0); + + +/** + * Lock the table. This is necessary as we are doing a two part update (first + * closing records then appending new records). It is theoretically possible + * that an upload may occur whilst preparing the staging tables. And the + * staging tables are about to be prepared.. + */ +%if &LOADTARGET = YES %then %do; + %put locking &base_lib..&base_dsn; + %mp_lockanytable(LOCK, + lib=&base_lib,ds=&base_dsn,ref=&ETLSOURCE,ctl_ds=&dclib..mpe_lockanytable + ) + %if "&outds_audit" ne "0" %then %do; + %put locking &outds_audit; + %mp_lockanytable(LOCK + ,lib=%scan(&outds_audit,1,.) + ,ds=%scan(&outds_audit,2,.) + ,ref=&ETLSOURCE + ,ctl_ds=&dclib..mpe_lockanytable + ) + %end; +%end; +%else %do; + /* not an actual load, so avoid updating the max key table in next step. */ + %let rk_update_maxkeytable=NO; +%end; + +%if %length(&RK_UNDERLYING)>0 %then %do; + %mp_retainedkey( + base_lib=&base_lib + ,base_dsn=&base_dsn + ,append_lib=&append_lib + ,append_dsn=&append_dsn + ,retained_key=&pk + ,business_key=&rk_underlying + ,check_uniqueness=&CHECK_UNIQUENESS + ,outds=work.append + %if &rk_update_maxkeytable=NO %then %do; + ,maxkeytable=0 + %end; + %else %do; + ,maxkeytable=&dclib..&RK_MAXKEYTABLE + %end; + ,locktable=&dclib..mpe_lockanytable + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then %do; + ,filter_str=%str( (where=( &now < &tech_to)) ) + %end; + ) +%end; +%else %do; + proc sql; + create view work.append as select * from &append_lib..&append_dsn; +%end; +/** +* generate md5 for append table +*/ +/* it is possible the source dataset has additional (unwanted) columns. + Drop if specified; */ +%if %length(&keepvars)>0 %then %do; + /* remove tech dates from keepvars as they are generated later */ + %let keepvars=%sysfunc(tranwrd(%str( &keepvars ),%str( &tech_from ),%str( ))); + %let keepvars=%sysfunc(tranwrd(%str( &keepvars ),%str( &tech_to ),%str( ))); + %let keepvars=(keep=&keepvars &bus_from &bus_to &processed &md5_col); +%end; + +/* CAS varchar types cause append issues here, so perform autoconvert + by creating empty local table first */ +data; + set &base_lib..&base_dsn &drop_tx_dates_noobs; +run; +%local emptybasetable; %let emptybasetable=&syslast; + +data work.bitemp0_append &keepvars &outds_del(drop=&md5_col ) + %if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do; + /nonote2err + %end; + ; + /* apply formats for bitemporal vars but not tx dates which are added later */ + %if %length(&keepvars)>0 and &loadtype=BITEMPORAL %then %do; + format &bus_from &bus_from_fmt; + format &bus_to &bus_to_fmt; + %end; + set &emptybasetable /* base table reqd in case append has fewer cols */ + work.append &drop_tx_dates; + %if %length(%str(&bus_from_override))>0 %then %do; + &bus_from= %unquote(&bus_from_override) ; + %end; + %if %length(%str(&bus_to_override))>0 %then %do; + &bus_to= %unquote(&bus_to_override) ; + %end; + length &md5_col $32; + &md5_col=put(md5(&stripcols),hex32.); + %if %length(&processed)>0 %then %do; + format &processed &processed_fmt; + &processed=&now; + %end; + +/** + * If a delete column exists then create the delete dataset + */ +%if %mf_existvar(&append_lib..&append_dsn, &delete_col) %then %do; + drop &delete_col; + if upcase(&delete_col) = "YES" then output &outds_del ; + else output work.bitemp0_append ; + run; + + %if %mf_getattrn(&outds_del,NLOBS)>0 %then %do; + %bitemporal_closeouts( + tech_from=&tech_from + ,tech_to = &tech_to + ,base_lib=&base_lib + ,base_dsn=&base_dsn + ,append_lib=work + ,append_dsn=%scan(&outds_del,-1,.) + ,PK=&bus_from &pk + ,NOW=&dbnow + ,loadtarget=&loadtarget + ,loadtype=&loadtype + ) + %end; +%end; +%else %do; + output work.bitemp0_append; + run; +%end; + +%mp_abort(iftrue= (&syscc gt 0 at line 494) + ,mac=&_program + ,msg=%str(syscc=&syscc) +) + +%if %length(&close_vars)>0 %then %do; + /** + * need to close out records that are not provided + */ + proc sql; + create table bitemp1_closevars1 as + select distinct a.%mf_getquotedstr(in_str=&pk,dlm=%str(,a.),quote=) + from &base_lib..&base_dsn a + inner join work.bitemp0_append b + on 1=1 + /* join on closevars key */ + %do idx_pk=1 %to %sysfunc(countw(&close_vars)); + %let idx_val=%scan(&close_vars,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + /* filter base on tech dates if necessary */ + %if &loadtype=TXTEMPORAL %then %do; + where a.&tech_from <=&now and &now < a.&tech_to + %end; + ; + create table bitemp1_closevars2 as + select distinct a.* + from bitemp1_closevars1 a + left join work.bitemp0_append b + on 1=1 + /* join on primary key */ + %do idx_pk=1 %to %sysfunc(countw(&pk)); + %let idx_val=%scan(&pk,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + /* identify removed records by null value in a field in PK but not close_vars + */ + where b.%scan( + %mf_wordsInStr1ButNotStr2(Str1=&pk,Str2=&close_vars),1,%str( ) + ) IS NULL + ; + + %if %mf_getattrn(bitemp1_closevars2,NLOBS)>0 %then %do; + %bitemporal_closeouts( + tech_from=&tech_from + ,tech_to = &tech_to + ,base_lib=&base_lib + ,base_dsn=&base_dsn + ,append_lib=work + ,append_dsn=bitemp1_closevars2 + ,PK=&bus_from &pk + ,NOW=&dbnow + ,loadtarget=&loadtarget + ,loadtype=&loadtype + ) + %end; +%end; + +/* return if nothing to load (was just deletes) */ +%if %mf_getattrn(work.bitemp0_append,NLOBS)=0 %then %do; + %put NOTE:; %put NOTE-;%put NOTE-;%put NOTE-; + %put NOTE- No updates - just deletes!; + %put NOTE-;%put NOTE-;%put NOTE-; +%end; + + +/** + * If applying manual overrides to business dates, then the input table MUST + * be unique on the PK. Check, and if not - abort. + */ +%local msg; +%if %length(&bus_from_override.&bus_to_override)>0 or &CHECK_UNIQUENESS=YES +%then %do; + proc sort data=work.bitemp0_append out=work.bitemp0_check nodupkey; + by &pk; + run; + %if %mf_getattrn(work.bitemp0_check,NLOBS) + ne %mf_getattrn(work.bitemp0_append,NLOBS) + %then %do; + %let msg=INPUT table &append_lib..&append_dsn is not unique on PK (&pk); + %mp_lockanytable(UNLOCK,lib=&base_lib,ds=&base_dsn,ref=&ETLSOURCE (&msg), + ctl_ds=&dclib..mpe_lockanytable + ) + %mp_lockanytable(UNLOCK + ,lib=%scan(&outds_audit,1,.) + ,ds=%scan(&outds_audit,2,.) + ,ref=&ETLSOURCE + ,ctl_ds=&dclib..mpe_lockanytable + ) + %mp_abort(msg=&msg,mac=bitemporal_dataloader.sas); + %end; +%end; + + +/** +* extract from BASE table. Only want matching records, as could be very BIG. +* New records are subsequently identified via left join and test for nulls. +*/ +%local temp_table temp_table2 base_table baselib_schema; +%put DCNOTE: Extracting matching observations from &base_lib..&base_dsn; + +%if &engine_type=OLEDB %then %do; + %let temp_table=##BITEMP_&base_dsn; + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then + %let base_table=(select * from [dbo].&base_dsn + where convert(datetime,&SQLNOW) < &tech_to ); + %else %let base_table=[dbo].&base_dsn; + proc sql; + create table &base_lib.."&temp_table"n as + select * from work.bitemp0_append; + /* open up a connection for pass through SQL */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + create table work.bitemp0_base as select * from connection to myAlias( +%end; +%else %if &engine_type=REDSHIFT or &engine_type=POSTGRES %then %do; + /* grab schema */ + %let baselib_schema=%mf_getschema(&base_lib); + %if &baselib_schema.X ne X %then %let baselib_schema=&baselib_schema..; + + /* grab redshift config */ + %local redcnt; %let redcnt=0; + %if &engine_type=REDSHIFT %then %do; + data _null_; + set &config_table(where=(var_scope='DCBL_REDSH' and var_active=1)); + x+1; + call symputx(cats('rednm',x),var_value,'l'); + call symputx(cats('redval',x),var_value,'l'); + call symputx('redcnt',x,'l'); + run; + %end; + /* cannot persist temp tables so must create a temporary permanent table */ + %let temp_table=%mf_getuniquename(prefix=XDCTEMP); + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then + %let base_table=(select * from &baselib_schema.&base_dsn + where timestamp &sqlnow < &tech_to ); + %else %let base_table=&baselib_schema.&base_dsn; + /* make empty table first - must clone & drop extra cols as autoload is bad */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + + exec (create table &temp_table (like &baselib_schema.&base_dsn)) by myAlias; + %if &engine_type=REDSHIFT %then %do; + exec (alter table &temp_table alter sortkey none) by myAlias; + %end; + %local dropcols; + %let dropcols=%mf_wordsinstr1butnotstr2( + str1=%upcase(%mf_getvarlist(&basecopy)) + ,str2=%upcase(&pk) + ); + %if %length(&dropcols>0) %then %do idx_pk=1 %to %sysfunc(countw(&dropcols)); + %put &=dropcols; + %let idx_val=%scan(&dropcols,&idx_pk); + exec(alter table &temp_table drop column &idx_val;) by myAlias; + %end; + exec (alter table &temp_table add column &md5_col varchar(32);) by myAlias; + /* create view to strip formats and avoid warns in log */ + data work.vw_bitemp0/view=work.vw_bitemp0; + set work.bitemp0_append(keep=&pk &md5_col); + format _all_; + run; + proc append base=&base_lib..&temp_table + %if &engine_type=REDSHIFT %then %do; + ( + %do idx_pk=1 %to &redcnt; + &&rednm&idx_pk = &&redval&idxpk + %end; + ) + %end; + data=work.vw_bitemp0 force nowarn; + run; + /* open up a connection for pass through SQL */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + create table work.bitemp0_base as select * from connection to myAlias( +%end; +%else %if &engine_type=CAS %then %do; + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then + %let base_table=&base_lib..&base_dsn + (where=(&tech_from <=&now and &now < &tech_to)); + %else %let base_table=&base_lib..&base_dsn; + %let temp_table=CASUSER.%mf_getuniquename(prefix=DC); + data &temp_table; + set work.bitemp0_append; + run; + %let bitemp0base=CASUSER.%mf_getuniquename(prefix=DC); + proc fedsql sessref=dcsession; + create table &bitemp0base{options replace=true} as +%end; +%else %do; + %let temp_table=work.bitemp0_append; + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then + %let base_table=&base_lib..&base_dsn + (where=(&tech_from <=&now and &now < &tech_to)); + %else %let base_table=&base_lib..&base_dsn; + proc sql; + create table work.bitemp0_base as +%end; + + select a.&md5_col /* this identifies NEW records */ + , b.* + /* assume first PK field cannot be null (if defined in a PK constraint then + it definitely cannot be null) */ + , case when b.%scan(&pk,1) IS NULL then 1 else 0 end as ___TMP___NEW_FLG + from &baselib_schema.&temp_table a + left join &base_table b + on 1=1 +%do idx_pk=1 %to &pk_cnt; + %let idx_val=%scan(&pk,&idx_pk); + and a.&idx_val=b.&idx_val +%end; + + +%if &engine_type=OLEDB or &engine_type=REDSHIFT or &engine_type=POSTGRES +%then %do; + ); proc sql; drop table &base_lib.."&temp_table"n; +%end; +%else %if &engine_type=CAS %then %do; + ; + quit; + data work.bitemp0_base; + set &bitemp0base; + run; + proc sql; + drop table &temp_table; + drop table &bitemp0base; +%end; +%else %do; + ; +%end; + +/** +* matching & changed records are those without NULL key values +* &idx_val resolves to rightmost PK value (loop above) +*/ +%put syscc (line525)=&syscc, sqlrc=&sqlrc; +%mp_abort(iftrue= (&syscc gt 0 or &sqlrc>0) + ,mac=&_program + ,msg=%str(syscc=&syscc sqlrc=&sqlrc) +) + +%put hashcols2=&stripcols; +proc sql; +create table work.bitemp1_current(drop=___TMP___NEW_FLG) as + select * + , put(md5(&stripcols),$hex32.) as &md5_col + from work.bitemp0_base (drop=&md5_col) + where ___TMP___NEW_FLG=0; + +/** +* NEW records were identified in ___TMP___NEW_FLG in bitemp0_base +*/ +proc sql; +create table &outds_add + (drop=&md5_col + %if %mf_existvar(work.bitemp0_base, &delete_col) %then %do; + &delete_col + %end; + ) + as select a.* + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then %do; + ,&now as &tech_from &tech_from_fmt + ,&high_date as &tech_to &tech_to_fmt + %end; + from work.bitemp0_append a /* STAGING records (mix of existing & new) */ + , work.bitemp0_base b /* BASE records (contains null values for new) */ + where a.&md5_col=b.&md5_col /* took staging md5 across in left join */ + and b.___TMP___NEW_FLG=1; /* NEW records also identified in bitemp0_base */ + + +/** +* identify INSERTS. These are records with the same business key but +* the bus_from and bus_to value are higher / lower (respectively) +* such that the existing record needs to be SPLIT to surround the new +* record. +* eg: OLD RECORD from=1 to=10 +* NEW RECORD from=5 to=7 +* +* APPENDED RECORDS: +* - from=1 to=5 +* - from=5 to=7 +* - from=7 to=10 +*/ + +/* inserts cannot happen with TXTEMPORAL */ +%if &loadtype=BITEMPORAL or &loadtype=BUSTEMPORAL %then %do; + /* IDENTIFY */ + create table work.bitemp3_inserts as + select b.* + ,a.&bus_from as ___TMP___from + ,a.&bus_to as ___TMP___to + from work.bitemp0_append a + ,work.bitemp1_current b + where a.&bus_from > b.&bus_from + and a.&bus_to < b.&bus_to + %do idx_pk=1 %to &pk_cnt; + %let idx_val=%scan(&pk,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + order by + /* compress blanks and then insert commas (as the datetime fields may + not be in use) */ + %sysfunc(tranwrd(%sysfunc(compbl( + &pk &bus_from &bus_to &processed + )),%str( ), %str(,))) + ; + + /* SPLIT */ + data work.bitemp3a_inserts (drop=___TMP___from ___TMP___retain ___TMP___to) ; + set work.bitemp3_inserts; + by &pk &bus_from &bus_to &processed; + if first.&idx_val then do; + ___TMP___retain=&bus_to; + &bus_to=___TMP___from; + output; + &bus_to=___TMP___retain; + end; + if last.&idx_val then do; + &bus_from=___TMP___to; + output; + end; + run; +%end; +%else %do; + /* TX temporal load */ + data work.bitemp3a_inserts; + set work.bitemp1_current; + stop; + run; +%end; +/* APPEND */ +proc sql; +create view work.bitemp3a_view as + select * from work.bitemp1_current + where &md5_col not in (select &md5_col from work.bitemp3a_inserts); + +data bitemp3b_newbase; + set work.bitemp3a_inserts work.bitemp3a_view; +run; + +/** do not use! this converts short numerics into 8 bytes +proc sql; +create table work.bitemp3b_newbase as + select * from work.bitemp3a_inserts +union corr + select * from work.bitemp1_current + where &md5_col not in (select &md5_col from work.bitemp3a_inserts); +*/ + +/** +* identify CHANGED records from staging. +* Same business key with different temporal dates or md5 value +* This table must be overlayed onto / into existing business history +*/ +proc sql; +create table work.bitemp4_updated as select distinct a.* + from work.bitemp0_append a + ,work.bitemp3b_newbase b + where 1=1 + %do idx_pk=1 %to &pk_cnt; + %let idx_val=%scan(&pk,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + and ( a.&md5_col ne b.&md5_col + %if &loadtype=BITEMPORAL or &loadtype=BUSTEMPORAL %then %do; + OR (a.&bus_from ne b.&bus_from or a.&bus_to ne b.&bus_to) + %end; + ) +; + +/** + * This section would have been one simple step with union all + * but that converts short numerics into 8 bytes! + * so, convoluted alternative to retain the same functionality. + */ + +/* base records */ +create view work.bitemp4_prep1 as + select 'BASE' as ___TMP___ + ,b.* + from work.bitemp4_updated a + ,work.bitemp3b_newbase b + where 1 + %do idx_pk=1 %to &pk_cnt; + %let idx_val=%scan(&pk,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + ; +/* updated records */ +create view work.bitemp4_prep2 as + select 'STAG' as ___TMP___ ,* + from work.bitemp4_updated; +/* ensure we only keep columns that appear in both */ +%local bp1 bp2 bp3 bp4; +%let bp1=%mf_getvarlist(bitemp4_prep1); +%let bp2=%mf_getvarlist(bitemp4_prep2); +%let bp3=%mf_wordsInStr1ButNotStr2(Str1=&bp1,Str2=&bp2); +%let bp4=%mf_wordsInStr1ButNotStr2(Str1=&bp2,Str2=&bp1); +data work.bitemp4_prep3/view=bitemp4_prep3; + set bitemp4_prep1 bitemp4_prep2; +%if %length(XX&bp3&bp4)>2 %then %do; + drop &bp3 &bp4 ; +%end; +run; +/* remove duplicates */ +proc sql; +create table work.bitemp4a_allrecs as + select distinct * + from work.bitemp4_prep3 + order by + /* compress blanks and then insert commas (as the datetime fields + may not be in use) */ + %sysfunc(tranwrd(%sysfunc(compbl( + &pk &bus_from &bus_to &processed + )),%str( ), %str(,))) + ; + +%if &loadtype=BITEMPORAL or &loadtype=BUSTEMPORAL %then %do; + /* this section aligns the business dates + (eg for inserts or overlaps in the range) */ + data work.bitemp4b_firstpass (drop=___TMP___cond ___TMP___from ___TMP___to ); + set work.bitemp4a_allrecs; + by &pk &bus_from &bus_to &processed; + retain ___TMP___cond 'Name of Condition'; + retain ___TMP___from ___TMP___to 0; + ___TMP___md5lag=lag(&md5_col); + /* reset retained variables */ + if first.&idx_val then do; + call missing (___TMP___cond, ___TMP___from, ___TMP___to,___TMP___md5lag); + end; + else do; + /* if record is identical, carry forward bus_from (and bus_to if higher)*/ + if &md5_col=___TMP___md5lag then do; + &bus_from=___TMP___from; + if &bus_to<___TMP___to then &bus_to=___TMP___to; + end; + end; + + if ___TMP___='STAG' then do; + /* need to carry forward the closing record */ + ___TMP___cond='Condition 1'; + end; + else if ___TMP___cond='Condition 1' then do; + /* else ensure bus_from starts from prior record bus_to */ + if &md5_col ne ___TMP___md5lag and &bus_from <= ___TMP___to + then &bus_from= ___TMP___to; + /* new record may replace old record entirely */ + if &bus_to <= &bus_from then delete; + else call missing (___TMP___cond, ___TMP___from, ___TMP___to); + end; + ___TMP___from=&bus_from; + ___TMP___to=&bus_to; + run; +%end; +%else %do; + /* keep staged records only */ + data work.bitemp4b_firstpass; + set work.bitemp4a_allrecs; + if ___TMP___='STAG'; + run; +%end; + +/* next phase is to pass through in reverse - so set up the sort statement */ +%local byvar; +%do idx_pk=1 %to &pk_cnt; + %let byvar=&byvar descending %scan(&pk,&idx_pk); +%end; +%if &loadtype=BITEMPORAL or &loadtype=BUSTEMPORAL +%then %let byvar=&byvar descending &bus_from descending &bus_to; +/* if matching bus dates supplied, need to ensure we also have a sort + between BASE and STAGING tables */ +%let byvar=&byvar descending ___TMP___; + +proc sort data=work.bitemp4b_firstpass out=work.bitemp4c_sort ; + by &byvar; +run; + +/** +* Now (in reverse) pass back business start dates +*/ +data work.bitemp4d_secondpass; +%if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then %do; + &tech_from=&now; + &tech_to=&high_date; +%end; + set work.bitemp4c_sort ; + by &byvar; + retain ___TMP___cond 'Name of Condition'; + retain ___TMP___from ___TMP___to 0; +%if &loadtype=BITEMPORAL or &loadtype=BUSTEMPORAL %then %do; +/* put / _all_ /;*/ + ___TMP___md5lag=lag(&md5_col); + if first.&idx_val then do; + /* reset retained variables */ + call missing (___TMP___cond,___TMP___from,___TMP___to,___TMP___md5lag); + end; + else do; + /* if record is identical, carry back bus_to */ + if &md5_col=___TMP___md5lag then &bus_to=___TMP___to; + end; + + if ___TMP___='STAG' then do; + /* need to carry forward the closing record */ + ___TMP___cond='Condition 2'; + end; + else if ___TMP___cond='Condition 2' then do; + /* else ensure bus_to stops at subsequent record bus_from */ + if &md5_col ne ___TMP___md5lag and &bus_to >= ___TMP___from + then &bus_to= ___TMP___from; + /* new record may replace old record entirely */ + if &bus_from >= &bus_to then delete; + if &bus_from=___TMP___from and &bus_to=___TMP___to then delete; + else call missing (___TMP___cond, ___TMP___from, ___TMP___to); + end; + ___TMP___from=&bus_from; + ___TMP___to=&bus_to; + +%end; +run; +%put syscc (line600)=&syscc; +/** + There may still be some records (eg old business history) which have not + changed. + Need to identify these and remove from the append so they are not updated + unnecessarily. This is done by generating a new md5 (which INCLUDES the + business key) and any matching / identical records are split out (from those + that need to be updated). +*/ + +%if &loadtype=BITEMPORAL %then %do; + %let cat_string=catx('|' ,&bus_from,&bus_to); + + data bitemp5a_lkp (keep=&md5_col); + set bitemp0_base; + /* for BITEMPORAL we need to compare business dates also */ + &md5_col=put(md5(&cat_string!!'|'!!&stripcols),$hex32.); + run; + + data bitemp5b_updates; + set bitemp4d_secondpass; + if _n_=1 then do; + dcl hash md5_lkp(dataset:'bitemp5a_lkp'); + md5_lkp.definekey("&md5_col"); + md5_lkp.definedone(); + end; + /* drop old md5 col as will rebuild with new business dates */ + &md5_col=put(md5(&cat_string!!'|'!!&stripcols),$hex32.) ; + if md5_lkp.check()=0 then delete; + run; + + proc sql; + /* get min bus from as will update (close out) all records from this point + (for that PK)*/ + create table work.bitemp5d_subquery as + select &pk_comma, min(&bus_from)as &bus_from, max(&bus_to) as &bus_to + from work.bitemp5b_updates + group by &pk_comma; + /* index has a huge efficiency impact on upcoming nested subquery */ + create index index1 on work.bitemp5d_subquery(&pk_comma,&bus_from, &bus_to); + + %let lastds=work.bitemp5b_updates; +%end; +%else %if &loadtype=TXTEMPORAL or &loadtype=UPDATE %then %do; + proc sql; + create table work.bitemp5d_subquery as + select distinct &pk_comma + from bitemp4d_secondpass; + %let lastds=work.bitemp4d_secondpass; +%end; +%else %let lastds=work.bitemp4d_secondpass; + +/* create single append table (an overlapped pre-sert may be classed as + both an update AND a new record). Also create temp views that may be + used for pre-load analysis. */ +data &outds_mod; + set &lastds(drop=___TMP___: &md5_col); +run; + +data bitemp6_allrecs / view=bitemp6_allrecs; + set &outds_mod /* UPDATED records */ + &outds_add /* NEW records */; +run; + +proc sort data=work.bitemp6_allrecs + out=work.bitemp6_unique + noduprec + dupout=work.xx_BADBADBAD; +by _all_; +run; + +/* we have all our temp tables now so exit if this is all that is needed */ +%if &LOADTARGET ne YES %then %return; + +/* also exit if an err condition exists */ + +%if &syscc>0 %then %do; + %put syscc=&syscc; + %mp_lockanytable(UNLOCK,lib=&base_lib,ds=&base_dsn,ref=&ETLSOURCE, + ctl_ds=&dclib..mpe_lockanytable + ) + %if "&outds_audit" ne "0" %then %do; + %mp_lockanytable(UNLOCK + ,lib=%scan(&outds_audit,1,.) + ,ds=%scan(&outds_audit,2,.) + ,ref=&ETLSOURCE + ,ctl_ds=&dclib..mpe_lockanytable + ) + %end; +%end; +%mp_abort(iftrue= (&syscc>0) + ,mac=&sysmacroname in &_program + ,msg=%str(Bitemporal transform / job aborted due to SYSCC=&SYSCC status) +) + +/* final check - abort if a lock has appeared on the target or audit table */ +%mp_lockfilecheck(libds=&base_lib..&base_dsn) +%if %mf_existds(&outds_audit) %then %do; + %mp_lockfilecheck(libds=&outds_audit) +%end; + +/** +* STAGING TABLES PREPARED, ERR CONDITION TESTED FOR.. NOW TO LOAD!! +*/ + +/** +* First, CLOSE OUT changed records (if not a REPLACE) +* Note that SAS does not support ANSI standard for UPDATE with a join condition. +* However - this can be worked around using a nested subquery.. +*/ +data _null_; + putlog "&sysmacroname: CLOSEOUTS commencing"; +run; + +%if %mf_getattrn(&lastds,NLOBS)=0 %then %do; + data _null_; + putlog "&sysmacroname: No closeouts needed"; + run; +%end; +%else %if &engine_type=CAS %then %do; + %mp_abort(iftrue= (&loadtype=BITEMPORAL or &loadtype=TXTEMPORAL) + ,mac=&sysmacroname in &_program + ,msg=%str(&loadtype not yet supported in CAS engine) + ) + /* create temp table for deletions */ + %local delds;%let delds=%mf_getuniquename(prefix=DC); + data casuser.&delds; + set work.bitemp5d_subquery; + run; + /* delete the records */ + proc cas ; + table.deleteRows / table={ + caslib="&base_lib", + name="&base_dsn", + where="1=1", + whereTable={caslib='CASUSER',name="&delds"} + }; + quit; + /* drop temp table */ + proc sql; + drop table CASUSER.&delds; +%end; +%else %if (&loadtype=BITEMPORAL or &loadtype=TXTEMPORAL or &loadtype=UPDATE) +%then %do; + data _null_; + putlog "&sysmacroname: &loadtype operation using &engine_type engine"; + run; + %local flexinow; + proc sql; + /* if OLEDB then create a temp table for efficiency */ + %local innertable; + %if &engine_type=OLEDB %then %do; + %let innertable=[##BITEMP_&base_dsn]; + %let top_table=[dbo].&base_dsn; + %let flexinow=&SQLNOW; + create table &base_lib.."##BITEMP_&base_dsn"n as + select * from work.bitemp5d_subquery; + /* open up a connection for pass through SQL */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + execute( + %end; + %else %if &engine_type=REDSHIFT or &engine_type=POSTGRES %then %do; + %let innertable=%mf_getuniquename(prefix=XDCTEMP); + %let top_table=&baselib_schema.&base_dsn; + %let flexinow=timestamp &SQLNOW; + /* make empty table first - must clone & drop extra cols + as autoload is bad */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + exec (create table &innertable (like &baselib_schema.&base_dsn)) by myAlias; + %if &engine_type=REDSHIFT %then %do; + exec (alter table &innertable alter sortkey none) by myAlias; + %end; + %let dropcols=%mf_wordsinstr1butnotstr2( + str1=%upcase(%mf_getvarlist(&basecopy)) + ,str2=%upcase(%mf_getvarlist(work.bitemp5d_subquery)) + ); + %if %length(&dropcols>0) %then %do idx_pk=1 %to %sysfunc(countw(&dropcols)); + %put &=dropcols; + %let idx_val=%scan(&dropcols,&idx_pk); + exec(alter table &innertable drop column &idx_val;) by myAlias;; + %end; + /* create view to strip formats and avoid warns in log */ + data work.vw_bitemp5d/view=work.vw_bitemp5d; + set work.bitemp5d_subquery; + format _all_; + run; + proc append base=&base_lib..&innertable ( + %do idx_pk=1 %to &redcnt; + &&rednm&idx_pk = &&redval&idxpk + %end; + ) + data=work.vw_bitemp5d force nowarn; + run; + /* open up a connection for pass through SQL */ + %dc_assignlib(WRITE,&base_lib,passthru=myAlias) + execute( + %end; + %else %do; + %let innertable=bitemp5d_subquery; + %let top_table=&base_lib..&base_dsn; + %let flexinow=&now; + %end; + + + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then %do; + update &top_table set &tech_to=&flexinow + %if %length(&processed)>0 %then %do; + ,&processed=&flexinow + %end; + where &tech_from <= &flexinow and &flexinow < &tech_to and + %end; + %else %if &loadtype=UPDATE %then %do; + /* changed records are deleted then re-appended when doing UPDATEs */ + delete from &top_table where + %end; + %else %do; + %put %str(ERR)OR: BUSTEMPORAL NOT YET SUPPORTED; + %let syscc=5; + %mp_lockanytable(UNLOCK,lib=&base_lib,ds=&base_dsn,ref=&ETLSOURCE, + ctl_ds=&dclib..mpe_lockanytable + ) + %mp_lockanytable(UNLOCK + ,lib=%scan(&outds_audit,1,.) + ,ds=%scan(&outds_audit,2,.) + ,ref=&ETLSOURCE + ,ctl_ds=&dclib..mpe_lockanytable + ) + %goto end_of_macro; + %end; + + /* perform join inside query as per + http://stackoverflow.com/questions/24629793/update-with-a-proc-sql */ + + exists( select 1 from &baselib_schema.&innertable where + + /* loop PK join */ + %do idx_pk=1 %to &pk_cnt; + %let idx_val=%scan(&pk,&idx_pk); + &base_dsn..&idx_val=&innertable..&idx_val and + %end; + %if &loadtype=BITEMPORAL %then %do; + &base_dsn..&bus_from >= &innertable..&bus_from + and &base_dsn..&bus_to <= &innertable..&bus_to and + %end; + + /* close the statement */ + + 1=1); + + %if &engine_type=OLEDB or &engine_type=REDSHIFT or &engine_type=POSTGRES + %then %do; + ) by myAlias; + execute (drop table &baselib_schema.&innertable) by myAlias; + %end; +%end; +quit; +data _null_; + putlog "&sysmacroname: Closeout complete"; +run; +/** + * Append the new / updated records + */ +%if &engine_type=CAS %then %do; + + /* get varchar variables ready for casting */ + %local vcfmt vcrename vcassign vcdrop; + data _null_; + set work.bitemp_cols(where=(type=6)) end=last; + length vcrename vcassign vcdrop vcfmt $32767 rancol $32; + retain vcrename vcassign vcdrop vcfmt; + if _n_=1 then vcrename='(rename=('; + rancol=resolve('%mf_getuniquename()'); + vcfmt=trim(vcfmt)!!'length '!!cats(name)!!' varchar(*);'; + vcrename=trim(vcrename)!!' '!!cats(name,'=',rancol); + vcassign=cats(vcassign,name,'=',rancol,';'); + vcdrop=cats(vcdrop,'drop '!!rancol,';'); + if last then do; + vcrename=cats(vcrename,'))'); + call symputx('vcfmt',vcfmt); + call symputx('vcrename',vcrename); + call symputx('vcassign',vcassign); + call symputx('vcdrop',vcdrop); + end; + run; + + /* prepare a temp cas table with varchars casted */ + %let tmp=%mf_getuniquename(); + data casuser.&tmp ; + &vcfmt + set work.bitemp6_unique &vcrename; + &vcassign + &vcdrop + run; + + /* load the table with varchars applied*/ + data &base_lib..&base_dsn (append=yes )/sessref=dcsession ; + set casuser.&tmp; + run; + + /* drop temp table */ + proc sql; + drop table CASUSER.&tmp; + + /* this code will not work as regular tables do not have varchars */ + /* + proc casutil; + load data=work.bitemp6_unique + outcaslib="&base_lib" casout="&base_dsn" append ; + quit; + */ +%end; +%else %if &engine_type=REDSHIFT or &engine_type=POSTGRES %then %do; + proc append base=&base_lib..&base_dsn + %if &engine_type=REDSHIFT %then %do; + ( + %do idx_pk=1 %to &redcnt; + &&rednm&idx_pk = &&redval&idxpk + %end; + ) + %end; + data=bitemp6_unique force nowarn; + run; +%end; +%else %do; + proc append base=&base_lib..&base_dsn data=bitemp6_unique force nowarn; run; +%end; + +%mp_lockanytable(UNLOCK,lib=&base_lib,ds=&base_dsn,ref=&ETLSOURCE, + ctl_ds=&dclib..mpe_lockanytable +) + +/* final check on syscc */ +%mp_abort(iftrue= (&syscc >4) + ,mac=&_program + ,msg=%str(!!Upload NOT successful!! Failed on actual update / append stage..) +) + +%if &outds_audit ne 0 and &LOADTARGET=YES %then %do; + data work.vw_outds_orig /view=work.vw_outds_orig; + set work.bitemp0_base (drop=&md5_col); + where ___TMP___NEW_FLG=0; + drop ___TMP___NEW_FLG; + run; + /* update the AUDIT table */ + %if %mf_existds(&outds_audit) %then %do; + options mprint; + %mp_storediffs(&base_lib..&base_dsn + ,work.vw_outds_orig + ,&pk &bus_from + ,delds=&outds_del + ,modds=&outds_mod + ,appds=&outds_add + ,outds=work.mp_storediffs + ,processed_dttm=&now + ,loadref=%superq(etlsource) + ) + data _null_; + set work.mp_storediffs; + putlog load_ref= libref= dsn= key_hash= tgtvar_nm=; + run; + proc append base=&outds_audit data=work.mp_storediffs; + run; + %mp_lockanytable(UNLOCK + ,lib=%scan(&outds_audit,1,.) + ,ds=%scan(&outds_audit,2,.) + ,ref=&ETLSOURCE + ,ctl_ds=&dclib..mpe_lockanytable + ) + %end; +%end; +%mp_abort(iftrue= (&syscc >4) + ,mac=bitemporal_dataloader + ,msg=%str(Problem in audit stage (&outds_audit)) +) + +%let user=%mf_getUser(); +/** + Notify as appropriate EMAILS DISABLED + +%sumo_alerts(ALERT_EVENT=UPDATE + , ALERT_TARGET=&base_lib..&base_dsn + , from_user= &user); +*/ +/* monitor BiTemporal usage */ +%if &log=1 %then %do; + %put syscc=&syscc; + /* do not perform duration calc in pass through */ + %local dur; + data _null_; + now=symget('now'); + dur=%sysfunc(datetime())-&now; + call symputx('dur',dur,'l'); + run; + proc sql; + insert into &dclib..mpe_dataloads + set libref=%upcase("&base_lib") + ,DSN=%upcase("&base_dsn") + ,ETLSOURCE="&ETLSOURCE" + ,LOADTYPE="&loadtype" + ,CHANGED_RECORDS=%mf_getattrn(&lastds,NLOBS) + ,NEW_RECORDS=%mf_getattrn(&outds_add,NLOBS) + ,DELETED_RECORDS=%mf_getattrn(&outds_del,NLOBS) + ,DURATION=&dur + ,MAC_VER="v&ver" + ,user_nm="&user" + ,PROCESSED_DTTM=&now; + quit; + %put syscc=&syscc; +%end; +%end_of_macro: +%mend bitemporal_dataloader; diff --git a/sas/sasjs/macros/bitemporal_dataloader.test.1.sas b/sas/sasjs/macros/bitemporal_dataloader.test.1.sas new file mode 100644 index 0000000..2eafd07 --- /dev/null +++ b/sas/sasjs/macros/bitemporal_dataloader.test.1.sas @@ -0,0 +1,87 @@ +/** + @file + @brief Test Harness for bitemporal dataloader + @details see below for usage: + + options mprint; + options insert=(sasautos="/pub/programs/macrocore/base"); + options insert=(sasautos="/pub/programs/macrocore/meta"); + options insert=(sasautos="/pub/programs/datacontroller/macros"); + + %mpeinit() + + %bitemporal_tester(test=1) + + TODO - add short numerics!!! + + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mp_assert.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%let syscc=0; +%let now=%sysfunc(datetime()); +%let high_date='31DEC8888:23:59:59'dt; + +/* create base table */ +data basetable; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1'; + eff_from_dttm=0; eff_to_dttm=&now-10000; field1='somevalue'; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; field1='newvalue'; + field2='somenewvalue'; output; +run; + +data appendtable; + if 0 then set basetable; + eff_from_dttm=&now-500; eff_to_dttm=&now+500; pk='PK1'; field1='blah'; + field2='blah';output; + call symputx('x',repeat('x',200)); +run; +libname work2(work); + +/* create mpe_dataloads table */ +proc sql; +create table work.mpe_dataloads( + libref varchar(8) , + dsn varchar(32) , + etlsource varchar(100) , + loadtype varchar(20) , + changed_records int, + new_records int, + deleted_records int, + duration num, + user_nm varchar(50) , + processed_dttm num format=datetime19.3, + mac_ver varchar(5) +);quit; +proc datasets lib=work noprint; + modify mpe_dataloads; + index create + pk_mpe_dataloads=(processed_dttm libref dsn etlsource) + /nomiss unique; +quit; + +%bitemporal_dataloader(dclib=work2 + ,processed= + ,PK=pk + ,ETLSOURCE=&x + ,base_dsn=BASETABLE + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=1 +) + +%mp_assert(iftrue=(&syscc=0), + desc=Testing long ETLSOURCE value +) + + diff --git a/sas/sasjs/macros/bitemporal_dataloader.test.2.sas b/sas/sasjs/macros/bitemporal_dataloader.test.2.sas new file mode 100755 index 0000000..92dee25 --- /dev/null +++ b/sas/sasjs/macros/bitemporal_dataloader.test.2.sas @@ -0,0 +1,1536 @@ +/** + @file + @brief Test Harness for bitemporal dataloader + @details see below for usage: + + options mprint; + options insert=(sasautos="/pub/programs/macrocore/base"); + options insert=(sasautos="/pub/programs/macrocore/meta"); + options insert=(sasautos="/pub/programs/datacontroller/macros"); + + %mpeinit() + + %bitemporal_tester(test=1) + + TODO - add short numerics!!! + + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li dc_assignlib.sas + @li mf_getattrn.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +proc sql; +create table work.maxkeytable +( + KEYTABLE char(41) format=$41. + label='Key table in 2 part format (libref.dataset)', + KEYCOLUMN char(32) format=$32. + label='The Surrogate / Retained key field containing the key values.', + MAX_KEY num format=8. + label= + 'Integer value representing current max RK or SK value in the KEYTABLE', + PROCESSED_DTTM num format=DATETIME21. + label='Datetime this value was last updated' +); +proc sql; +create table work.mpe_lockanytable( + lock_lib char(8), + lock_ds char(32), + lock_status_cd char(10) , + lock_user_nm char(100) , + lock_ref char(200), + lock_pid char(10), + lock_start_dttm num format=E8601DT26.6, + lock_end_dttm num format=E8601DT26.6 +); +quit; +proc datasets lib=work noprint; + modify mpe_lockanytable; + index create + pk_mpe_lockanytable=(lock_lib lock_ds) + /nomiss unique; +quit; + + +%let syscc=0; +%let now=%sysfunc(datetime()); +%let high_date='31DEC8888:23:59:59'dt; + +/* create base table */ +data basetable; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1'; + eff_from_dttm=0; eff_to_dttm=&now-10000; field1='somevalue'; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; field1='newvalue'; + field2='somenewvalue'; output; +run; +/* create results table */ +data results; + format test $7. result $4. reason $50.; stop; +run; + +%put assigning lib..; +%dc_assignlib(WRITE,&dc_libref) + +%macro bitemporal_tester(test=ALL); +%let test=%upcase(&test); + +%if &test=ALL or &test=1 %then %do; + /* test 1 - new record */ + data basetable1; set basetable;run; + data appendtable; + if 0 then set basetable; + eff_from_dttm=&now; eff_to_dttm=&high_date; pk='PK1'; field1='blah'; + field2='blah'; + output; + run; + %bitemporal_dataloader(dclib=work + ,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test1 + ,base_dsn=BASETABLE1 + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + %if %mf_getattrn(basetable1,NLOBS)=4 %then %let test1=PASS; + %else %let test1=FAIL; + proc sql; + insert into results set test='TEST001',result="&test1"; +%end; + +%if &test=ALL or &test=2 %then %do; + /* test 2 - insert record */ + data basetable2; set basetable;run; + data appendtable; + if 0 then set basetable; + eff_from_dttm=&now-500; eff_to_dttm=&now+500; pk='PK1'; field1='blah'; + field2='blah'; + run; + %bitemporal_dataloader(dclib=work + ,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test2 + ,base_dsn=BASETABLE2 + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + %if %mf_getattrn(basetable2,NLOBS)=5 %then %let test2=PASS; + %else %let test2=FAIL; + proc sql; + insert into results set test='TEST002',result="&test2"; +%end; + +%if &test=ALL or &test=3 %then %do; + /* test 3 - wide table (350 columns) */ + data basetable3; set basetable; + format var1-var350 $40.; + %do x=1 %to 350; + var&x=subpad("this will be a loooong string!!",1,40); + %end; + run; + data appendtable; + if 0 then set basetable3; + eff_from_dttm=&now-500; eff_to_dttm=&now+500; pk='PK1'; field1='blah'; + field2='blah'; + run; + %bitemporal_dataloader(dclib=work,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test3 wide + ,base_dsn=BASETABLE3 + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + %if %mf_getattrn(basetable3,NLOBS)=5 %then %let test3=PASS; + %else %let test3=FAIL; + proc sql; + insert into results set test='TEST003',result="&test3"; +%end; + +/* test 4 - Txtemporal update */ +%if &test=ALL or &test=4 %then %do; + /* test 3 - wide table (50 columns) */ + proc sort data= basetable (drop=eff:) out=basetable4 nodupkey; + by tx_from_dttm pk; + run; + data appendtable; + if 0 then set basetable4; + pk='PK1'; field1='blah'; field2='blah'; + run; + %bitemporal_dataloader(dclib=work,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test3 wide + ,base_dsn=BASETABLE4 + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOADTYPE=TXTEMPORAL + ,LOG=NO); + %if %mf_getattrn(basetable4,NLOBS)=2 %then %let test4=PASS; + %else %let test4=FAIL; + proc sql; + insert into results set test='TEST004',result="&test4"; +%end; + +/* test 5 - Numeric variables */ +%if &test=ALL or &test=5 %then %do; + data basetable5; set basetable; + val1=ranuni(0); val2=ranuni(0); + run; + data appendtable; + if 0 then set basetable5; + eff_from_dttm=&now; eff_to_dttm=&high_date; + pk='PK1'; field1='blah'; field2='blah';val1=ranuni(0); val2=ranuni(0); + run; + %bitemporal_dataloader(dclib=work,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test&test wide + ,base_dsn=BASETABLE5 + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + %if %mf_getattrn(basetable5,NLOBS)=4 %then %let test5=PASS; + %else %let test5=FAIL; + proc sql; + insert into results set test='TEST005',result="&test5"; +%end; + +/* test 6 - change business dates but nothing else */ +%if &test=ALL or &test=6 %then %do; + %let testnum=6; + data basetable6 basetable6_show; + eff_from_dttm=0; eff_to_dttm=&high_date;tx_from_dttm=0; + tx_to_dttm=&high_date; + PK='PK1';field1='test';field2='test'; + run; + data appendtable; + set basetable6; + eff_from_dttm=&now; eff_to_dttm=&now+11111; + run; + run; + %bitemporal_dataloader(dclib=work,processed= + ,PK=pk + ,ETLSOURCE=bitemporal_tester test&testnum wide + ,base_dsn=BASETABLE&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + %if %mf_getattrn(basetable&testnum,NLOBS)=1 %then %let test&testnum=PASS; + %else %let test&testnum=FAIL; + proc sql; + insert into results set test="TEST00&testnum",result="&&test&testnum"; +%end; + +/* test 7 - provide hard coded bus_from and to dates (override) */ +%if &test=ALL or &test=7 %then %do; + %let testnum=7; + data basetable&testnum basetable&testnum._show; + format comment $1000.; + set basetable end=last; + output; + if last then do; + PK='2'; field1='base';field2='base'; + comment='will be preceded (so should not be closed out)';output; + PK='4'; field1='base'; field2='base';eff_from_dttm=4; eff_to_dttm=40; + comment='will be overwritten (overlapped) '; output; + PK='5'; field1='base'; field2='base';eff_from_dttm=0; + eff_to_dttm='31DEC9999:23:59:59'dt; + comment='will not be replaced'; output; + end; + run; + data appendtable; + if 0 then set basetable&testnum; + PK='PK1'; field1='Pk_test7'; field2='test7'; + comment='inserted record ';output; + PK='2'; field1='test7_changed'; field2='test7'; + comment='precedes record'; output; + PK='3'; field1='new7'; field2='new7';comment='new field';output; + PK='4'; field1='new'; field2='new';comment='replaces';output; + PK='5'; field1='base'; field2='base'; comment='will not be replaced';output; + run; + %bitemporal_dataloader(dclib=work,processed= + ,PK=pk + ,bus_from_override=2 + ,bus_to_override=999999999 + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,RK_MAXKEYTABLE=maxkeytable + ,LOG=NO); + %if %mf_getattrn(basetable&testnum,NLOBS)=11 %then %let test&testnum=PASS; + %else %let test&testnum=FAIL; + proc sql; + insert into results set test="TEST00&testnum",result="&&test&testnum"; +%end; + +/* test 8 - RK generator */ +%if &test=ALL or &test=8 %then %do; + %let testnum=8; + data basetable&testnum basetable&testnum._show; + format comment $1000.; + set basetable end=last; + RK=4; + output; + if last then do; + RK+1;PK='2'; field1='base';field2='base'; + comment='will be preceded (so should not be closed out)';output; + RK+1;PK='4'; field1='base'; field2='base';eff_from_dttm=4; + eff_to_dttm=40; + comment='will be overwritten (overlapped) '; output; + RK+1;PK='5'; field1='base'; field2='base';eff_from_dttm=0; + eff_to_dttm='31DEC9999:23:59:59'dt; + comment='will not be replaced'; output; + end; + run; + data appendtable; + if 0 then set basetable&testnum ; + PK='PK1'; field1='Pk_test7'; field2='test7'; + comment='inserted record ';output; + PK='2'; field1='test7_changed'; field2='test7'; + comment='precedes record'; output; + PK='3'; field1='new7'; field2='new7';comment='new field';output; + PK='4'; field1='new'; field2='new';comment='replaces';output; + PK='5'; field1='base'; field2='base'; + comment='will not be replaced'; output; + stop; + run; + + + %bitemporal_dataloader(dclib=work,processed= + ,PK=rk + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from_override=2 + ,bus_to_override=999999999 + ,RK_UNDERLYING=PK + ,RK_UPDATE_MAXKEYTABLE=YES + ,CHECK_UNIQUENESS=YES + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,RK_MAXKEYTABLE=maxkeytable + ,LOG=NO); + %let check=; + proc sql noprint; select max(rk) into :check from basetable&testnum; + %if %mf_getattrn(basetable&testnum,NLOBS)=11 and &check=8 + %then %let test&testnum=PASS; + %else %let test&testnum=FAIL; + proc sql; + insert into results set test="TEST00&testnum",result="&&test&testnum"; +%end; + +/* test 9 - RK generator (more simple) */ +%if &test=ALL or &test=9 %then %do; + %let testnum=9; + data basetable&testnum basetable&testnum._show; + tx_from_dttm=0;tx_to_dttm=&high_date; + processed_dttm=%sysfunc(datetime()); + format text $1000.; + do x=1 to 10; + PK1=cats('blah',x); + PK2=cats('blah haha',x); + RK+1; + if x=2 then text='no change'; else text=''; + eff_from_dttm=0; eff_to_dttm=6666; value=cats('value',x); output; + eff_from_dttm=6666; eff_to_dttm=&high_date; value=cats('devalue',x); + output; + end; + drop x; + run; + data appendtable; + if 0 then set basetable&testnum (drop=tx_: rk) ; + PK1='blah1';PK2='blah haha1'; text='updated record (on end)';output; + PK1='blah2';PK2='blah haha2'; value='devalue2'; text='no change';output; + PK1='blah3';PK2='new'; value='devalue3'; text='new record';output; + do x=1 to 10; + PK1=cats('new',x);PK2='';text='More new records'; + output; + end; + drop x; + stop; + run; + + proc sql; + create table work.max_key_values + ( + KEYTABLE char(41) format=$41. + label='Key table in 2 part format (libref.dataset)', + KEYCOLUMN char(32) format=$32. + label='The Surrogate / Retained key field containing the key values.', + MAX_KEY num format=8. + label= + 'Integer value representing current max RK or SK value in the KEYTABLE', + PROCESSED_DTTM num format=DATETIME21. + label='Datetime this value was last updated' + ); + %bitemporal_dataloader(dclib=work,processed= PROCESSED_DTTM + ,PK=rk + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from_override=77777 + ,bus_to_override=9999999999 + ,RK_UNDERLYING=PK1 PK2 + ,RK_UPDATE_MAXKEYTABLE=YES + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,CHECK_UNIQUENESS=YES + ,RK_MAXKEYTABLE=max_key_values + ,LOG=NO); + + /* run it twice for sh*ts and giggles */ + %bitemporal_dataloader(dclib=work,processed= PROCESSED_DTTM + ,PK=rk + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from_override=888888 + ,bus_to_override=999988888 + ,RK_UNDERLYING=PK1 PK2 + ,RK_UPDATE_MAXKEYTABLE=YES + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,CHECK_UNIQUENESS=YES + ,RK_MAXKEYTABLE=max_key_values + ,LOG=NO); + + %let check=0; + proc sql; select max(rk) into :check from basetable&testnum; + %if %mf_getattrn(basetable&testnum,NLOBS)=34 and &check=21 + %then %let test&testnum=PASS; + %else %let test&testnum=FAIL; + proc sql; + insert into results set test="TEST00&testnum",result="&&test&testnum"; +%end; + +/* test 10 - keeping only relevant variables */ +%if &test=ALL or &test=10 %then %do; + %let testnum=10; + data basetable&testnum basetable&testnum._show; + set basetable; + PROCESSED_DTTM=datetime(); + run; + data appendtable&testnum; + set basetable&testnum ; + field1='testing 567'; + newfield='to be dropped'; + output; + stop; + run; + + %bitemporal_dataloader(dclib=work,processed= PROCESSED_DTTM + ,PK=pk + ,append_dsn=appendtable&testnum + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,keepvars=PK field1 field2 + ,RK_MAXKEYTABLE=maxkeytable + ,LOG=NO); + + + data test&testnum; + set basetable&testnum; + if tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + if eff_from_dttm le %sysfunc(datetime())+4 lt eff_to_dttm; + run; + + %if %mf_getattrn(basetable&testnum,NLOBS)=3 %then %let test&testnum=PASS; + %else %let test&testnum=FAIL; + proc sql; + insert into results set test="TEST0&testnum",result="&&test&testnum"; +%end; + +/* test 11 - append different records with same business dates and PK*/ +%if &test=ALL or &test=11 %then %do; + %let testnum=11; + data basetable&testnum basetable&testnum._show; + set basetable; + PROCESSED_DTTM=%sysfunc(datetime()); + run; + data appendtable&testnum; + set basetable&testnum ; + field1='testing123'; + output; + stop; + run; + + %bitemporal_dataloader(dclib=work,PK=pk + ,append_dsn=appendtable&testnum + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,RK_MAXKEYTABLE=maxkeytable + + ,LOG=NO); + /* does it return just one record? */ + proc sql; + create table test11 as select * from basetable11 + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and eff_from_dttm le 100 lt eff_to_dttm; + %if %mf_getattrn(test11,NLOBS)>1 %then %do; + proc sql; + insert into results + set test="TEST0&testnum",result="FAIL",reason="Duplicates in base table"; + %end; + %else %do; + %let test&testnum=PASS; + proc sql; + insert into results set test="TEST0&testnum",result="&&test&testnum"; + %end; +%end; + +/* test 12 - append table with fewer records than the base table */ +%if &test=ALL or &test=12 %then %do; + %let testnum=12; + data basetable&testnum basetable&testnum._show; + set basetable; + extravar1='blah'; + extravar2=123; + extravar3='01AUG1969'd; + run; + data appendtable&testnum(drop=extravar:); + set basetable&testnum ; + if tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and eff_from_dttm le %sysfunc(datetime()) lt eff_to_dttm; + run; + + %bitemporal_dataloader(dclib=work,PK=pk + ,append_dsn=appendtable&testnum + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + + /* does it return just one record? */ + proc sql; + create table test11 as select * from basetable11 + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and eff_from_dttm le 100 lt eff_to_dttm; + %if %mf_getattrn(basetable&testnum,NLOBS) ne 3 %then %do; + proc sql; + insert into results + set test="TEST0&testnum" + ,result="FAIL",reason="Expected 3 records in basetable&testnum"; + %end; + %else %do; + %let test&testnum=PASS; + proc sql; + insert into results set test="TEST0&testnum",result="&&test&testnum"; + %end; +%end; + +/* test 13 - perform an insert. */ +%if &test=ALL or &test=13 %then %do; + %let testnum=13; + + /* two base table records */ + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1';pk2=2; + eff_from_dttm=0; eff_to_dttm=&now-10000; field1='somevalue '; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; + field1='newvalue'; field2='somenewvalue'; output; + run; + + /* one INSERT record */ + data appendtable&testnum._a; + set basetable&testnum ; + eff_from_dttm=4; eff_to_dttm=5; field1='somevalue2'; output; stop; + run; + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum._a + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO + ) + + + /* insert another record with same values */ + data appendtable&testnum._b; + set appendtable&testnum._a ; + field1='somevalue3'; output; stop; + run; + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum._b + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO + ) + + data _null_; + set work.basetable13; + putlog (_all_)(=); + run; + + /* TEST RESULTS HERE */ + proc sql noprint; + select count(distinct tx_from_dttm) into: test13_tx_count from basetable13; + %put &=test13_tx_count; + select distinct tx_From_dttm format=16.2 + into: test13_array separated by ' ' from basetable13; + %do x=1 %to %sysfunc(countw(&test13_array,' ')); + select count(*) into: test13_&x from BASETABLE&testnum + where tx_from_dttm <= %scan(&test13_array,&x,%str( )) < tx_to_dttm; + %put scan(&test13_array,&x)=%scan(&test13_array,&x,%str( )); + %put test13_&x=&&test13_&x; + %end; + + quit; + + %if &test13_tx_count=3 /* base plus two appends = three load stamps */ + and &test13_1 = 2 /* basetable13_start began with two records */ + and &test13_2 = 4 /* insert closed 1 record, added a new one, + changed the start of the third and left 4th open */ + and &test13_3 = 4 /* this was a pure overlay so only one record changed + from above */ + and %mf_getattrn(basetable&testnum,NLOBS) = 6 + %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + + +/* test 14 - perform an pre-sert. Note that the data does not change, + so should just extend the bus_From. */ +%if &test=ALL or &test=14 %then %do; + %let testnum=14; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1';pk2=2; + eff_from_dttm=90; eff_to_dttm=&now-10000; field1='somevalue '; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; + field1='newvalue'; field2='somenewvalue'; output; + run; + + data appendtable&testnum._a; + set basetable&testnum ; + eff_from_dttm=4; eff_to_dttm=90; output; stop; + run; + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum._a + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO); + + + %if %mf_getattrn(basetable&testnum,NLOBS) = 3 %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 15 - perform a pre-sert with changed data */ +%if &test=ALL or &test=15 %then %do; + %let testnum=15; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1';pk2=2; + eff_from_dttm=90; eff_to_dttm=&now-10000; field1='somevalue '; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; + field1='newvalue'; field2='somenewvalue'; output; + run; + + data appendtable&testnum._a; + set basetable&testnum ; + eff_from_dttm=84; eff_to_dttm=90; field1='newvalue'; output; stop; + run; + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum._a + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,RK_MAXKEYTABLE=maxkeytable + + ,LOG=NO + ); + + + %if %mf_getattrn(basetable&testnum,NLOBS) = 3 %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 16 - perform an update with very slightly changed data */ +%if &test=ALL or &test=16 %then %do; + %let testnum=16; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; PK='PK1';pk2=2; + field3=1.0000000012355555; + eff_from_dttm=90; eff_to_dttm=&now-10000; field1='somevalue '; + field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; + field1='newvalue'; field2='somenewvalue'; output; + run; + + data appendtable&testnum._a; + set basetable&testnum end=last; + field3=1.0000000012355559; + eff_from_dttm=&now; +/*eff_to_dttm=90; */ + if last then output; + run; + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum._a + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO + ); + + + %if %mf_getattrn(basetable&testnum,NLOBS) = 4 %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 17 - perform an UPDATE style update */ +%if &test=ALL or &test=17 %then %do; + %let testnum=17; + + data basetable&testnum basetable&testnum._start; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum.; + PK='PK1';pk2=2; field3=3; output; + run; + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,LOG=NO + ,LOADTYPE=UPDATE + ,bus_from= ,bus_to = + ); + + + %if %mf_getattrn(basetable&testnum,NLOBS) ne 3 %then %let result=FAIL; + %else %do; + proc sql noprint; + select case when field3=3 then 'PASS' else 'FAIL' end into: result + from basetable&testnum + where PK='PK1' and pk2=2; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 18 - perform CLOSEOUTS on a TXTemporal table */ +%if &test=ALL or &test=18 %then %do; + %let testnum=18; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + PK='PK2';pk2=3; field3=1.022355555; output; + PK='PK2';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum.; + PK='PK1';pk2=2; field3=3; output; + PK='PK1';pk2=4; field3=3; output; + run; + + %bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=basetable&testnum + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=appendtable&testnum. + ,PK= pk pk2 + ,NOW=%sysfunc(datetime()) /* allows consistent tracking of tech dates */ + ,FILTER= /* supply a filter to limit the update */ + ); + + %let result=; + %if %mf_getattrn(basetable&testnum,NLOBS) ne + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst18 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %if &tst18=3 & %mf_getattrn(basetable&testnum,NLOBS)=5 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 19 - perform CLOSEOUTS via bitemporal loader (on txtemporal table) */ +%if &test=ALL or &test=19 %then %do; + %let testnum=19; + + data basetable&testnum basetable&testnum._start; + format tx_from_dttm tx_to_dttm datetime21.2; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=3; output; + PK='PK1';pk2=4; field3=1.032355555; output; + + PK='PK2';pk2=3; field3=3; output; + PK='PK2';pk2=4; field3=1.032355555; output; + PK='PK2';pk2=5; field3=1.032355555; output; + + run; + + data appendtable&testnum.; + _____DELETE__THIS__RECORD_____='YES';PK='PK1';pk2=2; field3=3; output; + _____DELETE__THIS__RECORD_____='YES';PK='PK1';pk2=4; field3=3; output; + + _____DELETE__THIS__RECORD_____='No'; PK='PK2';pk2=3; field3=3; output; + _____DELETE__THIS__RECORD_____='Y'; PK='PK2';pk2=4; field3=3; output; + _____DELETE__THIS__RECORD_____='N'; PK='PK2';pk2=5; field3=3; output; + + _____DELETE__THIS__RECORD_____='YES';PK='PK3';pk2=6; field3=3; output; + _____DELETE__THIS__RECORD_____='No'; PK='PK3';pk2=7; field3=3; output; + run; + + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,LOG=NO + ,LOADTYPE=txtemporal + ,tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ); + + %let result=; + %let test1=; + %let test2=; + %let test3=; + %if %mf_getattrn(basetable&testnum,NLOBS) = + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: test1 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK1'; + select count(*) into: test2 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK2'; + select count(*) into: test3 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK3'; + %put tests=&test1 &test2 &test3; + + %if &test1=1 & &test2=3 & &test3=1 & %mf_getattrn(basetable&testnum,NLOBS)=9 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 20 - perform CLOSEOUTS via bitemporal loader (on BItemporal table) */ +%if &test=ALL or &test=20 %then %do; + %let testnum=20; + + data basetable&testnum basetable&testnum._start; + format tx_from_dttm tx_to_dttm datetime21.2; + processed_dttm=3; + tx_from_dttm=0;tx_to_dttm=&high_date; pk2=2; field3=3; + eff_from_dttm=0; eff_to_dttm=&now-10000; PK='PK1'; + field1='somevalue '; field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK1'; + field1='newvalue'; field2='somenewvalue'; output; + eff_from_dttm=0; eff_to_dttm=&now-10000; PK='PK2'; + field1='somevalue '; field2='someothervalue'; output; + eff_from_dttm=&now-10000; eff_to_dttm=&high_date; PK='PK3'; + field1='newvalue'; field2='somenewvalue'; output; + eff_from_dttm=1; eff_to_dttm=&high_date; PK='PK4'; + field1='newvalue'; field2='somenewvalue'; output; + run; + + data appendtable&testnum.; + set basetable&testnum; + if _n_=1 or _n_=5 then _____DELETE__THIS__RECORD_____='YES'; + else _____DELETE__THIS__RECORD_____=''; + if _n_=3 then eff_from_dttm=eff_from_dttm+1; /* not a change */ + if _n_=4 then field3=field3*3; /* a change */ + run; + + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,LOG=NO + ,LOADTYPE=bitemporal + ,tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,bus_From=eff_from_dttm + ,bus_to=eff_to_dttm + ); + + %let result=; + %let test1=; + %let test2=; + %let test3=; + %let test4=; + %let test5=; + %if %mf_getattrn(basetable&testnum,NLOBS) = + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: test1 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK1'; + select count(*) into: test2 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK2'; + select count(*) into: test3 from basetable&testnum + where pk='PK3'; + select count(*) into: test4 from basetable&testnum + where processed_dttm>3; + select count(*) into: test5 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm + and pk='PK4'; + %put tests=&test1 &test2 &test3 &test4 &test5; + + %if &test1=1 & &test2=1 & &test3=2 & %mf_getattrn(basetable&testnum,NLOBS)=6 + & &test4=4 & &test5= 0 %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + + +/* test 21 - perform CLOSEOUTS via bitemporal loader (on UPDATE style table) */ +%if &test=ALL or &test=21 %then %do; + %let testnum=21; + + data basetable&testnum basetable&testnum._start; + processed_dttm=10; + PK='PK1';pk2=1; field3=1.012355555; output; + PK='PK2';pk2=2; field3=3; output; + PK='PK3';pk2=3; field3=1.032355555; output; + PK='PK4';pk2=4; field3=4; output; + PK='PK5';pk2=5; field3=1.032355555; output; + PK='PK6';pk2=6; field3=1.032355555; output; + PK='PK7';pk2=7; field3=0; output; + run; + + data appendtable&testnum.; + _____DELETE__THIS__RECORD_____='YES';PK='PK1';pk2=1; output; /* gone */ + _____DELETE__THIS__RECORD_____='YES';PK='PK2';pk2=2; output; /* gone */ + _____DELETE__THIS__RECORD_____='N';PK='PK3';pk2=3; output; /* changed */ + _____DELETE__THIS__RECORD_____='N';PK='PK4';pk2=4; field3=3; output; + _____DELETE__THIS__RECORD_____='N';PK='PK5';pk2=5; output; /* changed */ + _____DELETE__THIS__RECORD_____='YES';PK='PK6';pk2=6; output; /* gone */ + _____DELETE__THIS__RECORD_____='N';PK='PK7';pk2=7; field3=0; output; + run; + + + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,LOG=NO + ,LOADTYPE=update + ); + + %let result=; + %let test1=.; + %let test2=.; + %let test3=.; + %let test4=.; + %let test5=.; + %if %mf_getattrn(basetable&testnum,NLOBS) = + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: test1 from basetable&testnum + where pk in ('PK1','PK2','PK6'); + select field3 into: test2 from basetable&testnum + where pk='PK3'; + select count(*) into: test3 from basetable&testnum + where processed_dttm=10; + select field3 into: test4 from basetable&testnum + where pk='PK4'; + select field3 into: test5 from basetable&testnum + where pk='PK5'; + %put tests=&test1 &test2 &test3 &test4 &test5; + + %if &test1=0 & &test2=. & &test3=1 & %mf_getattrn(basetable&testnum,NLOBS)=4 + & &test4=3 & &test5=3 %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 22 - perform CLOSEOUTS via bitemporal loader (on RK style table) */ +%if &test=ALL or &test=22 %then %do; + %let testnum=22; + + data basetable&testnum basetable&testnum._show; + tx_from_dttm=0;tx_to_dttm=&high_date; + processed_dttm=5; + format text $1000.; + do x=1 to 10; + PK1=cats('blah',x); + PK2=cats('blah haha',x); + RK+1; + if x=2 then text='no change'; + else if mod(x,2)=0 then text='deleted record'; + else text=''; + value=cats('devalue',x); output; + end; + drop x; + run; + data appendtable&testnum; + if 0 then set basetable&testnum (drop=tx_: rk) ; + PK1='blah1';PK2='blah haha1'; + text='updated record (on end)';value='newval';output; + PK1='blah2';PK2='blah haha2'; value='devalue2'; text='no change';output; + PK1='blah3';PK2='new'; value='devalue3'; text='new record';output; + do x=4 to 10; + PK1=cats('blah',x);pk2=cats('blah haha',x); + text='';value=cats('devalue',x); + output; + end; + drop x; + stop; + run; + + data appendtable&testnum; + set appendtable&testnum; + /* delete even numbered observations */ + if mod(_n_,2)=0 and _n_ ne 2 then _____DELETE__THIS__RECORD_____='YES'; + else _____DELETE__THIS__RECORD_____=0; + run; + + %bitemporal_dataloader(dclib=work + ,PK=rk + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,append_dsn=appendtable&testnum + ,RK_UNDERLYING=PK1 PK2 + ,RK_UPDATE_MAXKEYTABLE=YES + ,RK_MAXKEYTABLE=max_key_values + ,LOG=NO + ,loadtype=txtemporal + ) + + + %let result=; + %let test1=.; + %let test2=.; + %let test3=.; + %let test4=.; + %if %mf_getattrn(basetable&testnum,NLOBS) = + %mf_getattrn(basetable&testnum._show,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: test1 from basetable&testnum + where pk1 in ('blah1'); + select value into: test2 from basetable&testnum + where pk1='blah1' and tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + select count(*) into: test3 from basetable&testnum + where processed_dttm=5; + select count(*) into: test4 from basetable&testnum + where pk1='blah4' and tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %put tests=&test1 &test2 &test3 &test4 ; + + %if &test1=2 & &test2=newval & &test3=5 + & %mf_getattrn(basetable&testnum,NLOBS)=12 + & &test4=0 %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 23 - testing LOADTARGET option on BITEMPORAL */ +%if &test=ALL or &test=23 %then %do; + %let testnum=23; + + data basetable&testnum basetable&testnum._show; + set basetable; + run; + + data appendtable&testnum; + if 0 then set basetable; + eff_from_dttm=&now; eff_to_dttm=&high_date; + pk='PK1'; field1='blah'; field2='blah'; + run; + + %bitemporal_dataloader(dclib=work + ,PK=pk + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE23 + ,append_dsn=appendtable&testnum + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO + ,LOADTARGET=NO); + + %if %mf_getattrn(basetable23,NLOBS)=2 %then %let test23=PASS; + %else %let test23=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&test23"; + +%end; + +/* test 24 - testing LOADTARGET option on TXTEMPORAL */ +%if &test=ALL or &test=24 %then %do; + %let testnum=24; + + proc sort data= basetable (drop=eff:) out=basetable&testnum nodupkey; + by tx_from_dttm pk; + run; + data appendtable&testnum; + if 0 then set basetable&testnum; + pk='PK1'; field1='blah'; field2='blah'; + run; + + %bitemporal_dataloader(dclib=work,PK=pk + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE24 + ,append_dsn=appendtable&testnum + ,LOADTYPE=TXTEMPORAL + ,bus_from=eff_from_dttm, bus_to=eff_to_dttm + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOG=NO + ,LOADTARGET=NO); + %if %mf_getattrn(basetable24,NLOBS)=1 %then %let test24=PASS; + %else %let test24=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&test24"; +%end; + +/* test 25 - testing LOADTARGET option on UPDATE */ +%if &test=ALL or &test=25 %then %do; + %let testnum=25; + + data basetable&testnum basetable&testnum._start; + PROCESSED_DTTM=0; /* if this changes, an update happened! */ + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum.; + PK='PK1';pk2=2; field3=3; output; + run; + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,LOG=NO + ,LOADTARGET=NO + ,LOADTYPE=UPDATE + ,bus_from= ,bus_to = + ); + + + %if %mf_getattrn(basetable&testnum,NLOBS) ne 3 %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: check&testnum from basetable&testnum + where processed_dttm>0; + %if &&check&testnum>0 %then %let result=FAIL; + %else %let result=PASS; + %end; + + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 26 - testing LOADTARGET option on CLOSEOUTS */ +%if &test=ALL or &test=26 %then %do; + %let testnum=26; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + PK='PK2';pk2=3; field3=1.022355555; output; + PK='PK2';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum.; + PK='PK1';pk2=2; field3=3; output; + PK='PK1';pk2=4; field3=3; output; + run; + + %bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=basetable&testnum + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=appendtable&testnum. + ,PK= pk pk2 + ,NOW=%sysfunc(datetime()) + ,LOADTARGET=NO + ,FILTER= /* supply a filter to limit the update */ + ); + + %let result=; + %if %mf_getattrn(basetable&testnum,NLOBS) ne + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst26 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %if &tst26=5 & %mf_getattrn(basetable&testnum,NLOBS)=5 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 27 - testing a load using a view (with records) */ +%if &test=ALL or &test=27 %then %do; + %let testnum=27; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + PK='PK2';pk2=3; field3=1.022355555; output; + PK='PK2';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum /view=appendtable&testnum; + PK='PK1';pk2=2; field3=3; output; + PK='PK1';pk2=4; field3=3; output; + run; + + %bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=basetable&testnum + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=appendtable&testnum. + ,PK= pk pk2 + ,NOW=%sysfunc(datetime()) + ,LOADTARGET=NO + ,FILTER= /* supply a filter to limit the update */ + ); + + %let result=; + proc sql noprint; + select count(*) into:testnobs&testnum from basetable&testnum; + select count(*) into:testnobs2&testnum from basetable&testnum._start; + %if &&testnobs&testnum ne &&testnobs2&testnum %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst27 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %if &tst27=5 & %mf_getattrn(basetable&testnum,NLOBS)=5 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 28 - testing a load using a view (without records) */ +%if &test=ALL or &test=28 %then %do; + %let testnum=28; + + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555; output; + PK='PK1';pk2=3; field3=1.022355555; output; + PK='PK1';pk2=4; field3=1.032355555; output; + PK='PK2';pk2=3; field3=1.022355555; output; + PK='PK2';pk2=4; field3=1.032355555; output; + run; + + data appendtable&testnum /view=appendtable&testnum; + set basetable&testnum; + stop; + run; + + %bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=basetable&testnum + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=appendtable&testnum. + ,PK= pk pk2 + ,NOW=%sysfunc(datetime()) + ,LOADTARGET=NO + ); + + %let result=; + proc sql noprint; + select count(*) into:testnobs&testnum from basetable&testnum; + select count(*) into:testnobs2&testnum from basetable&testnum._start; + %if (&&testnobs&testnum = &&testnobs2&testnum) and &&testnobs&testnum=5 + %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 29 - testing a load with different formats to base table */ +%if &test=ALL or &test=29 %then %do; + %let testnum=29; + + data basetable&testnum basetable&testnum._start; + format test_tm datetime19.3; + tx_from_dttm=0;tx_to_dttm=&high_date; test_tm=datetime(); + PK='PK1';pk2=2; field3=1; output; + PK='PK1';pk2=3; field3=1; output; + PK='PK1';pk2=4; field3=1; output; + PK='PK2';pk2=3; field3=1; output; + PK='PK2';pk2=4; field3=1; output; + run; + + data appendtable&testnum ; + format field3 3. test_tm datetime17.2; + set basetable&testnum; + field3=3; test_tm=datetime();output; + stop; + run; + + %bitemporal_dataloader(dclib=work,PK=pk pk2 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,base_dsn=BASETABLE&testnum + ,RK_MAXKEYTABLE=maxkeytable + + ,LOG=NO + ,LOADTARGET=YES + ,tech_from=tx_from_dttm, tech_to=tx_to_dttm + ,LOADTYPE=TXTEMPORAL + ); + + + %let result=; + proc sql noprint; + select count(*) into:testnobs&testnum from basetable&testnum; + select count(*) into:testnobs2&testnum from basetable&testnum._start; + %if (&&testnobs&testnum =6) and &&testnobs2&testnum=5 %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 30 - testing a load to OLEDB (should use SQL server temp table) */ +%if (&test=ALL or &test=30 ) and 0 %then %do; /* skip until have a db */ + %let testnum=30; + +%assign_direct_lib(libref=XXX); + data appendtable&testnum ; + set XXX.temp_rk_table + (where=(tx_from le %sysfunc(datetime()) lt tx_to)); + some_num+1; + output; + some_id=put(ranuni(0)*10000000,8.);output; + stop; + run; + proc sql noprint; + select count(*) into:testnobs&testnum from web.temp_rk_table; + + %bitemporal_dataloader(dclib=work,PK=some_rk + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,tech_from=tx_from + ,tech_to=tx_to + ,base_lib=web + ,base_dsn=temp_rk_table + ,LOG=YES + ,rk_underlying=some_id + ,LOADTARGET=YES + ,LOADTYPE=TXTEMPORAL + ); + + + %let result=; + proc sql noprint; + select count(*) into:testnobs2&testnum from web.temp_rk_table; + %if (&&testnobs2&testnum =%eval(&&testnobs&testnum+2)) %then %let result=PASS; + %else %let result=FAIL; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 31 - bitemporal closeouts with embedded speechmarks in PK */ +%let testnum=31; +%if &test=ALL or &test=&testnum %then %do; + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=1.012355555;field4='blah '; output; + PK='PK1';pk2=3; field3=1.022355555;field4='blah2'; output; + PK='PK1';pk2=4; field3=1.032355555;field4='blah3'; output; + PK='PK2';pk2=3; field3=1.022355555;field4='bla"h'; output; + PK='PK2';pk2=4; field3=1.032355555;field4="blah'h"; output; + run; + + data appendtable&testnum.; + PK='PK1';pk2=2;field4='blah '; output; + PK='PK1';pk2=3;field4='blah2'; output; + PK='PK1';pk2=4;field4='blah3'; output; + PK='PK2';pk2=3;field4='bla"h'; output; + PK='PK2';pk2=4;field4="blah'h"; output; + run; + + %bitemporal_closeouts( + tech_from=tx_from_dttm + ,tech_to = tx_to_dttm + ,base_lib=WORK /* Libref of the BASE table. */ + ,base_dsn=basetable&testnum + ,append_lib=WORK /* Libref of the STAGING table. */ + ,append_dsn=appendtable&testnum. + ,PK= pk pk2 field4 + ,NOW=%sysfunc(datetime()) /* allows consistent tracking of tech dates */ + ,FILTER= /* supply a filter to limit the update */ + ); + + %let result=; + %if %mf_getattrn(basetable&testnum,NLOBS) ne + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst31 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %if &tst31=0 & %mf_getattrn(basetable&testnum,NLOBS)=5 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; +/* test 32 - testing closevars process*/ +%let testnum=32; +%if &test=ALL or &test=&testnum %then %do; + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; some_val=0; + closeme='NO ';x=1;y=2;z=2;output; + closeme='NO';x=1;y=2;z=3;output; + closeme='NO';x=1;y=2;z=4;output; + closeme='YES';x=1;y=3;z=1;output; + closeme='YES';x=1;y=3;z=2;output; + closeme='YES';x=1;y=3;z=3;output; + closeme='NO';x=4;y=3;z=3;output; + closeme='YES';x=5;y=3;z=1;output; + closeme='YES';x=5;y=3;z=2;output; + closeme='YES';x=5;y=3;z=3;output; + run; + + data appendtable&testnum.; + closeme='YES';x=1;y=3;z=1;some_val=0;output; + closeme='YES';x=5;y=3;z=1;some_val=0;output; + closeme='NO ';x=1;y=2;z=2;some_val=1;output; + run; + + %bitemporal_dataloader(dclib=work,PK=CLOSEME X Y Z + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum override + ,tech_from=tx_from_dttm + ,tech_to=tx_to_dttm + ,base_lib=work + ,base_dsn=basetable&testnum + ,LOG=YES + ,LOADTARGET=YES + ,LOADTYPE=TXTEMPORAL + ,CLOSE_VARS=CLOSEME X Y + ); + + %let result=; + %if %mf_getattrn(basetable&testnum,NLOBS) ne 11 %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst32 from basetable&testnum + where %sysfunc(datetime()) lt tx_to_dttm + and closeme='YES'; + %if &tst32=2 %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +/* test 33- bitemporal load with high precision decimals (and nulls) */ +%let testnum=33; +%if &test=ALL or &test=&testnum %then %do; + data basetable&testnum basetable&testnum._start; + tx_from_dttm=0;tx_to_dttm=&high_date; + PK='PK1';pk2=2; field3=0.0026539721926;field4='blah '; output; + PK='PK1';pk2=3; field3=._;field4='blah2'; output; + PK='PK1';pk2=4; field3=.;field4='blah3'; output; + PK='PK2';pk2=3; field3=1.0026239721926;field4='bla"h'; output; + PK='PK2';pk2=4; field3=1.0026139721926;field4="blah'h"; output; + run; + + data appendtable&testnum.; + set basetable&testnum; + run; + + + %bitemporal_dataloader(dclib=work,PK= pk pk2 field4 + ,append_dsn=appendtable&testnum. + ,ETLSOURCE=bitemporal_tester test&testnum precision + ,tech_from=tx_from_dttm + ,tech_to=tx_to_dttm + ,base_lib=work + ,base_dsn=basetable&testnum + ,LOG=YES + ,LOADTARGET=YES + ,LOADTYPE=TXTEMPORAL + ) + + %let result=; + %if %mf_getattrn(basetable&testnum,NLOBS) ne + %mf_getattrn(basetable&testnum._start,NLOBS) %then %let result=FAIL; + %else %do; + proc sql noprint; + select count(*) into: tst32 from basetable&testnum + where tx_from_dttm le %sysfunc(datetime()) lt tx_to_dttm; + %if &tst32=5 & %mf_getattrn(basetable&testnum,NLOBS)=5 + %then %let result=PASS; + %else %let result=FAIL; + %end; + proc sql; insert into results set test="TEST&testnum",result="&result"; +%end; + +quit; +%mend bitemporal_tester; + +options mprint; +%bitemporal_tester(test=ALL) + + +data work.test_results; + set work.results; + rename test=test_description result=test_result; +run; + diff --git a/sas/sasjs/macros/bitemporal_dataloader.test.3.sas b/sas/sasjs/macros/bitemporal_dataloader.test.3.sas new file mode 100644 index 0000000..8831def --- /dev/null +++ b/sas/sasjs/macros/bitemporal_dataloader.test.3.sas @@ -0,0 +1,76 @@ +/** + @file + @brief Test Harness for bitemporal dataloader + @details testing special numerics + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mp_assert.sas + @li mf_nobs.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%let syscc=0; +%let now=%sysfunc(datetime()); +%let high_date='31DEC8888:23:59:59'dt; + +/* create base table */ +data basetable; + PK='PK1';field1='somevalue';numvar=.; output; + PK='PK2';field1='newvalue';numvar=0; output; + PK='PK3';field1='somevalue';numvar=._; output; + PK='PK4';field1='newvalue';numvar=.z; output; +run; + +data appendtable; + set basetable; + if numvar=._ then numvar=.a; + if numvar=.z then numvar=.y; +run; +libname work2(work); + +proc sql; +create table work.mpe_dataloads( + libref varchar(8) , + dsn varchar(32) , + etlsource varchar(100) , + loadtype varchar(20) , + changed_records int, + new_records int, + deleted_records int, + duration num, + user_nm varchar(50) , + processed_dttm num format=datetime19.3, + mac_ver varchar(5) +);quit; +proc datasets lib=work noprint; + modify mpe_dataloads; + index create + pk_mpe_dataloads=(processed_dttm libref dsn etlsource) + /nomiss unique; +quit; + +%bitemporal_dataloader(dclib=work2 + ,PK=pk + ,ETLSOURCE=&_program + ,base_dsn=BASETABLE + ,LOG=1 + ,outds_mod=work.changes + ,loadtype=UPDATE +) + +%mp_assert(iftrue=(&syscc=0), + desc=Testing long ETLSOURCE value +) + +%mp_assert(iftrue=(%mf_nobs(work.changes)=2), + desc=Testing special missings +) + + diff --git a/sas/sasjs/macros/bitemporal_dataloader.test.4.sas b/sas/sasjs/macros/bitemporal_dataloader.test.4.sas new file mode 100644 index 0000000..0dc3e2a --- /dev/null +++ b/sas/sasjs/macros/bitemporal_dataloader.test.4.sas @@ -0,0 +1,91 @@ +/** + @file + @brief Test Harness for bitemporal dataloader - deletes only + @details When an upload is 'deletes only' we need to ensure that the audit + table is still updated accordingly + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mddl_dc_difftable.sas + @li mp_assert.sas + @li mf_nobs.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%let syscc=0; +%let now=%sysfunc(datetime()); +%let high_date='31DEC8888:23:59:59'dt; + +/* create base table */ +data work.basetable; + PK='PK1';field1='somevalue';numvar=.; output; + PK='PK2';field1='newvalue';numvar=0; output; + PK='PK3';field1='somevalue';numvar=._; output; + PK='PK4';field1='newvalue';numvar=.z; output; + PK='PK5';field1='newvalue';numvar=.z; output; +run; + +data work.stagetable; + set work.basetable; + _____DELETE__THIS__RECORD_____='Yes'; + if _n_>2 then stop; +run; +libname work2(work); + +proc sql; +create table work.mpe_dataloads( + libref varchar(8) , + dsn varchar(32) , + etlsource varchar(100) , + loadtype varchar(20) , + changed_records int, + new_records int, + deleted_records int, + duration num, + user_nm varchar(50) , + processed_dttm num format=datetime19.3, + mac_ver varchar(5) +);quit; +proc datasets lib=work noprint; + modify mpe_dataloads; + index create + pk_mpe_dataloads=(processed_dttm libref dsn etlsource) + /nomiss unique; +quit; + +%mddl_dc_difftable(libds=work.mpe_audit) + +%bitemporal_dataloader(dclib=work2 + ,PK=pk + ,ETLSOURCE=bitemporal_dataloader.test.4 + ,base_dsn=BASETABLE + ,append_dsn=stagetable + ,LOG=1 + ,outds_mod=work.changes + ,outds_del=work.deleted + ,loadtype=UPDATE + ,outds_audit=work.mpe_audit +) + +proc sql noprint; +select count(distinct key_hash) into: dels + from work.mpe_audit + where move_type='D'; + +%mp_assert(iftrue=(&dels=2), + desc=2 deleted records present in audit table +) + +%mp_assert(iftrue=(%mf_nobs(work.basetable)=3), + desc=Ensuring 3 records are now in base table +) + +%mp_assert(iftrue=(%mf_nobs(work.deleted)=2), + desc=Confirming 2 deleted records on output table +) diff --git a/sas/sasjs/macros/mpe_accesscheck.sas b/sas/sasjs/macros/mpe_accesscheck.sas new file mode 100755 index 0000000..7c92197 --- /dev/null +++ b/sas/sasjs/macros/mpe_accesscheck.sas @@ -0,0 +1,89 @@ +/** + @file + @brief Checks the level of access a user has to the MP Editor + @details In order for a user to be able to EDIT or APPROVE a table they must + be in a metadata group that has been granted access to that table in the + &mpelib..mpe_security table. Alternatively, they may be in the + &mpeadmins group (has overall access). + +

SAS Macros

+ @li mp_abort.sas + @li mf_verifymacvars.sas + @li mpe_getgroups.sas + @li mp_dropmembers.sas + + @param [in] access_level= access_level (per &mpelib..mp_editor_security) reqd + + @returns outds A table containing all the groups that user is a member of, + which are granted the access_level requested. + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_accesscheck( + base_table /* base table to check for */ + ,outds=med_accesscheck /* WORK table to contain access details */ + ,user= /* metadata user to check for */ + ,access_level=APPROVE + ); + + %if &user= %then %let user=%mf_getuser(); + + %if %index(&outds,.) %then %do; + %local lib ds; + %let lib=%scan(&outds,1,.); + %let ds=%scan(&outds,2,.); + %if %upcase(&lib) ne WORK %then %do; + %mp_abort(msg=outds should be a WORK table + ,mac=mpe_accesscheck); + %end; + %end; + %else %let ds=&outds; + + %mp_abort( + iftrue=(%mf_verifymacvars(base_table user access_level)=0) + ,mac=bitemporal_dataloader + ,msg=%str(Missing base_table/user access_level) + ) + + /* ensure any existing table is dropped */ + %mp_dropmembers(&ds) + + /* create a new table for temp use */ + data; run; + %local tempds; %let tempds=&syslast; + + /* overwrite with the list of groups */ + %mpe_getgroups(user=&user,outds=&tempds); + + %if &_debug ge 131 %then %do; + data _null_; + set &tempds; + putlog (_all_)(=); + run; + %end; + + proc sql; + create table &outds as + select * from &tempds + where groupname="&mpeadmins" + or groupname in + (select sas_group from &mpelib..mpe_security + where &dc_dttmtfmt. lt tx_to + and access_level="&access_level" + & ( + (libref="%scan(&base_table,1,.)" and dsn="%scan(&base_table,2,.)") + or (libref="%scan(&base_table,1,.)" and dsn="*ALL*") + or (libref="*ALL*") + ) + ); + +%put base_table=&base_table; +%put libref=%scan(&base_table,1,.); +%put dsn=%scan(&base_table,2,.); +%put access_level=&access_level; +%mend mpe_accesscheck; diff --git a/sas/sasjs/macros/mpe_alerts.sas b/sas/sasjs/macros/mpe_alerts.sas new file mode 100755 index 0000000..ff403fb --- /dev/null +++ b/sas/sasjs/macros/mpe_alerts.sas @@ -0,0 +1,175 @@ +/** + @file + @brief send alerts + @details Send emails to users on review, approve, and/or reject + + @param alert_event= either SUBMITTED, APPROVED or REJECTED + @param alert_lib= the library of the table being submitted + @param alert_ds= the table submitted + @param dsid= the staging reference for the submitted table + +

SAS Macros

+ @li mf_getattrn.sas + @li mf_existds.sas + @li mf_getuser.sas + + @version 9.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + + +%macro mpe_alerts(alert_event= + , alert_lib= + , alert_ds= + , dsid= +); + +/* exit if not configured */ +%global DC_EMAIL_ALERTS; +%if &DC_EMAIL_ALERTS ne YES %then %do; + %put DCNOTE: Email alerts are not configured; + %put DCNOTE: (dc_email_alerts=&dc_email_alerts in &mpelib..mpe_config); + %return; +%end; + + +%let alert_event=%upcase(&alert_event); +%let alert_lib=%upcase(&alert_lib); +%let alert_ds=%upcase(&alert_ds); +%let from_user=%mf_getuser(); + + +/* get users TO which the email should be sent */ + +proc sql noprint; +create table users as select distinct a.alert_user, + b.user_displayname, + b.user_email + from &mpelib..mpe_alerts + (where=(&dc_dttmtfmt. lt tx_to)) a + left join &mpelib..mpe_emails + (where=(&dc_dttmtfmt. lt tx_to)) b + on upcase(trim(a.alert_user))=upcase(trim(b.user_name)) + where a.alert_event in ("&alert_event","*ALL*") + and a.alert_lib in ("&alert_lib","*ALL*") + and a.alert_ds in ("&alert_ds","*ALL*"); + +%local isThere; +select count(*) into: isThere from &syslast where alert_user="&from_user"; +%if &isThere>0 %then %do; + insert into &syslast set alert_user="&from_user"; +%end; + + +/* if no email / displayname is provided, then extract from metadata */ +data emails; + set users; + length emailuri uri text $256; call missing(emailuri,uri); drop emailuri uri; + + /* get displayname */ + text=cats("omsobj:Person?@Name='",alert_user,"'"); + if metadata_getnobj(text,1,uri)<=0 then do; + putlog "DCWARN: &from_user not found"; + return; + end; + else if user_displayname = '' then do; + if metadata_getattr(uri,'DisplayName',user_displayname)<0 then do; + putlog 'DCWARN: strange err, no displayname attribute of user URI'; + end; + end; + + if index(user_email,'@') then return; + /* get email from metadata if not in input table */ + if metadata_getnasn(uri,"EmailAddresses",1,emailuri)<=0 then do; + putlog "DCWARN: " alert_user " has no emails in MPE_EMAILS or metadata!"; + if metadata_getattr(emailuri,"Address",user_email)<0 then do; + putlog 'DCWARN: Unexpected error! Valid emailURI but no email. Weird.'; + end; + end; + /* only keep valid emails */ + if index(user_email,'@') ; +run; + +%local emails; +proc sql noprint; +select user_email into: emails separated by '" "' from emails; + +/* exit if nobody to email */ +%if %mf_getattrn(emails,NLOBS)=0 %then %do; + %put NOTE: No alerts configured (mpe_alerts.sas); + %return; +%end; + +/* display email options */ +data _null_; + set sashelp.voption(where=(group='EMAIL')); + put optname '=' setting; +run; + +filename __out email ("&emails") + subject="Table &alert_lib..&alert_ds has been &alert_event"; + +%local SUBMITTED_TXT; +%if &alert_event=SUBMITTED %then %do; + data _null_; + set &mpelib..mpe_submit; + where table_id="&dsid" and submit_status_cd='SUBMITTED'; + call symputx('SUBMITTED_TXT',submitted_reason_txt,'l'); + run; + data _null_; + File __out lrecl=32000; + put 'Dear user,'; + put ' '; + put "Please be advised that a change to table &alert_lib..&alert_ds has " + "been proposed by &from_user on the '&syshostname' SAS server."; + put " "; + length txt $2048; + txt=symget('SUBMITTED_TXT'); + put "Reason provided: " txt; + put " "; + put "This is an automated email by Data Controller for SAS®. For " + "documentation, please visit https://docs.datacontroller.io"; + run; +%end; +%else %if &alert_event=APPROVED %then %do; + /* there is no approval message */ + data _null_; + File __out lrecl=32000; + put 'Dear user,'; + put ' '; + put "Please be advised that a change to table &alert_lib..&alert_ds has " + "been approved by &from_user on the '&syshostname' SAS server."; + put " "; + put "This is an automated email by Data Controller for SAS®. For " + "documentation, please visit https://docs.datacontroller.io"; + run; +%end; +%else %if &alert_event=REJECTED %then %do; + data _null_; + set &mpelib..mpe_review; + where table_id="&dsid" and review_status_id='REJECTED'; + call symputx('REVIEW_REASON_TXT',REVIEW_REASON_TXT,'l'); + run; + data _null_; + File __out lrecl=32000; + put 'Dear user,'; + put ' '; + put "Please be advised that a change to table &alert_lib..&alert_ds has " + "been rejected by &from_user on the '&syshostname' SAS server."; + put " "; + length txt $2048; + txt=symget('REVIEW_REASON_TXT'); + put "Reason provided: " txt; + put " "; + put "This is an automated email by Data Controller for SAS®. For " + "documentation, please visit https://docs.datacontroller.io"; + run; +%end; + +filename __out clear; + +%mend mpe_alerts ; diff --git a/sas/sasjs/macros/mpe_columnlevelsecurity.sas b/sas/sasjs/macros/mpe_columnlevelsecurity.sas new file mode 100644 index 0000000..df2ffe2 --- /dev/null +++ b/sas/sasjs/macros/mpe_columnlevelsecurity.sas @@ -0,0 +1,141 @@ +/** + @file + @brief Filters a table with CLS rules + @details Implements CLS as per the rules described here: + + https://docs.datacontroller.io/column-level-security/ + + Usage: + + %mpe_columnlevelsecurity(TGTLIB,TGTDS,work.inds + ,mode=VIEW + ,clsds=dc.mpe_cls + ,groupds=work.groups + ,outds=work.final + ,outmeta=work.cls_rules + ) + + + @param [in] tgtlib The libref of the target table + @param [in] tgtds The dataset reference of the target table + @param [in] inds A two-level (lib.ds) reference to the WORK table to which to + apply the column filter rules + @param [in] mode= (VIEW) Either VIEW or EDIT to indicate whether the + resulting table is intended to be viewable or editable. + @param [in] groupds= (work.groups)A two-level (lib.ds) reference to a dataset + containing the list of groups of which the current user is a member. The + column containing the group name should be called `groupname`. + @param [in] clsds= (work.clsds) A two-level (lib.ds) reference to the + configuration table containing the CLS rules to apply. + @param [out] outds= (WORK.CLSVIEW) A two-level (lib.ds) reference to the WORK + dataset to create + @param [out] outmeta= (WORK.CLS_RULES)The rule metadata, with the following + structure: + |CLS_VARIABLE_NM:$32.|CLS_HIDE:best.| + |---|---|---|---|---| + |`SOME_VARIABLE`|`0 `| + |`VAR3`|`1 `| + + +

SAS Macros

+ + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_columnlevelsecurity(tgtlib,tgtds,inds + ,mode=VIEW + ,groupds=work.groups + ,clsds=work.clsview + ,outds=CLSVIEW + ,outmeta=work.cls_rules +); + +%local col_list is_admin; +/* filter for the appropriate rules */ +proc sql; +create table &outmeta as + select CLS_VARIABLE_NM, + min(case when CLS_HIDE=1 then 1 else 0 end) as CLS_HIDE + from &clsds + where &dc_dttmtfmt. lt tx_to + and CLS_SCOPE in ("&mode",'ALL') + and CLS_ACTIVE=1 + %if &mode=VIEW %then %do; + and CLS_HIDE ne 1 + %end; + and upcase(CLS_GROUP) in (select upcase(groupname) from &groupds) + and CLS_LIBREF="%upcase(&tgtlib)" + and CLS_TABLE="%upcase(&tgtds)" + group by CLS_VARIABLE_NM; + +%let is_admin=0; +proc sql; +select count(*) into: is_admin from &groupds where groupname="&MPEADMINS"; +%put &sysmacroname: &=is_admin; +%if %mf_nobs(work.cls_rules) = 0 or &is_admin>0 %then %do; + %put &sysmacroname: no CLS rules to apply; + %put &=is_admin; + /* copy using append for speed */ + data &outds; + set &inds; + stop; + run; + proc append base=&outds data=&inds; + run; + /* ensure CLS_RULES is empty in case of admin */ + data &outmeta; + set &outmeta; + stop; + run; + %return; +%end; +%else %if &mode=VIEW %then %do; + /* just send back the relevant columns */ + %let col_list=0; + proc sql noprint; + select CLS_VARIABLE_NM into: col_list separated by ' ' from &outmeta + where CLS_HIDE=0; + + %if &col_list=0 %then %do; + /* + We have columns that are set to CLS_HIDE=1 but we do not have any to + explicitly show. Therefore we assume all columns are to be shown except + those that are explicitly hidden. + */ + proc sql noprint; + select CLS_VARIABLE_NM into: col_list separated by ' ' from &outmeta + where CLS_HIDE=1; + + data &outds; + set &inds; + drop &col_list; + run; + %end; + %else %do; + data &outds; + set &inds; + keep &col_list; + run; + %end; +%end; +%else %if &mode=EDIT %then %do; + /* + In this case we pass all columns and the frontend will filter out the + ones that are not allowed to be edited. + */ + data &outds; + set &inds; + stop; + run; + proc append base=&outds data=&inds; + run; +%end; +%else %do; + %put &sysmacroname: invalid mode - &mode!; + %abort; +%end; + +%mend mpe_columnlevelsecurity; diff --git a/sas/sasjs/macros/mpe_filtermaster.sas b/sas/sasjs/macros/mpe_filtermaster.sas new file mode 100644 index 0000000..b7d3968 --- /dev/null +++ b/sas/sasjs/macros/mpe_filtermaster.sas @@ -0,0 +1,262 @@ +/** + @file + @brief dynamic where clause creation + @details Generates a where clause based on the following inputs: + + @li The filter_RK (if provided) + @li The mode (if EDIT then filter for current records) + @li The user permissions (Row Level Security) + + This macro should be used whenever surfacing data to the user. Note that + it is not possible to %include filerefs directly in a proc sql where clause. + The workaround is to use a data step view. + + Note - DCLIB should be assigned. + + @param [in] mode The mode. If EDIT, then current rows are returned. Valid + Values: + @li EDIT + @li VIEW + @li DLOAD - used in getrawdata + @li ULOAD - used by stagedata.sas to prevent restricted rows being submitted + + @param [in] libds The target libref.dataset to which the filter will apply. + @param [in] filter_rk= (-1) The filter_rk, if available + @param [in] dclib= The libref of the DC control tables + @param [out] outref= The output fileref to create (containing the filter) + @param [out] outds= (work.query) The query dataset (if filter_rk supplied) + +

SAS Macros

+ @li mf_fmtdttm.sas + @li mf_getuser.sas + @li mf_getuniquefileref.sas + @li mf_getuniquename.sas + @li mf_nobs.sas + @li mp_abort.sas + @li mp_filtergenerate.sas + @li mpe_getgroups.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_filtermaster(mode,libds, + dclib=, + filter_rk=-1, + outref=0, + outds=work.query +); + +%put &sysmacroname entry vars:; +%put _local_; + +%let mode=%upcase(&mode); +%let libds=%upcase(&libds); + + +%mp_abort(iftrue= ( + &mode ne EDIT and &mode ne VIEW and &mode ne DLOAD and &mode ne ULOAD + ) + ,mac=&sysmacroname + ,msg=%str(Invalid MODE: &mode) +) +%mp_abort(iftrue= (&outref = 0) + ,mac=&sysmacroname + ,msg=%str(Please provide a fileref!) +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc) +) + +filename &outref temp; + +/* ensure outputs exist */ +data _null_; + file &outref; + put ' '; +run; +data &outds; + set &dclib..mpe_filtersource; + stop; +run; + +/** + * Deal with FILTER_RK first + */ +%if &filter_rk gt 0 %then %do; + + data _null_; + file &outref; + put '( '@@; + set &dclib..mpe_filteranytable(where=(filter_rk=&filter_rk)); + call symputx('filter_hash',filter_hash,'l'); + run; + + proc sort data=&dclib..mpe_filtersource(where=(filter_hash="&filter_hash")) + out=&outds(drop=filter_hash filter_line processed_dttm); + by filter_line; + run; + %mp_filtergenerate(&outds,outref=&outref) + +%end; + +/* Now filter for current records if the MODE is EDIT or DLOAD */ +%local varfrom varto; +%let varfrom=0; + +proc sql; +select coalescec(var_txfrom,'0'), var_txto into: varfrom,:varto + from &dclib..MPE_TABLES + where &dc_dttmtfmt. lt tx_to + and libref="%scan(&libds,1,.)" and dsn="%scan(&libds,2,.)"; + +%put &=varfrom; +%put &=varto; + +/** + * Check if the date variables were mentioned in the query + * This is a trigger for serving a historical view instead of current + * we skip this part when checking an ULOAD as there are no date vars + */ +%if &varfrom ne 0 and (&mode=EDIT or &mode=DLOAD) %then %do; + %local validityvars; + proc sql; + select count(*) into: validityvars + from &outds + where variable_nm in ("&varfrom","&varto"); + %if &validityvars=0 %then %do; + data _null_; + file &outref mod; + length filter_text $32767; + varfrom=symget('varfrom'); + varto=symget('varto'); + filter_text=catx(' ', + '("%sysfunc(datetime(),',"%mf_fmtdttm()",')"dt <',varto,')' + ); + if &filter_rk > 0 then put 'AND ' filter_text; + else put filter_text; + run; + %end; +%end; + +/** + * Now do Row Level Security based on the MPE_ROW_LEVEL_SECURITY table + */ + +/* first determine users group membership */ +%mpe_getgroups(user=%mf_getuser(),outds=work.groups) +%local admin_check; +proc sql; +select count(*) into: admin_check + from work.groups + where groupname="&mpeadmins"; + +%put &sysmacroname: &=admin_check &=mpeadmins; +%if &admin_check=0 %then %do; + %local scopeval; + %if &mode=DLOAD %then %let scopeval=VIEW; + %if &mode=ULOAD %then %let scopeval=EDIT; + %else %let scopeval=&mode; + /* extract relevant rows */ + %local rlsds; + %let rlsds=%mf_getuniquename(); + proc sql; + create table work.&rlsds as + select rls_group, + rls_group_logic as group_logic, + rls_subgroup_logic as subgroup_logic, + rls_subgroup_id as subgroup_id, + rls_variable_nm as variable_nm, + rls_operator_nm as operator_nm, + rls_raw_value as raw_value + from &mpelib..mpe_row_level_security + where &dc_dttmtfmt. lt tx_to + and rls_scope in ("&scopeval",'ALL') + and upcase(rls_group) in (select upcase(groupname) from work.groups) + and rls_libref="%scan(&libds,1,.)" + and rls_table="%scan(&libds,2,.)" + and rls_active=1 + order by rls_group,rls_subgroup_id; + %if &sqlobs>0 %then %do; + /* check if we currently have filter or not */ + data ; + infile &outref end=eof; + input; + if _n_=1 and eof and cats(_infile_)='' then newfilter=1; + output; + stop; + run; + data _null_; + set &syslast; + file &outref mod; + if newfilter=1 then put '('; + else put 'AND ('; + run; + + /* loop through and apply filters for each group membership */ + %local fref ds; + %let fref=%mf_getuniquefileref(); + %let ds=%mf_getuniquename(); + + proc sql noprint; + select distinct rls_group into : group1 - + from work.&rlsds; + + %do i=1 %to &sqlobs; + data work.&ds; + set work.&rlsds; + where rls_group="&&group&i"; + drop rls_group; + run; + %mp_filtergenerate(&ds,outref=&fref) + data _null_; + infile &fref; + file &outref mod; + input; + if &i>1 and _n_=1 then put ' OR '; + put _infile_; + run; + %end; + data _null_; + file &outref mod; + put ')'; + run; + %end; /* &sqlobs>0 */ + %else %do; + %put &sysmacroname: no matching groups; + data _null_; + set work.groups; + putlog (_all_)(=); + run; + %end; + %mp_abort(iftrue= (&syscc>0) + ,mac=&sysmacroname + ,msg=%str(Row Level Security Generation Error) + ) +%end; /* &admin_check=0 */ + +%put leaving &sysmacroname with the following query:; + +%local empty; +%let empty=0; +data _null_; + infile &outref end=eof; + input; + putlog _infile_; + if _n_=1 and eof and cats(_infile_)='' then do; + put '1=1'; + call symputx('empty',1,'l'); + end; +run; +%if &empty=1 %then %do; + data _null_; + file &outref; + put '1=1'; + run; +%end; + +%mend mpe_filtermaster; diff --git a/sas/sasjs/macros/mpe_filtermaster.test.1.sas b/sas/sasjs/macros/mpe_filtermaster.test.1.sas new file mode 100644 index 0000000..b54768f --- /dev/null +++ b/sas/sasjs/macros/mpe_filtermaster.test.1.sas @@ -0,0 +1,115 @@ +/** + @file + @brief setup mpe_filtermaster RLS test + @brief testing row level security + + +

SAS Macros

+ @li mf_getuniquename.sas + @li mf_getuser.sas + @li mp_assertcolvals.sas + @li mpe_filtermaster.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + + +/** + During tests, a DC group is made admin. By removing this account from the + MPE_GROUPS table and replacing with a SAS system group (that this account is + a member of) we can become a "regular" member. + */ + +proc sql; +delete from &dc_libref..MPE_GROUPS where user_name="%mf_getuser()"; + +%let tempgroup=%mf_getuniquename(); +insert into &dc_libref..MPE_GROUPS + set user_name="%mf_getuser()" + ,group_name="&tempgroup" + ,group_desc="temp group" + ,tx_from='01Jan1960:00:00:00'dt + ,tx_to='31Dec9999:23:59:59'dt; + +/** + Prep table + */ +delete from &dc_libref..MPE_ROW_LEVEL_SECURITY + where RLS_TABLE="MPE_X_TEST"; +select max(rls_rk) into: max_rk from &dc_libref..MPE_ROW_LEVEL_SECURITY; + +insert into &dc_libref..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=&max_rk+1 + ,RLS_SCOPE='ALL' + ,RLS_GROUP="&tempgroup" + ,RLS_LIBREF="&dc_libref" + ,RLS_TABLE="MPE_X_TEST" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=0 + ,RLS_VARIABLE_NM='SOME_DROPDOWN' + ,RLS_OPERATOR_NM='IN' + ,RLS_RAW_VALUE="('Option 1','Option 2')" + ,RLS_ACTIVE=1; + +/* + Test 1 - Expect 5 records: + + (( + LIBREF CONTAINS 'DC' + ) AND ( + DSN = 'MPE_LOCK_ANYTABLE' + )) + +*/ +%mpe_filtermaster(VIEW,&dc_libref..MPE_X_TEST, + dclib=&dc_libref, + outref=qref +) + +data _null_; + infile qref; + input; + if _n_=1 then put 'Test 1: filter query'; + put _infile_; +run; + +data work.test; + set &dc_libref..MPE_X_TEST; + where %inc qref;; +run; +proc sort data=work.test out=work.logme nodupkey; +by some_dropdown; +run; +%put checking values; +data _null_; + set work.logme; + put some_dropdown=; +run; + +data work.check; + val='Option 1';output; + val='Option 2';output; +run; +%mp_assertcolvals(work.test.SOME_DROPDOWN, + checkvals=work.check.val, + desc=Testing for RLS filtered rows in MPE_X_TEST, + test=ALLVALS +) + +/** + * put record back + */ +proc sql; +insert into &dc_libref..mpe_groups set + tx_from=&dc_dttmtfmt. + ,group_name="DC Demo Group" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="%mf_getuser()" + ,tx_to='31DEC5999:23:59:59'dt; diff --git a/sas/sasjs/macros/mpe_filtermaster.test.sas b/sas/sasjs/macros/mpe_filtermaster.test.sas new file mode 100644 index 0000000..f3a3d58 --- /dev/null +++ b/sas/sasjs/macros/mpe_filtermaster.test.sas @@ -0,0 +1,144 @@ +/** + @file + @brief setup mpe_filtermaster macro test + @details requires some filter rks, so step 1 is to trigger the validatefilter + STP + +

SAS Macros

+ @li mp_abort.sas + @li mp_assertdsobs.sas + @li mpe_filtermaster.sas + @li mp_filterstore.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +/* +proc printto log="/tmp/dcviya/%scan(&_program,-1,/)_%sysfunc(datetime()).log"; +run; +*/ + +/** + * STEP 1 - first, make filter + */ +data work.inquery; + infile datalines4 dsd; + input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. + OPERATOR_NM:$10. RAW_VALUE:$4000.; +datalines4; +AND,AND,1,LIBREF,CONTAINS,"'DC'" +AND,OR,2,DSN,=,"'MPE_LOCK_ANYTABLE'" +;;;; +run; +%mp_filterstore( + libds=&dc_libref..MPE_TABLES, + filter_summary=&dc_libref..mpe_filteranytable, + filter_detail=&dc_libref..mpe_filtersource, + lock_table=&dc_libref..mpe_lockanytable, + maxkeytable=&dc_libref..mpe_maxkeyvalues, + queryds=work.inquery, + outresult=work.result, + outquery=work.query +) +data _null_; + set work.result; + call symputx('filter_rk',filter_rk); + putlog (_all_)(=); +run; + + +/** + * begin testing! + */ + +/* + Test 1 - Expect 5 records: + + (( + LIBREF CONTAINS 'DC' + ) AND ( + DSN = 'MPE_LOCK_ANYTABLE' + )) + +*/ +%mpe_filtermaster(VIEW,&dclib..MPE_TABLES, + dclib=&dclib, + filter_rk=&filter_rk, + outref=qref +) +data work.out; + infile qref; + input; + put _infile_; +run; +%mp_assertdsobs(work.out, + desc=Test 1 - Five records from simple query, + test=EQUALS 5, + outds=work.test_results +) + +/* + Test 2 - Expect 6 records from an EDIT query + + (( + LIBREF CONTAINS 'DC' + ) AND ( + DSN = 'MPE_LOCK_ANYTABLE' + )) + AND ( %sysfunc(datetime()) < TX_TO ) + +*/ + +%mpe_filtermaster(EDIT,&dclib..MPE_TABLES, + dclib=&dclib, + filter_rk=&filter_rk, + outref=qref +) +data work.out; + infile qref; + input; + put _infile_; +run; +%mp_assertdsobs(work.out, + desc=Test 2 - Six records from EDIT query, + test=EQUALS 6, + outds=work.test_results +) + +/* + Test 3 - Empty query + + +*/ +data work.class; + do age=1 to 19; + weight=age*1.3; + output; + end; +run; +%mpe_filtermaster(VIEW,work.class, + dclib=&dclib, + filter_rk=-1, + outref=qref3 +) +data _null_; + infile qref3; + input; + putlog _infile_; +run; +data work.out3; + set work.class; + where %inc qref3;; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc in Test 3) +) +%mp_assertdsobs(work.out3, + desc=Test 3 - all records returned due to empty query, + test=EQUALS 19, + outds=work.test_results +) diff --git a/sas/sasjs/macros/mpe_getgroups.sas b/sas/sasjs/macros/mpe_getgroups.sas new file mode 100644 index 0000000..b60334c --- /dev/null +++ b/sas/sasjs/macros/mpe_getgroups.sas @@ -0,0 +1,39 @@ +/** + @file mpe_getgroups.sas + @brief Gets groups from metadata and augments with DC groups + @details Fetches groups using relevant logic (Viya, EBI, Base) and augments + with the contents of the MPE_GROUPS table. + + %mpe_getgroups(user=&user,outds=work.usergroups) + +

SAS Macros

+ @li dc_getusergroups.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_getgroups(user=,outds=); + + %if not %symexist(dc_repo_users) %then %let dc_repo_users=foundation; + + %dc_getusergroups(user=&user,outds=&outds) + + data; + length groupname groupdesc $256; + set &dc_libref..mpe_groups; + where &dc_dttmtfmt. lt tx_to; + where also upcase(user_name)="%upcase(&user)"; + groupname=group_name; + groupdesc=group_desc; + keep groupname groupdesc; + run; + + data &outds; + set &syslast &outds(keep=groupname groupdesc); + run; + +%mend mpe_getgroups; diff --git a/sas/sasjs/macros/mpe_getlabels.sas b/sas/sasjs/macros/mpe_getlabels.sas new file mode 100644 index 0000000..2837a4a --- /dev/null +++ b/sas/sasjs/macros/mpe_getlabels.sas @@ -0,0 +1,38 @@ +/** + @file mpe_getlabels.sas + @brief Gets the table and column labels for a particular table + @details Takes labels first from mpe_datadictionary then from table metadata. + +

SAS Macros

+ @li mf_getuniquename.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_getlabels(type,source,outds=mpe_getlabels); +%local tmpds; + +%if &type=COLUMNS %then %do; + %let tmpds=%mf_getuniquename(); + proc contents noprint data=&source + out=&tmpds(keep=name memlabel label); + run; + proc sql ; + create table &outds as + select upcase(a.name) as name + ,a.memlabel + ,coalesce(b.dd_shortdesc,a.label) as desc + ,b.dd_longdesc as longdesc + from &tmpds a + left join &mpelib..mpe_datadictionary + (where=(&dc_dttmtfmt. < tx_to + and dd_source ? %upcase("&source") + and dd_type='COLUMN')) b + on scan(b.dd_source,-1,'.')=upcase(a.name); +%end; + +%mend mpe_getlabels; diff --git a/sas/sasjs/macros/mpe_getvars.sas b/sas/sasjs/macros/mpe_getvars.sas new file mode 100644 index 0000000..73a646d --- /dev/null +++ b/sas/sasjs/macros/mpe_getvars.sas @@ -0,0 +1,27 @@ +/** + @file + @brief Takes a input table and makes every variable a macro variable + @details If table has multiple records, only first record is used. + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_getvars(injs,outds); + /* load parameters */ + data _null_; + __dummychar='';__dummynum=0; + set &outds; + array __charvals _character_; + do over __charvals; + call symputx(vname(__charvals),__charvals,'g'); + end; + array __numvals _numeric_; + do over __numvals; + call symputx(vname(__numvals),__numvals,'g'); + end; + run; +%mend mpe_getvars; diff --git a/sas/sasjs/macros/mpe_loader.sas b/sas/sasjs/macros/mpe_loader.sas new file mode 100755 index 0000000..eccfc41 --- /dev/null +++ b/sas/sasjs/macros/mpe_loader.sas @@ -0,0 +1,590 @@ +/** + @file + @brief Loads CSV and sends to the staging area for approval + @details this macro used to capture multiple CSVs (eg from one excel file) in + a staging area and send them all to a landing area. For simplicity this + functionality is now deprecated, and each load should be made as a seperate + request. If there is a use case to load multiple tables at once, the client + should manage this and load them seperately. + + @param url= used for debugging (provided by stagedata stp) + @param dlm= use to provide alternative delimeters for CSVs (not just comma) + @param [in] termstr= (crlf) Always crlf from adapter, whereas loadfile service + figures it out + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_getattrn.sas + @li mf_getuser.sas + @li mf_mkdir.sas + @li mf_verifymacvars.sas + @li mp_abort.sas + @li mp_cntlout.sas + @li mp_dirlist.sas + @li mp_lockanytable.sas + @li mpe_accesscheck.sas + @li mpe_alerts.sas + @li mpe_loadfail.sas + @li mpe_runhook.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_loader( + mperef= /* name of subfolder containing the staged data */ + ,mDebug=0 /* set to 1 for development or debugging */ + ,submitted_reason_txt= /* populates column of same name in sumo_approvals*/ + ,approver= /* allows a userid to be provided for direct approval email */ + ,url= /* optional - url for debugging */ + ,dlm=%str(,) + ,termstr=crlf + ,dc_dttmtfmt=E8601DT26.6 + ); +%put entered mpe_loader from &=_program; +%put &=url; +%put &=termstr; +%put &=dlm; + /* determine full path to CSV directory */ +%local now; +%let now=&dc_dttmtfmt; +%put &=now; + +/** + * get full path to package (only subdirectory passed through) + */ +%mp_abort( + iftrue=(%mf_verifymacvars(mperef mpelocapprovals)=0) + ,mac=bitemporal_dataloader + ,msg=%str(Missing: mperef mpelocapprovals) +) + +%let csv_dir=%trim(&mpelocapprovals/&mperef); + +/* exit if package has already been uploaded */ +%local check; +proc sql noprint; +select count(*) into: check + from &mpelib..mpe_loads + where csv_dir="&mperef"; +%if &check %then %do; + %mp_abort(msg=Folder &mperef already has an entry in &mpelib..mpe_loads + ,mac=mpe_loader.sas); + %return; +%end; + +/* get CSV directory contents */ +%mp_dirlist(path=&csv_dir,outds=WORK.getfiles) +data WORK.csvs; + set WORK.getfiles; + if upcase(scan(filename,3,'.'))='CSV' then do; + lib=upcase(scan(filename,1,'.')); + ds=upcase(scan(filename,2,'.')); + output; + end; +run; + +/* get table attributes */ +proc sql noprint; +create table WORK.sumo_tables as + select a.filename, b.* + from WORK.csvs a + left join &mpelib..mpe_tables b + on a.lib=b.libref + and a.ds=b.dsn + where b.tx_from le &now + and &now lt b.tx_to; + +/* define user as meta user if available */ +%local user; +%let user=%mf_getuser(); + +/* check if there is actually a table to load */ +%if %mf_getattrn(WORK.sumo_tables,NLOBS)=0 %then %do; + %let msg=Table not registered in &mpelib..mpe_tables; + %mpe_loadfail( + status=&msg + ,now=&now + ,mperef=&mperef + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %mp_abort(msg=&msg,mac=mpe_loader.sas); + %return; +%end; + +proc sql; +insert into &mpelib..mpe_loads + set USER_NM="&user" + ,STATUS='IN PROGRESS' + ,CSV_dir="&mperef" + ,PROCESSED_DTTM=&now; + + +/* import CSV */ + +%let droplist=; +%let attrib=; +%let droplist=; +%let libref=; +%let DS=; + +/* get table info */ +data _null_; + set sumo_tables; + libds=upcase(cats(libref,'.',dsn)); + call symputx('orig_libds',libds); + is_fmt=0; + if substr(cats(reverse(dsn)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + libds='work.fmtextract'; + is_fmt=1; + end; + call symputx('is_fmt',is_fmt); + call symputx('libds',libds); + call symputx('FNAME',filename); + call symputx('LIBREF',libref); + call symputx('DS',dsn); + call symputx('LOADTYPE',loadtype); + call symputx('BUSKEY',buskey); + call symputx('VAR_TXFROM',var_txfrom); + call symputx('VAR_TXTO',var_txto); + call symputx('VAR_BUSFROM',var_busfrom); + call symputx('VAR_BUSTO',var_busto); + call symputx('VAR_PROCESSED',var_processed); + call symputx('RK_UNDERLYING',RK_UNDERLYING); + call symputx('POST_EDIT_HOOK',POST_EDIT_HOOK); + call symputx('NOTES',NOTES); + call symputx('PK',coalescec(RK_UNDERLYING,buskey)); + call symputx('NUM_OF_APPROVALS_REQUIRED',NUM_OF_APPROVALS_REQUIRED,'l'); + put (_all_)(=); + stop; +run; + +%if %length(&ds)=0 %then %do; + %let msg=%str(ERR)OR: Unable to extract record from &mpelib..mpe_tables; + %mpe_loadfail( + status=FAILED + ,now=&now + ,mperef=&mperef + ,reason_txt=%quote(&msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %mp_abort(msg=&msg,mac=mpe_loader.sas); + %return; +%end; + +/* export format catalog */ +%mp_cntlout( + iftrue=(&is_fmt=1) + ,libcat=&orig_libds + ,fmtlist=0 + ,cntlout=work.fmtextract +) + +/* user must have EDIT access to load a table */ +%mpe_accesscheck(&orig_libds + ,outds=work.sumo_access + ,user=&user + ,access_level=EDIT ) +%put exiting accesscheck; + +%if %mf_getattrn(work.sumo_access,NLOBS)=0 %then %do; + %let msg=%str(ERR)OR: User is not authorised to edit &orig_libds!; + %mpe_loadfail( + status=UNAUTHORISED + ,now=&now + ,mperef=&mperef + ,reason_txt=%quote(&msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %mp_abort(msg=&msg,mac=mpe_loader.sas); + %return; +%end; + +%put now importing: "&csv_dir/&fname" termstr=&termstr; +/* get the variables from the CSV */ +data vars_csv1(index=(idxname=(varnum name)) drop=infile); + infile "&csv_dir/&fname" lrecl=32767 dsd termstr=&termstr encoding='utf-8'; + input; + length infile $32767; + infile=compress(_infile_,'"',); + infile=compress(infile,"'",); + format name $32.; + putlog 'received vars: ' infile; + call symputx('received_vars',infile,'l'); + do varnum=1 to countw(infile,"&dlm"); + /* keep writeable chars */ + name=compress(upcase(scan(infile,varnum)),,'kw'); + if name ne "_____DELETE__THIS__RECORD_____" then output; + end; + stop; +run; +%put received_vars = &received_vars; + +%dc_assignlib(WRITE,&libref) + +/* get list of variables and their formats */ +proc contents noprint data=&libds + out=vars(keep=name type length varnum format:); +run; +data vars(keep=name type length varnum format); + set vars(rename=(format=format2 type=type2)); + name=upcase(name); + format2=upcase(format2); + /* not interested in transaction or processing dates + (append table must be supplied without them) */ + if name not in ("&VAR_TXFROM","&VAR_TXTO","&VAR_PROCESSED" + ,"_____DELETE__THIS__RECORD_____"); + if type2 in (2,6) then do; + length format $49.; + if format2='' then format=cats('$',length,'.'); + else format=cats(format2,max(formatl,length),'.'); + type='char'; + end; + else do; + if format2='' then format=cats(length,'.'); + else if format2=:'DATETIME' or format2=:'E8601DT' then do; + format='DATETIME19.'; + end; + else if format2=:'DATE' or format2=:'DDMMYY' + or format2=:'MMDDYY' or format2=:'YYMMDD' + or format2=:'E8601DA' or format2=:'B8601DA' + then do; + format='DATE9.'; + end; + else if format2='BEST' & formatl=0 then format=cats('BEST',length,'.'); + /* + else if format2=:'DATETIME' or format2=:'DATE' or format2=:'DDMMYY' + or format2=:'MMDDYY' or format2=:'YYMMDD' then do; + *date or datetime format so use original ; + dsid=open("&libref..&ds"); + vnum=varnum(dsid,name); + format=varfmt(dsid,vnum); + dsid=close(dsid); + end; + */ + else do; + if formatl=0 then formatl=length; + format=cats(format2,formatl,'.',formatd); + end; + type='num'; + end; + put (_all_)(=); +run; + +/* build attrib statement */ +data vars_attrib; + length attrib_statement $32767 type2 $20; + set vars end=lastobs; + retain attrib_statement; + + if type='char' then type2='$'; + str1=catx(' ',name,'length=',cats(type2,length)); + attrib_statement=trim(attrib_statement)!!' '!!trim(str1); + + if lastobs then call symputx('ATTRIB',attrib_statement,'L'); +run; + +/* build input statement - first get vars in right order + and join with target formats*/ +proc sql noprint; +create table vars_csv2 as + select b.* + from vars_csv1 a + left join vars_attrib b + on a.name=b.name + order by a.varnum; + + /* make sure that the variables we are importing, actually + exist on the target table */ + + /** edit - extra variables are now simply ignored + %local very_bad_vars; + select name into: very_bad_vars separated by ' ' + from vars_csv1 + where name not in (select name from vars) + and name ne "_____DELETE__THIS__RECORD_____"; + %if %length(&very_bad_vars) > 0 %then %do; + %let msg=%str(WARNING: The following vars are not defined in %trim( + )&libref..&ds, yet they exist in &csv_dir/&ds..csv: &very_bad_vars); + %mpe_loadfail( + status=FAILED + ,now=&now + ,mperef=&mperef + ,reason_txt=%quote(&msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %return; + %end; + **/ + +/* now build input statement */ +data final_check; + set vars_csv2 end=lastobs; + length input_statement $32767 type2 $20 droplist $32767; + retain input_statement droplist; + + /* Build input statement - CATCH EXCEPTIONS HERE!*/ + if name in ('QUOTE_DTTM') then do; + name=cats(name,'2'); + droplist=catx(' ',trim(droplist),name); + type2='$20.';/* converted below */ + end; + else if type='char' then type2=cats('$CHAR', length,'.'); + else if format='DATE9.' then type2='ANYDTDTE.'; + else if format='DATETIME19.' then type2='ANYDTDTM.'; + else if format=:'TIME' then type2='ANYDTTME.'; + else if name='' then do;/* additional vars in input data */ + name='_____DELETE__THIS__VARIABLE_____'; + droplist=catx(' ',trim(droplist),'_____DELETE__THIS__VARIABLE_____'); + type2='$1.'; + end; + else type2='best32.'; + * else type2=cats(length,'.'); + + input_statement=catx(' ',input_statement,name,':',type2); + + if lastobs then do; + call symputx('INPUT', input_statement,'L'); + if trim(droplist) ne '' then + call symputx('droplist',"drop "!!droplist!!';','l'); + end; +run; + +%let mpeloadstop=0; + +data work.STAGING_DS; + &droplist; + infile "&csv_dir/&fname" dsd dlm="&dlm" lrecl=32767 + firstobs=2 missover termstr=&termstr encoding='utf-8'; + attrib &attrib ; + if _n_=1 then call missing (of _all_); + missing a b c d e f g h i j k l m n o p q r s t u v w x y z _; + input + %if %scan(%quote(&received_vars),1)=_____DELETE__THIS__RECORD_____ %then %do; + _____DELETE__THIS__RECORD_____: $3. + %end; + &input; + + %if %index(%quote(&attrib.),UNLIKELY_VAR ) %then %do; + /*UNLIKELY_VAR=input(UNLIKELY_VAR2,ANYDTDTM21.);*/ + /* SPECIAL LOGIC FOR SPECIAL VARS */ + %end; + + if _error_ ne 0 then do; + putlog _infile_; + call symputx('mpeloadstop',_n_); + stop; + end; + /* remove all blank rows */ + if compress(cats(of _all_),'.')=' ' then delete; +run; + +%if &mpeloadstop>0 %then %do; + %if %symexist(SYSPRINTTOLOG) %then %let logloc=&SYSPRINTTOLOG; + %else %let logloc=%qsysfunc(getoption(LOG)); + %put redirecting log output to capture return message; + %put currentloc=&logloc; + filename tmp temp; + proc printto log=tmp;run; + data _null_; + &droplist; + infile "&csv_dir/&fname" dsd dlm="&dlm" lrecl=32767 firstobs=2 + missover termstr=&termstr; + attrib &attrib ; + input + %if %scan(%quote(&received_vars),1)=_____DELETE__THIS__RECORD_____ + %then %do; + _____DELETE__THIS__RECORD_____: $3. + %end; + &input; + if _error_ then stop; + run; + /* get log back */ + proc printto log=&logloc;run; + data _null_; infile tmp; input; putlog _infile_;run; + /* scan log for invalid data warning */ + data _null_; + infile tmp; + input; + length msg1 msg2 msg3 msg4 msg5 msg url $32767; + if index(_infile_,'NOTE: Invalid data for') then do; + msg1=_infile_; + input; + msg2=_infile_; + input; + msg3=_infile_; + input; + msg4=_infile_; + input; + msg5=_infile_; + url=symget('url'); + msg=catx('\n',msg1,msg2,msg3,msg4,msg5,'\n',url); + call symputx('msg',msg); + stop; + end; + run; + + %mpe_loadfail( + status=FAILED + ,now=&now + ,mperef=&mperef + ,reason_txt=%superq(msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %return; +%end; + +/* check that the table is unique on PK */ +proc sort data=work.STAGING_DS dupout=work.MPE_DUPS (keep=&pk) nodupkey; + by &pk; +run; +%if %mf_getattrn(work.MPE_DUPS,NLOBS)>0 %then %do; + %local duplist; + data _null_; + set work.mpe_dups; + %do i=1 %to %sysfunc(countw(&pk)); + %let iWord=%scan(&pk,&i); + call symputx('duplist',symget('duplist')!! + " &iWord="!!trim(&iWord)); + %end; + run; + %let msg=This upload contains duplicates on the Primary Key columns %trim( + )(&pk) \n Please remove the duplicates and try again. %trim( + )\n &duplist \n ; + %mp_abort(msg=%superq(msg),mac=mpe_loader.sas); + %return; +%end; + +%if &syscc gt 4 %then %do; + %let msg=SYSCC=&syscc prior to post edit hook (%superq(syserrortext)); + %mpe_loadfail( + status=FAILED - &syscc + ,now=&now + ,mperef=&mperef + ,reason_txt=%superq(msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %return; +%end; + +%mpe_runhook(POST_EDIT_HOOK) + +/* stop if err */ +%if &syscc gt 4 %then %do; + %let msg=ERR in post edit hook (&post_edit_hook); + %mpe_loadfail( + status=FAILED - &syscc + ,now=&now + ,mperef=&mperef + ,reason_txt=%quote(&msg) + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %return; +%end; + + +/** + * send to approve process + */ + +/* create a dataset key (datetime plus 3 digit random number plus PID) */ + +/* send dataset to approvals subfolder with same name as subfolder */ +libname approval "&mpelocapprovals/&mperef"; +data approval.&mperef; + set work.staging_ds; +run; +proc export data=approval.&mperef + outfile="&mpelocapprovals/&mperef/&mperef..csv" + dbms=csv + replace; +run; + +/* update the control dataset with relevant info */ +data append_app; + if 0 then set &mpelib..mpe_submit;/* get formats */ + call missing (of _all_); + TABLE_ID="&mperef"; + submit_status_cd='SUBMITTED'; + submitted_by_nm="%mf_getuser()"; + base_lib="&libref"; + base_ds="&ds"; + submitted_on_dttm=&now; + submitted_reason_txt=symget('submitted_reason_txt'); + input_vars=%mf_getattrn(approval.&mperef,NVARS); + input_obs=%mf_getattrn(approval.&mperef,NLOBS); + num_of_approvals_required=&NUM_OF_APPROVALS_REQUIRED; + num_of_approvals_remaining=&NUM_OF_APPROVALS_REQUIRED; + reviewed_by_nm=''; + reviewed_on_dttm=.; +run; + +%mp_lockanytable(LOCK,lib=&mpelib,ds=mpe_submit, + ref=%str(&mperef update in &_program), + ctl_ds=&mpelib..mpe_lockanytable +) +proc append base= &mpelib..mpe_submit data=append_app; +run; +%mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_submit, + ctl_ds=&mpelib..mpe_lockanytable +) + +/* send email to REVIEW members */ +%put sending mpe_alerts; +%mpe_alerts(alert_event=SUBMITTED + , alert_lib=&libref + , alert_ds=&ds + , dsid=&mperef +) +/* DISABLE EMAIL FOR NOW + %let b2=REASON: %quote(&submitted_reason_txt); + + %local URLNOTES; + %if %length(¬es)>0 %then %let URLNOTES=%quote(%sysfunc(urlencode(¬es))); + + %let b3=%str(Click to review / approve: )%trim( + )%str(http://&_srvname:&_srvport&_url?_PROGRAM=/Web/approvals&)%trim( + )TABLEID=&dsid%str(&)BASETABLE=&libref..&ds%str(&)NOTES=&URLNOTES; + + %let b4=%str(Reference ID: &mperef); +*/ + +%put mpe_loader finishing up with syscc=&syscc; +%if &syscc le 4 %then %do; + %local dur; + data _null_; + now=symget('now'); + dur=%sysfunc(datetime())-&now; + call symputx('dur',dur,'l'); + putlog 'Updating mpe_loads with the following query:'; + putlog "update &mpelib..mpe_loads set STATUS='SUCCESS'"; + putlog " , duration=" dur; + putlog " , processed_dttm=" now; + putlog " , approvals = '&libref..&ds'"; + putlog " where CSV_DIR='&mperef';"; + run; + proc sql; + update &mpelib..mpe_loads set STATUS='SUCCESS' + , duration=&dur + , processed_dttm=&now + , approvals = "&libref..&ds" + where CSV_DIR="&mperef"; +%end; +%else %do; + %mpe_loadfail( + status="FAILED - &syscc" + ,now=&now + ,approvals=&libref..&ds + ,mperef=&mperef + ,dc_dttmtfmt=&dc_dttmtfmt. + ) + %return; +%end; + +%mend mpe_loader; diff --git a/sas/sasjs/macros/mpe_loadfail.sas b/sas/sasjs/macros/mpe_loadfail.sas new file mode 100755 index 0000000..8c08fe2 --- /dev/null +++ b/sas/sasjs/macros/mpe_loadfail.sas @@ -0,0 +1,44 @@ +/** + @file + @brief Updates the mpe_loads tracking table with success / failure info + @details + +

SAS Macros

+ @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + + +%macro mpe_loadfail( + status=FAILED - &syscc + ,now=%sysfunc(datetime()) + ,approvals= + ,mperef= + ,reason_txt= + ,mac=mpe_loadfail.sas + ,dc_dttmtfmt=E8601DT26.6 + ); + /* do not perform duration calc in pass through */ + %local dur; + data _null_; + now=symget('now'); + dur=%sysfunc(datetime())-&now; + call symputx('dur',dur,'l'); + run; + proc sql; + update &mpelib..mpe_loads + set STATUS=symget('status') + , duration=&dur + , processed_dttm=&dc_dttmtfmt. + , approvals = symget('approvals') + , reason_txt= symget('reason_txt') + where CSV_DIR="&mperef"; + %let syscc=666; + %mp_abort(msg=%superq(status)\n%superq(reason_txt),mac=&mac) +%mend mpe_loadfail; diff --git a/sas/sasjs/macros/mpe_makedata.sas b/sas/sasjs/macros/mpe_makedata.sas new file mode 100644 index 0000000..f286085 --- /dev/null +++ b/sas/sasjs/macros/mpe_makedata.sas @@ -0,0 +1,1801 @@ +/** + @file + @brief Populates the Data Controller tables with sample data + @details + + Usage: + + %mpe_makedata(lib=DC869651 + ,mpeadmins=SASAdministrators + ,path=/opt/data/dc/VIYA8698 + ) + +

SAS Macros

+ @li mf_increment.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd - this is a licensed product and NOT FOR RESALE + OR DISTRIBUTION. +**/ + +%macro mpe_makedata(lib=,mpeadmins=,path=); +%if &syscc ne 0 %then %do; + %put syscc=&syscc exiting &sysmacroname; + %return; +%end; + +proc sql; +insert into &lib..mpe_alerts set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,alert_event='*ALL*' + ,alert_lib='*ALL*' + ,alert_ds='*ALL*' + ,alert_user="&sysuserid"; + +insert into &lib..mpe_column_level_security set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,CLS_SCOPE='EDIT' + ,CLS_GROUP='AllUsers' + ,CLS_LIBREF="&lib" + ,CLS_TABLE='MPE_LOCKANYTABLE' + ,CLS_VARIABLE_NM='LOCK_STATUS_CD' + ,CLS_ACTIVE=1 + ,CLS_HIDE=0; + +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_EMAIL_ALERTS" + ,var_value='NO' + ,var_active=1 + ,var_desc='YES or NO to enable email alerts. Note - this requires email ' + !!'options to be preconfigured! They can be configured in the ' + !!'settings stp if needed.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_VIEWLIB_CHECK" + ,var_value='NO' + ,var_active=1 + ,var_desc= + 'Set to YES to enable library validity checking in viewLibs service.' + !!' Note: this can make the service very slow if there are lots of ' + !!'external libraries. If enabled, this removes empty libraries from ' + !!'the viewer library dropdown. To switch off, set to NO.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_MACROS" + ,var_value=cats(symget('path'),"/dc_macros") + ,var_active=1 + ,var_desc='Location of underlying macros - EUC feature.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_MAXOBS_WEBEDIT" + ,var_value="100" + ,var_active=1 + ,var_desc='This sets the maximum number of observations that can be loaded' + !!' into the browser for editing in the EDIT screen. A higher number' + !!' will require a decent browser (ie, not IE) and more memory on the' + !!' client side.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_RESTRICT_VIEWER" + ,var_value="NO" + ,var_active=1 + ,var_desc='YES will restrict the list of libraries and tables in VIEWER to' + !!' those explicitly set to VIEW in the MPE_SECURITY table. Default=NO.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_RESTRICT_EDITRECORD" + ,var_value="NO" + ,var_active=1 + ,var_desc='Setting YES will prevent the EDIT RECORD dialog appearing in the' + !!' EDIT screen by removing the "Edit Row" option in the right click menu' + !!', and the "ADD RECORD" button in the bottom left. Default=NO.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC_CATALOG" + ,var_name="DC_IGNORELIBS" + ,var_value="|MAPSSAS|MAPS|" + ,var_active=1 + ,var_desc='Pipe seperated list of librefs (uppercase) to be ignored when' + !!' running the Data Catalog refresh process. This can enable a clean' + !!' run when invalid librefs are returned by the mpe_refreshlibs macro.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_LOCALE" + ,var_value="SYSTEM" + ,var_active=1 + ,var_desc='Set to a locale (such as en_gb or en_be) to override the system' + !!' value (which can be driven from the browser settings). This is ' + !!'useful when importing ambiguous dates from CSV or Excel (eg 1/2/20 vs ' + !!'2/1/20) as DC uses the anydtdtm informats for import. Default=SYSTEM.'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BULKLOAD" + ,var_value="YES" + ,var_active=0 + ,var_desc='Set to YES to enable BULKLOAD=YES in redshift'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BL_BUCKET" + ,var_value="'your-aws-bucket/Exchange'" + ,var_active=0 + ,var_desc='Set to the (quoted) value of the AWS bucket to' + !!' use for s3 uploads in redshift'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BL_AWS_CREDENTIALS_FILE" + ,var_value="'/path/to/your/aws/s3/.credentials'" + ,var_active=0 + ,var_desc='Set to the (quoted) value of the AWS creds file'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BL_REGION" + ,var_value="'eu-west-1'" + ,var_active=0 + ,var_desc='Set to the (quoted) AWS region in use'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BL_COMPRESS" + ,var_value="YES" + ,var_active=0 + ,var_desc='Set to YES to perform compression ahead of the COPY command'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DCBL_REDSH" + ,var_name="BL_USE_SSL" + ,var_value="YES" + ,var_active=0 + ,var_desc='Set to YES to use SSL encryption'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC_REVIEW" + ,var_name="HISTORY_ROWS" + ,var_value='100' + ,var_active=1 + ,var_desc='Number of rows (or additional rows) to return in the HISTORY ' + !!'page'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_LICENCE_KEY" + ,var_value=' ' + ,var_active=1 + ,var_desc='Licence Key'; +insert into &lib..mpe_config set + tx_from=0 + ,tx_to='31DEC9999:23:59:59'dt + ,var_scope="DC" + ,var_name="DC_ACTIVATION_KEY" + ,var_value=' ' + ,var_active=1 + ,var_desc='Activation Key'; + + +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='LIBRARY' + ,DD_SOURCE="&lib" + ,DD_SHORTDESC="Data Controller Control Tables" + ,DD_LONGDESC="# The Data Controller Library" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='TABLE' + ,DD_SOURCE="&lib..MPE_TABLES" + ,DD_SHORTDESC="Configuration of new tables for Data Controller" + ,DD_LONGDESC="# MPE_TABLES - adding new tabels to Data Controller" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='COLUMN' + ,DD_SOURCE="&lib..MPE_TABLES.DSN" + ,DD_SHORTDESC="Dataset Name to be edited" + ,DD_LONGDESC="_DSN_ - must be UPCASE" + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='DIRECTORY' + ,DD_SOURCE="/some/directory" + ,DD_SHORTDESC="Directory for some purpose" + ,DD_LONGDESC="This directory is great. It's great directory. + It trumps all other directories." + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='TABLE' + ,DD_SOURCE="&lib" + ,DD_SHORTDESC="Transaction table for capturing Data Controller users" + ,DD_LONGDESC="After a user accepts the Data Controller EULA they are " + !!"registered as a user in this table." + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_datadictionary set + tx_from=0 + ,DD_TYPE='COLUMN' + ,DD_SOURCE="&lib..MPE_CONFIG.VAR_ACTIVE" + ,DD_SHORTDESC="Set to 1 to make an option active" + ,DD_LONGDESC="This value is used as a filter by data controller whenever " + !!"querying for option settings." + ,DD_OWNER="&sysuserid" + ,DD_RESPONSIBLE="&sysuserid" + ,DD_SENSITIVITY="Low" + ,tx_to='31DEC5999:23:59:59'dt; + +/** + * MPE_GROUPS + */ +insert into &lib..mpe_groups set + tx_from=0 + ,group_name="dc-admin" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="allbow" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_groups set + tx_from=0 + ,group_name="dc-admin" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="dctestuser1" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_groups set + tx_from=0 + ,group_name="dc-admin" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="mihmed" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_groups set + tx_from=0 + ,group_name="sec-sas9-prd-ext-sasplatform-300115datacontroller" + ,group_desc="Custom Group for Data Controller Purposes" + ,user_name="DCTest" + ,tx_to='31DEC5999:23:59:59'dt; + +/** + * MPE_ROW_LEVEL_SECURITY + */ +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=1 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_GROUPS" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=0 + ,RLS_VARIABLE_NM='GROUP_NAME' + ,RLS_OPERATOR_NM='NE' + ,RLS_RAW_VALUE="'-1'" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=2 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib" + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=0 + ,RLS_VARIABLE_NM='RLS_RK' + ,RLS_OPERATOR_NM='>' + ,RLS_RAW_VALUE='0' + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=3 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='DC Demo Group' + ,RLS_LIBREF="&lib" + ,RLS_TABLE="MPE_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=0 + ,RLS_VARIABLE_NM='ACCESS_LEVEL' + ,RLS_OPERATOR_NM='NE' + ,RLS_RAW_VALUE="'N/A'" + ,RLS_ACTIVE=1; + + +/** + * MPE_SECURITY + */ +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="APPROVE" + ,sas_group="sec-sas9-prd-int-sasplatform-300114sasjs" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="EDIT" + ,sas_group="sec-sas9-prd-int-sasplatform-300114sasjs" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="APPROVE" + ,sas_group="sec-sas9-prd-ext-sasplatform-300114sasjs" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="EDIT" + ,sas_group="sec-sas9-prd-ext-sasplatform-300114sasjs" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="EDIT" + ,sas_group="dc-admin" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="APPROVE" + ,sas_group="dc-admin" + ,tx_to='31DEC5999:23:59:59'dt; + + + /* mpe_selectbox */ + %let rk=1; + insert into &lib..mpe_selectbox set + selectbox_rk=&rk + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_LOCKANYTABLE" + ,base_column="LOCK_STATUS_CD" + ,selectbox_value='LOCKED' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_LOCKANYTABLE" + ,base_column="LOCK_STATUS_CD" + ,selectbox_value='UNLOCKED' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='EDIT' + ,selectbox_order=0 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='APPROVE' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='VIEW' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='SIGNOFF' + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='UPDATE' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='REPLACE' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='TXTEMPORAL' + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='BITEMPORAL' + ,selectbox_order=4 + ,ver_to_dttm='31DEC5999:23:59:59'dt; +insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_TABLES" + ,base_column="LOADTYPE" + ,selectbox_value='FORMAT_CAT' + ,selectbox_order=5 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ALERTS" + ,base_column="ALERT_EVENT" + ,selectbox_value='*ALL*' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ALERTS" + ,base_column="ALERT_EVENT" + ,selectbox_value='SUBMITTED' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ALERTS" + ,base_column="ALERT_EVENT" + ,selectbox_value='APPROVED' + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ALERTS" + ,base_column="ALERT_EVENT" + ,selectbox_value='REJECTED' + ,selectbox_order=4 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_X_TEST" + ,base_column="SOME_DROPDOWN" + ,selectbox_value='Option 1' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_X_TEST" + ,base_column="SOME_DROPDOWN" + ,selectbox_value='Option 2' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_X_TEST" + ,base_column="SOME_DROPDOWN" + ,selectbox_value='Option 3' + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_X_TEST" + ,base_column="SOME_DROPDOWN" + ,selectbox_value="This is a long option. This option is very long. " + !!"It is optional, though." + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="CASE" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="MINVAL" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="MAXVAL" + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="HARDSELECT" + ,selectbox_order=4 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="SOFTSELECT" + ,selectbox_order=5 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="NOTNULL" + ,selectbox_order=6 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="DSN" + ,selectbox_value="SOME_DATASET" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="DSN" + ,selectbox_value="EXAMPLE" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_DATADICTIONARY" + ,base_column="DD_TYPE" + ,selectbox_value="COLUMN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_DATADICTIONARY" + ,base_column="DD_TYPE" + ,selectbox_value="TABLE" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_DATADICTIONARY" + ,base_column="DD_TYPE" + ,selectbox_value="LIBRARY" + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_DATADICTIONARY" + ,base_column="DD_TYPE" + ,selectbox_value="CATALOG" + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_DATADICTIONARY" + ,base_column="DD_TYPE" + ,selectbox_value="FORMAT" + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="LIBREF" + ,selectbox_value='*ALL*' + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_SECURITY" + ,base_column="ACCESS_LEVEL" + ,selectbox_value='AUDIT' + ,selectbox_order=4 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="HARDSELECT_HOOK" + ,selectbox_order=7 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_VALIDATIONS" + ,base_column="RULE_TYPE" + ,selectbox_value="SOFTSELECT_HOOK" + ,selectbox_order=7 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="ALL" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="EDIT" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SCOPE" + ,selectbox_value="VIEW" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_GROUP_LOGIC" + ,selectbox_value="AND" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_GROUP_LOGIC" + ,selectbox_value="OR" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SUBGROUP_LOGIC" + ,selectbox_value="AND" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_SUBGROUP_LOGIC" + ,selectbox_value="OR" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="=" + ,selectbox_order=0 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value=">" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="<" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="<=" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value=">=" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="BETWEEN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="IN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="NOT IN" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="NE" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_OPERATOR_NM" + ,selectbox_value="CONTAINS" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_EXCEL_CONFIG" + ,base_column="XL_RULE" + ,selectbox_value="FORMULA" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_ACTIVE" + ,selectbox_value="1" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_ROW_LEVEL_SECURITY" + ,base_column="RLS_ACTIVE" + ,selectbox_value="0" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_ACTIVE" + ,selectbox_value="1" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_ACTIVE" + ,selectbox_value="0" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_SCOPE" + ,selectbox_value="EDIT" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_SCOPE" + ,selectbox_value="VIEW" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_SCOPE" + ,selectbox_value="ALL" + ,selectbox_order=3 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_HIDE" + ,selectbox_value="0" + ,selectbox_order=1 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + insert into &lib..mpe_selectbox set + selectbox_rk=%mf_increment(rk) + ,ver_from_dttm=0 + ,select_lib="&lib" + ,select_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_column="CLS_HIDE" + ,selectbox_value="1" + ,selectbox_order=2 + ,ver_to_dttm='31DEC5999:23:59:59'dt; + +/** + * MPE_TABLES + */ + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_COLUMN_LEVEL_SECURITY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,buskey='CLS_SCOPE CLS_GROUP CLS_LIBREF CLS_TABLE CLS_VARIABLE_NM' + ,notes='Docs: https://docs.datacontroller.io/column-level-security' + ,post_edit_hook='services/hooks/mpe_column_level_security_postedit' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_LOCKANYTABLE' + ,num_of_approvals_required=1 + ,loadtype='UPDATE' + ,buskey='LOCK_LIB LOCK_DS' + ,notes='This table may be edited when a process failed and left a lock' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_TABLES' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='LIBREF DSN' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,notes='This entry allows the MP Editor to edit itself!' + ,post_edit_hook='services/hooks/mpe_tables_postedit' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_SECURITY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='LIBREF DSN ACCESS_LEVEL SAS_GROUP' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,notes='Shows which metadata groups can edit which tables' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_SELECTBOX' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='SELECTBOX_RK' + ,var_txfrom='VER_FROM_DTTM' + ,var_txto='VER_TO_DTTM' + ,notes='Can configure dropdowns for the front end' + ,rk_underlying='SELECT_LIB SELECT_DS BASE_COLUMN SELECTBOX_VALUE' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_X_TEST' + ,num_of_approvals_required=1 + ,loadtype='UPDATE' + ,buskey='PRIMARY_KEY_FIELD' + ,notes='Test table for controller' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_EMAILS' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='USER_NAME' + ,notes='Primary Emails Table (backup is metadata)' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_CONFIG' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='VAR_SCOPE VAR_NAME' + ,notes='Configuration variables for Data Controller' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_ALERTS' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='ALERT_EVENT ALERT_LIB ALERT_DS ALERT_USER' + ,notes='Configuration for alert email events' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_GROUPS' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='GROUP_NAME USER_NAME' + ,notes='Configuration for additional groups within Data Controller' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_VALIDATIONS' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='BASE_LIB BASE_DS BASE_COL RULE_TYPE' + ,notes='Configuration of data quality rules in Editor component' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,post_edit_hook='services/hooks/mpe_validations_postedit' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_DATADICTIONARY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='DD_TYPE DD_SOURCE' + ,notes='Configuration of data dictionary' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_EXCEL_CONFIG' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='XL_LIBREF XL_TABLE XL_COLUMN' + ,notes='Configuration of the excel import rules' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_ROW_LEVEL_SECURITY' + ,num_of_approvals_required=1 + ,loadtype='TXTEMPORAL' + ,buskey='RLS_RK' + ,notes='Configuration of Row Level Security' + ,var_txfrom='TX_FROM' + ,var_txto='TX_TO' + ,rk_underlying='RLS_SCOPE RLS_GROUP RLS_LIBREF RLS_TABLE RLS_GROUP_LOGIC ' + !!'RLS_SUBGROUP_LOGIC RLS_SUBGROUP_ID RLS_VARIABLE_NM RLS_OPERATOR_NM ' + !!'RLS_RAW_VALUE ' + ,post_edit_hook='services/hooks/mpe_row_level_security_postedit' + ; + insert into &lib..mpe_tables + set tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,libref="&lib" + ,dsn='MPE_X_CATALOG-FC' + ,num_of_approvals_required=1 + ,loadtype='FORMAT_CAT' + ,buskey='TYPE FMTNAME FMTROW' + ,notes='Sample Format Catalog' + ; + +/* mpe_validations */ +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_SCOPE" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_LIBREF" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_TABLE" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_TABLE" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_VARIABLE_NM" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_VARIABLE_NM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_ACTIVE" + ,rule_type='MAXVAL' + ,rule_value='1' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_HIDE" + ,rule_type='MAXVAL' + ,rule_value='1' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_COLUMN_LEVEL_SECURITY" + ,base_col="CLS_GROUP" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/sas_groups" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ALERTS" + ,base_col="ALERT_LIB" + ,rule_type='HARDSELECT_HOOK' + ,rule_value="services/validations/mpe_alerts.alert_lib" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='NOTNULL' + ,rule_value=' ' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='NOTNULL' + ,rule_value=' ' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="NUM_OF_APPROVALS_REQUIRED" + ,rule_type='MINVAL' + ,rule_value='1' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="BUSKEY" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="BUSKEY" + ,rule_type='NOTNULL' + ,rule_value=" " + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXFROM" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXTO" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSFROM" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSTO" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_PROCESSED" + ,rule_type='CASE' + ,rule_value='UPCASE' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SECURITY" + ,base_col="LIBREF" + ,rule_type='HARDSELECT' + ,rule_value="&lib..MPE_TABLES.LIBREF" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SECURITY" + ,base_col="DSN" + ,rule_type='SOFTSELECT' + ,rule_value="&lib..MPE_TABLES.DSN" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SECURITY" + ,base_col="SAS_GROUP" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/sas_groups" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_LIB" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_DS" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="BASE_COL" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="RULE_ACTIVE" + ,rule_type='MINVAL' + ,rule_value="0" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_VALIDATIONS" + ,base_col="RULE_ACTIVE" + ,rule_type='MAXVAL' + ,rule_value="1" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_TABLE" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_COLUMN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="DSN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/mpe_tables.dsn" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXFROM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_TXTO" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSFROM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_BUSTO" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_TABLES" + ,base_col="VAR_PROCESSED" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="SELECT_LIB" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="SELECT_DS" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_editable" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_SELECTBOX" + ,base_col="BASE_COLUMN" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ROW_LEVEL_SECURITY" + ,base_col="RLS_GROUP" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/sas_groups" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ROW_LEVEL_SECURITY" + ,base_col="RLS_LIBREF" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/libraries_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ROW_LEVEL_SECURITY" + ,base_col="RLS_TABLE" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/tables_all" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ROW_LEVEL_SECURITY" + ,base_col="RLS_SUBGROUP_ID" + ,rule_type='MINVAL' + ,rule_value='0' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_ROW_LEVEL_SECURITY" + ,base_col="RLS_VARIABLE_NM" + ,rule_type='SOFTSELECT_HOOK' + ,rule_value="services/validations/columns_in_libds" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_X_TEST" + ,base_col="SOME_NUM" + ,rule_type='HARDSELECT_HOOK' + ,rule_value="services/validations/mpe_x_test.some_num" + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_ACTIVE" + ,rule_type='MINVAL' + ,rule_value='0' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..MPE_VALIDATIONS set + tx_from=0 + ,base_lib="&lib" + ,base_ds="MPE_EXCEL_CONFIG" + ,base_col="XL_ACTIVE" + ,rule_type='MAXVAL' + ,rule_value='1' + ,rule_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +/** + * MPE_X_TEST + */ + insert into &lib..mpe_x_test + set primary_key_field=0 + ,some_char='this is dummy data' + ,some_dropdown='Option 1' + ,some_num=42 + ,some_date=42 + ,some_datetime=42 + ,some_time=42 + ,some_shortnum=3 + ,some_bestnum=44; + insert into &lib..mpe_x_test + set primary_key_field=1 + ,some_char='more dummy data' + ,some_dropdown='Option 2' + ,some_num=42 + ,some_date=42 + ,some_datetime=42 + ,some_time=422 + ,some_shortnum=3 + ,some_bestnum=44; + insert into &lib..mpe_x_test + set primary_key_field=2 + ,some_char='even more dummy data' + ,some_dropdown='Option 3' + ,some_num=42 + ,some_date=42 + ,some_datetime=42 + ,some_time=142 + ,some_shortnum=3 + ,some_bestnum=44; + insert into &lib..mpe_x_test + set primary_key_field=3 + ,some_char=repeat('It was a dark and stormy night. The wind was blowing' + !!' a gale! The captain said to his mate - mate, tell us a tale. And' + !!' this, is the tale he told: ',3) + ,some_dropdown='Option 2' + ,some_num=1613.001 + ,some_date=423 + ,some_datetime=423 + ,some_time=44 + ,some_shortnum=3 + ,some_bestnum=44; + insert into &lib..mpe_x_test + set primary_key_field=4 + ,some_char='if you can fill the unforgiving minute' + ,some_dropdown='Option 1' + ,some_num=1613.001123456 + ,some_date=4231 + ,some_datetime=423123123 + ,some_time=412 + ,some_shortnum=3 + ,some_bestnum=44; +%do x=10 %to 500; + insert into &lib..mpe_x_test + set primary_key_field=10&x + ,some_char="&x bottles of beer on the wall" + ,some_dropdown='Option 1' + ,some_num=ranuni(0) + ,some_date=round(ranuni(0)*1000,1) + ,some_datetime=round(ranuni(0)*50000,1) + ,some_time=round(ranuni(0)*100,1) + ,some_shortnum=round(ranuni(0)*100,1) + ,some_bestnum=round(ranuni(0)*100,1); +%end; + + +/* https://support.sas.com/resources/papers/proceedings/proceedings/sugi27/p056-27.pdf */ +proc format library=&lib..mpe_x_catalog; + value otdate + .Z = 'Some Zs' + .N = 'Some 9s' + other = [date9.] + ; + invalue disc + 'ABC' = 0.20 + 'DEF' = 0.25 + 'XYZ' = 0.00 + other = 0.00 + ; + invalue indate + '00000000' = .Z + '99999999' = .N + other = [yymmdd8.] + ; + value age(multilabel) + 20 - 29 = '20 - 29' + 30 - 39 = '30 - 39' + 40 - 49 = '40 - 49' + 50 - 59 = '50 - 59' + 60 - high = '60 +++' + 20 - 35 = '20 - 35' + 36 - 55 = '36 - 55' + 55 - high = '55 +++' + ; +/* https://libguides.library.kent.edu/SAS/UserDefinedFormats */ + VALUE $GENDERLABEL + "M" = "Male" + "F" = "Female" + ; + VALUE LIKERT_SEVEN + 1 = "Strongly Disagree" + 2 = "Disagree" + 3 = "Slightly Disagree" + 4 = "Neither Agree nor Disagree" + 5 = "Slightly Agree" + 6 = "Agree" + 7 = "Strongly Agree" + ; + VALUE LIKERT7_A + 1,2,3 = "Disagree" + 4 = "Neither Agree nor Disagree" + 5,6,7 = "Agree" + ; + VALUE LIKERT7_B + 1-3 = "Disagree" + 4 = "Neither Agree nor Disagree" + 5-7 = "Agree" + ; + VALUE INCOME + LOW -< 20000 = "Low" + 20000 -< 60000 = "Middle" + 60000 - HIGH = "High" + ; + VALUE RACE + 1 = "White" + 2 = "Black" + OTHER = "Other" + ; + VALUE GENDERCODE + 0 = 'Male' + 1 = 'Female'; + VALUE ATHLETECODE + 0 = 'Non-athlete' + 1 = 'Athlete'; + VALUE SMOKINGCODE + 0 = 'Nonsmoker' + 1 = 'Past smoker' + 2 = 'Current smoker'; +/* https://documentation.sas.com/doc/en/pgmsascdc/v_017/proc/p1upn25lbfo6mkn1wncu4dyh9q91.htm */ + value $state + 'Delaware'='DE' + 'Florida'='FL' + 'Ohio'='OH'; + value MYfmt + /* Format dates prior to 31DEC2011 using only a year. */ + low-'31DEC2011'd=[year4.] + + /* Format 2012 dates using the month and year. */ + '01jan2012'd-'31DEC12'd=[monyy7.] + + /* Format dates 01JAN2013 and beyond using the day, month, and year. */ + '01JAN2013'd-high=[date9.] + + /* Catch missing values. */ + other='n/a'; + value newfmt .='N/A' other=[12.1]; +/* https://www.lexjansen.com/nesug/nesug08/cc/cc14.pdf */ + value $genderml (multilabel) + '1'='Male' + '2'='Female' + '1','2',' '='Total people'; + value agemla (multilabel) + 1-4='Preschool' + 1-18='Children' + 19-120='Adults'; + value agemlb (multilabel) + 19-120='Adults' + 1-18='Children' + 1-4='Preschool'; + value agemlc (multilabel notsorted) + 19-120='Adults' + 1-18='Children' + 1-4='Preschool'; +%mend mpe_makedata; diff --git a/sas/sasjs/macros/mpe_makedatamodel.sas b/sas/sasjs/macros/mpe_makedatamodel.sas new file mode 100644 index 0000000..08e0837 --- /dev/null +++ b/sas/sasjs/macros/mpe_makedatamodel.sas @@ -0,0 +1,598 @@ +/** + @file + @brief Creates the empty Data Controller tables + @details Creates the empty DC tables during the initial deployment. + + Usage: + + %mpe_makedatamodel(lib=DCxxxx) + +

SAS Macros

+ @li mf_existfeature.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_makedatamodel(lib=); +%if &syscc ne 0 %then %do; + %put syscc=&syscc exiting &sysmacroname; + %return; +%end; + +%local notnull; +%if %mf_existfeature(COLCONSTRAINTS)=1 %then %let notnull=not null; +%put &=notnull; + +proc sql; +create table &lib..mpe_alerts( + tx_from num format=datetime19.3, + alert_event char(20), + alert_lib char(8), + alert_ds char(32), + alert_user char(100) , + tx_to num ¬null format=datetime19.3 +);quit; +proc datasets lib=&lib noprint; + modify mpe_alerts; + index create + pk_mpealerts=(tx_from alert_event alert_lib alert_ds alert_user) + /nomiss unique; +quit; + +proc sql; +create table &lib..mpe_audit( + load_ref char(36) label='unique load reference', + libref char(8) label='Library Reference (8 chars)', + dsn char(32) label='Dataset Name (32 chars)', + key_hash char(32) label= + 'MD5 Hash of primary key values (pipe seperated)', + tgtvar_nm char(32) label='Target variable name (32 chars)', + move_type char(1) label='Either (A)ppended, (D)eleted or (M)odified', + processed_dttm num format=E8601DT26.6 label='Processed at timestamp', + is_pk num label='Is Primary Key Field? (1/0)', + is_diff num label= + 'Did value change? (1/0/-1). Always -1 for appends and deletes.', + tgtvar_type char(1) label='Either (C)haracter or (N)umeric', + oldval_num num format=best32. label='Old (numeric) value', + newval_num num format=best32. label='New (numeric) value', + oldval_char char(32765) label='Old (character) value', + newval_char char(32765) label='New (character) value' +);quit; +proc datasets lib=&lib noprint; + modify mpe_audit; + index create + pk_mpe_audit=(load_ref libref dsn key_hash tgtvar_nm) + /nomiss unique; +quit; + +proc sql; +create table &lib..mpe_column_level_security( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + CLS_SCOPE char(4) ¬null, + CLS_GROUP char(64) ¬null, + CLS_LIBREF char(8) ¬null, + CLS_TABLE char(32) ¬null, + CLS_VARIABLE_NM char(32) ¬null, + CLS_ACTIVE num ¬null, + CLS_HIDE num +);quit; +proc datasets lib=&lib noprint; + modify mpe_column_level_security; + index create + pk_mpe_column_level_security= + (tx_to CLS_SCOPE CLS_GROUP CLS_LIBREF CLS_TABLE CLS_VARIABLE_NM) + /nomiss unique; +quit; + +proc sql; +create table &lib..mpe_config( + tx_from num ¬null format=datetime19.3 + ,tx_to num ¬null format=datetime19.3 + ,var_scope varchar(10) ¬null + ,var_name varchar(32) ¬null + ,var_value varchar(5000) + ,var_active num + ,var_desc varchar(300) +);quit; +proc datasets lib=&lib noprint; + modify mpe_config; + index create + pk_mpe_config=(tx_to var_scope var_name) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datacatalog_libs( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + libref char(8) label='Library Ref', + engine char(32) label='Library Engine', + libname char(256) format=$256. label='Library Name', + paths char(8192) label='Library Paths', + perms char(500) label='Library Permissions (if BASE)', + owners char(500) label='Library Owners (if BASE)', + schemas char(500) label='Library Schemas (if DB)', + libid char(17) label='LibraryId' +);quit; +proc datasets lib=&lib noprint; + modify mpe_datacatalog_libs; + index create + pk_mpe_datacatalog_libs=(libref tx_to) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datacatalog_TABS( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + memtype char(8) label='Member Type', + dbms_memtype char(32) label='DBMS Member Type', + memlabel char(512) label='Data Set Label', + typemem char(8) label='Data Set Type', + nvar num label='Number of Variables', + compress char(8) label='Compression Routine', + pk_fields char(512) + label='Primary Key Fields (identified by being in a constraint that is both Unique and Not Null)' +);quit; +proc datasets lib=&lib noprint; + modify mpe_datacatalog_TABS; + index create + pk_mpe_datacatalog_TABS=(libref dsn tx_to) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datacatalog_vars( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + libref char(8) label='Library Name', + dsn char(64) label='Table Name', + name char(64) label='Column Name', + memtype char(8) label='Member Type', + type char(16) label='Column Type', + length num label='Column Length', + varnum num label='Column Number in Table', + label char(512) label='Column Label', + format char(49) label='Column Format', + idxusage char(9) label='Column Index Type', + notnull char(3) label='Not NULL?', + pk_ind num label='Primary Key Indicator (1=Primary Key field)' +);quit; +proc datasets lib=&lib noprint; + modify mpe_datacatalog_vars; + index create + pk_mpe_datacatalog_vars=(libref dsn name tx_to) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datastatus_libs( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + libref char(8) label='Library Name', + libsize num format=SIZEKMG. label='Size of library', + table_cnt num label='Number of Tables' +);quit; +proc datasets lib=&lib noprint; + modify mpe_datastatus_libs; + index create + pk_mpe_datastatus_libs=(libref tx_to) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datastatus_tabs( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + libref char(8) label='Library Name', + dsn char(64) label='Member Name', + filesize num format=SIZEKMG. label='Size of file', + crdate num format=DATETIME. informat=DATETIME. label='Date Created', + modate num format=DATETIME. informat=DATETIME. label='Date Modified', + nobs num label='Number of Physical (Actual, inc. deleted) Observations' +);quit; +proc datasets lib=&lib noprint; + modify mpe_datastatus_tabs; + index create + pk_mpe_datastatus_tabs=(libref dsn tx_to) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_datadictionary + ( + TX_FROM num ¬null format=datetime19.3, + TX_TO num ¬null format=datetime19.3, + DD_TYPE char(16), + DD_SOURCE char(1024), + DD_SHORTDESC char(256), + DD_LONGDESC char(32767), + DD_OWNER char(128), + DD_RESPONSIBLE char(128), + DD_SENSITIVITY char(64) +);quit; +proc datasets lib=&lib noprint; + modify mpe_datadictionary; + index create + pk_mpe_datadictionary=(tx_to dd_type dd_source) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_dataloads( + libref varchar(8) ¬null, + dsn varchar(32) ¬null, + etlsource varchar(100) ¬null, + loadtype varchar(20) ¬null, + changed_records int, + new_records int, + deleted_records int, + duration num, + user_nm varchar(50) ¬null, + processed_dttm num format=datetime19.3, + mac_ver varchar(5) +);quit; +proc datasets lib=&lib noprint; + modify mpe_dataloads; + index create + pk_mpe_dataloads=(processed_dttm libref dsn etlsource) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_emails( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + user_name char(50) ¬null, + user_displayname char(100), + user_email char(100) ¬null +);quit; +proc datasets lib=&lib noprint; + modify mpe_emails; + index create + pk_mpe_emails=(tx_to user_name) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_excel_config( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + xl_libref char(8), + xl_table char(32), + xl_column char(32), + xl_rule char(32), + xl_active num +);quit; +proc datasets lib=&lib noprint; + modify mpe_excel_config; + index create + pk_mpe_excel_config=(tx_to xl_libref xl_table xl_column) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_filteranytable( + filter_rk num ¬null, + filter_hash char(32) ¬null, + filter_table char(41) ¬null, + processed_dttm num ¬null format=datetime19. +);quit; +proc datasets lib=&lib noprint; + modify mpe_filteranytable; + index create filter_rk /nomiss unique; +quit; +proc sql; +create table &lib..mpe_filtersource( + filter_hash char(32) ¬null, + filter_line num ¬null, + group_logic char(3) ¬null, + subgroup_logic char(3) ¬null, + subgroup_id num ¬null, + variable_nm varchar(32) ¬null, + operator_nm varchar(12) ¬null, + raw_value varchar(4000) ¬null, + processed_dttm num ¬null format=datetime19. +);quit; +proc datasets lib=&lib noprint; + modify mpe_filtersource; + index create + pk_mpe_filtersource=(filter_hash filter_line) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_groups( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + group_name char(100) ¬null, + user_name char(50) ¬null, + group_desc char(256) +);quit; +proc datasets lib=&lib noprint; + modify mpe_groups; + index create + pk_mpe_groups=(tx_to group_name user_name) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_lineage_cols + ( + col_id char(32), + direction char(1), + sourcecoluri char(256), + map_type char(256), + map_transform char(256), + jobname char(256), + sourcetablename char(256), + sourcecolname char(256), + targettablename char(256), + targetcolname char(256), + targetcoluri char(256), + Derived_Rule char(500), + level int, + modified_dttm num format=datetime19.3, + modified_by char(64) +);quit; +proc datasets lib=&lib noprint; + modify mpe_lineage_cols; + index create + pk_mpe_lineage_cols=(col_id direction sourcecoluri targetcoluri map_type map_transform) + /nomiss unique; +quit; +proc sql; +create table &lib..MPE_LINEAGE_TABS + ( + tx_from num ¬null format=datetime19.3, + jobid char(17), + srctableid char(17), + tgttableid char(17), + jobname char(128), + srctabletype char(16), + srctablename char(64), + srclibref char(8), + tgttabletype char(16), + tgttablename char(64), + tgtlibref char(8), + tx_to num ¬null format=datetime19.3 +);quit; +proc datasets lib=&lib noprint; + modify mpe_lineage_tabs; + index create + pk_mpe_lineage_tabs=(tx_to jobid srctableid tgttableid) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_loads( + csv_dir char(255), + user_nm char(50) , + status char(15) , + duration num , + processed_dttm num format=datetime19.3, + reason_txt char(2048) , + approvals char(64) +);quit; +proc datasets lib=&lib noprint; + modify mpe_loads; + index create csv_dir /nomiss unique; +quit; +proc sql; +create table &lib..mpe_lockanytable( + lock_lib varchar(8) ¬null , + lock_ds varchar(32) ¬null, + lock_status_cd varchar(10) ¬null, + lock_user_nm varchar(100) ¬null , + lock_ref varchar(200), + lock_pid varchar(10), + lock_start_dttm num format=E8601DT26.6, + lock_end_dttm num format=E8601DT26.6 +);quit; +proc datasets lib=&lib noprint; + modify mpe_lockanytable; + index create + pk_mpe_lockanytable=(lock_lib lock_ds) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_maxkeyvalues( + keytable varchar(41) label='Base table in libref.dataset format', + keycolumn char(32) format=$32. + label='The Surrogate / Retained key field containing the key values.', + max_key num label= + 'Integer value representing current max RK or SK value in the KEYTABLE', + processed_dttm num format=E8601DT26.6 + label='Datetime this value was last updated' +);quit; +proc datasets lib=&lib noprint; + modify mpe_maxkeyvalues; + index create keytable /nomiss unique; +quit; +/* no PK defined as it is a transaction table */ +proc sql; +create table &lib..mpe_requests( + request_dttm num ¬null format=datetime19., + request_user char(64) ¬null, + request_service char(64) ¬null, + request_params char(128) + ); +proc sql; +create table &lib..mpe_review( + table_id varchar(32) ¬null, + reviewed_by_nm varchar(100) ¬null, + base_table varchar(41) ¬null, + review_status_id varchar(10) ¬null, + reviewed_on_dttm num ¬null format=datetime19.3, + review_reason_txt varchar(400) +);quit; +proc datasets lib=&lib noprint; + modify mpe_review; + index create + pk_mpe_review=(table_id reviewed_by_nm) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_row_level_security( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + RLS_RK num ¬null, + RLS_SCOPE char(8) ¬null, + RLS_GROUP char(128) ¬null, + RLS_LIBREF char(8) ¬null, + RLS_TABLE char(32) ¬null, + RLS_GROUP_LOGIC char(3) ¬null, + RLS_SUBGROUP_LOGIC char(3) ¬null, + RLS_SUBGROUP_ID num ¬null, + RLS_VARIABLE_NM varchar(32) ¬null, + RLS_OPERATOR_NM varchar(12) ¬null, + RLS_RAW_VALUE varchar(4000) ¬null, + RLS_ACTIVE num ¬null +);quit; +proc datasets lib=&lib noprint; + modify mpe_row_level_security; + index create + pk_mpe_row_level_security=(tx_to RLS_RK) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_security( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + libref char(8) ¬null, + dsn char(32) ¬null, + access_level char(10) ¬null, + sas_group char(100) ¬null +);quit; +proc datasets lib=&lib noprint; + modify mpe_security; + index create + pk_mpe_security=(tx_to libref dsn access_level sas_group) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_selectbox( + ver_from_dttm num ¬null format=datetime19.3,/* timestamp for versioning*/ + ver_to_dttm num ¬null format=datetime19.3, /* timestamp for versioning */ + selectbox_rk num ¬null, /* surrogate key */ + select_lib varchar(17) ¬null, /* libref (big enough for uri)*/ + select_ds varchar(32) ¬null, + base_column varchar(36) ¬null, /* variable name against which to apply selectbox */ + selectbox_value varchar(500) ¬null, /* selectbox value */ + selectbox_order num , /* optional ordering (1 comes before 2) */ + selectbox_type varchar(32) /* column type (blank for default, else + sas or js to indicate relevant system functions)*/ +);quit; +proc datasets lib=&lib noprint; + modify mpe_selectbox; + index create + pk_mpe_selectbox=(ver_to_dttm selectbox_rk) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_signoffs( + tech_from_dttm num ¬null format=datetime19.3, + tech_to_dttm num ¬null format=datetime19.3, + signoff_table varchar(50) ¬null, + signoff_section_rk num ¬null, + signoff_version_rk num ¬null, + signoff_name varchar(100) ¬null +);quit; +proc datasets lib=&lib noprint; + modify mpe_signoffs; + index create + pk_mpe_signoffs=(tech_to_dttm signoff_table signoff_section_rk) + /nomiss unique; +quit; +/* mpe_submit */ +proc sql; +create table &lib..mpe_submit( + table_id varchar(32) ¬null, + submit_status_cd varchar(10) ¬null, + base_lib char(8) ¬null, + base_ds char(32) ¬null, + submitted_by_nm varchar(100) ¬null, + submitted_on_dttm num ¬null format=datetime19.3, + submitted_reason_txt varchar(400), + input_obs num, + input_vars num, + num_of_approvals_required num ¬null , + num_of_approvals_remaining num ¬null , + reviewed_by_nm char(100), + reviewed_on_dttm num +);quit; +proc datasets lib=&lib noprint; + modify mpe_submit; + index create table_id /nomiss unique; +quit; +proc sql; +create table &lib..mpe_tables( + tx_from num ¬null format=datetime19.3, + tx_to num ¬null format=datetime19.3, + libref char(8) ¬null, + dsn char(32) ¬null, + num_of_approvals_required int, + loadtype char(12) , + buskey char(1000) , + var_txfrom char(32) , + var_txto char(32) , + var_busfrom char(32) , + var_busto char(32) , + var_processed char(32) , + close_vars varchar(500), + pre_edit_hook char(200), + post_edit_hook char(200), + pre_approve_hook char(200) , + post_approve_hook char(200) , + signoff_cols varchar(500), + signoff_hook varchar(200), + notes char(1000) , + rk_underlying char(1000) , + audit_libds char(41) +);quit; +proc datasets lib=&lib noprint; + modify mpe_tables; + index create + pk_mpe_tables=(tx_to libref dsn) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_users( + user_id char(50) ¬null, + last_seen_dt num ¬null format=date9., + registered_dt num ¬null format=date9. +);quit; +proc datasets lib=&lib noprint; + modify mpe_users; + index create user_id /nomiss unique; +quit; +proc sql; +create table &lib..MPE_VALIDATIONS + ( + TX_FROM num ¬null format=datetime19.3, + BASE_LIB varchar(8), + BASE_DS varchar(32), + BASE_COL varchar(32), + RULE_TYPE varchar(32), + RULE_VALUE varchar(128), + RULE_ACTIVE num , + TX_TO num ¬null format=datetime19.3 +);quit; +proc datasets lib=&lib noprint; + modify mpe_validations; + index create + pk_mpe_validations=(tx_from base_lib base_ds base_col rule_type) + /nomiss unique; +quit; +proc sql; +create table &lib..mpe_x_test( + primary_key_field num ¬null, + some_char char(32767) , + some_dropdown char(128), + some_num num , + some_date num format=date9., + some_datetime num format=datetime19. informat=ANYDTDTM19., + some_time num format=time8., + some_shortnum num length=4, + some_bestnum num format=best. +);quit; +proc datasets lib=&lib noprint; + modify mpe_x_test; + index create primary_key_field /nomiss unique; +quit; + +%mend mpe_makedatamodel; diff --git a/sas/sasjs/macros/mpe_makesampledata.sas b/sas/sasjs/macros/mpe_makesampledata.sas new file mode 100644 index 0000000..47f82be --- /dev/null +++ b/sas/sasjs/macros/mpe_makesampledata.sas @@ -0,0 +1,362 @@ +/** + @file mpe_makesampledata.sas + @brief Creates sample data for DC and updates MPE_TABLES + @details Creates sample data for DC. + + Usage: + + %mpe_makesampledata(outlib=DCxxxx) + +

SAS Macros

+ + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro mpe_makesampledata(outlib=); +%if &syscc ne 0 %then %do; + %put syscc=&syscc exiting &sysmacroname; + %return; +%end; +%if &syssite ne 70221618 and &syssite ne 70253615 %then %do; + %put syssite=&syssite, exiting &sysmacroname; + %return; +%end; + +data &outlib..class(index=(name /unique)); + set sashelp.class; +run; + +data &outlib..cars(index=(carspk=(make model drivetrain) /unique)); + set sashelp.cars; +run; + +data &outlib..springs(index=(springspk=(name area latitude) /unique)); + set sashelp.springs; +run; + +data &outlib..fmt_checks;; + pk=1; E8601DA=date(); + format E8601DA E8601DA10.; +run; + +data append; + if 0 then set &dc_libref..mpe_tables; + TX_FROM=0; + TX_TO='31DEC9999:23:59:59'dt; + LIBREF=%upcase("&outlib"); + LOADTYPE='UPDATE'; + NUM_OF_APPROVALS_REQUIRED=1; + DSN='SPRINGS'; BUSKEY='NAME AREA LATITUDE'; output; + DSN='CARS'; BUSKEY='MAKE MODEL DRIVETRAIN'; output; + DSN='CLASS'; BUSKEY='NAME'; output; + DSN='FMT_CHECKS'; BUSKEY='PK'; output; +run; +proc append base=&dc_libref..MPE_TABLES data=&syslast; +run; + +/** + * DC data extra + */ +%local lib; +%let lib=&dc_libref; +proc sql; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=4 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_TABLES" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=0 + ,RLS_VARIABLE_NM='NUM_OF_APPROVALS_REQUIRED' + ,RLS_OPERATOR_NM='>' + ,RLS_RAW_VALUE='0' + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=5 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=1 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=6 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=1 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=7 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=2 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=8 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=3 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=9 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=4 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=10 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=5 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=11 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=6 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=12 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-int-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=7 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=13 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=5 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=1 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=14 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=6 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=1 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=15 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=7 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=2 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=16 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=8 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=3 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=17 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=9 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=4 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=18 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=10 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=5 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=19 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=6 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; +insert into &lib..mpe_row_level_security set + tx_from=0 + ,tx_to='31DEC5999:23:59:59'dt + ,RLS_RK=20 + ,RLS_SCOPE='ALL' + ,RLS_GROUP='sec-sas9-prd-ext-sasplatform-300114sasjs' + ,RLS_LIBREF="&lib." + ,RLS_TABLE="MPE_ROW_LEVEL_SECURITY" + ,RLS_GROUP_LOGIC='AND' + ,RLS_SUBGROUP_LOGIC='OR' + ,RLS_SUBGROUP_ID=7 + ,RLS_VARIABLE_NM='RLS_GROUP_LOGIC' + ,RLS_OPERATOR_NM='NOT IN' + ,RLS_RAW_VALUE="('N/A1','N/A2','N/A3','N/A4','N/A5','N/A6','N/A7')" + ,RLS_ACTIVE=1; + + +/** create excel config */ +insert into &lib..MPE_EXCEL_CONFIG set + tx_from=0 + ,xl_libref="&lib" + ,xl_table="MPE_DATADICTIONARY" + ,xl_column="DD_LONGDESC" + ,xl_rule="FORMULA" + ,xl_active=1 + ,tx_to='31DEC5999:23:59:59'dt; + +/** mpe_security table */ +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="APPROVE" + ,sas_group="303001.DataController" + ,tx_to='31DEC5999:23:59:59'dt; +insert into &lib..mpe_security set + tx_from=0 + ,libref="*ALL*" + ,dsn="*ALL*" + ,access_level="EDIT" + ,sas_group="303001.DataController" + ,tx_to='31DEC5999:23:59:59'dt; + +data append; + if 0 then set &dc_libref..mpe_tables; + TX_FROM=0; + TX_TO='31DEC9999:23:59:59'dt; + LIBREF=%upcase("&dc_libref"); + LOADTYPE='UPDATE'; + NUM_OF_APPROVALS_REQUIRED=1; + DSN='MPE_USERS'; BUSKEY='USER_ID'; output; +run; +proc append base=&dc_libref..MPE_TABLES data=&syslast; +run; + +%mend mpe_makesampledata; diff --git a/sas/sasjs/macros/mpe_refreshlibs.sas b/sas/sasjs/macros/mpe_refreshlibs.sas new file mode 100644 index 0000000..d155aaa --- /dev/null +++ b/sas/sasjs/macros/mpe_refreshlibs.sas @@ -0,0 +1,129 @@ +/** + @file mpe_refreshlibs.sas + @brief Refreshes the library data catalog + @details + +

SAS Macros

+ @li dc_getlibs.sas + @li mf_getplatform.sas + @li bitemporal_dataloader.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%macro mpe_refreshlibs(lib=0); + +%dc_getlibs(outds=work.mm_getLibs) +proc sort data=mm_getlibs; + by libraryref libraryname; +run; + +data libs0; + set mm_getlibs; + by libraryref; +%if &lib ne 0 %then %do; + where upcase(libraryref)="%upcase(&lib)"; +%end; + if "%mf_getplatform()"="SASMETA" then do; + /* note - invalid libraries can result in exception errors. If this happens, + configure the dc_viewlib_check variable to NO in Data Controller Settings */ + rc=libname(libraryref,,'meta',cats('library="',libraryname,'";')); + drop rc; + if rc ne 0 then do; + putlog "NOTE: Library " libraryname " does not exist!!"; + putlog (_all_) (=); + delete; + end; + end; + if not first.libraryref then delete; +run; + +proc sql; +create table libs1 as + select distinct libname + ,engine + ,path + ,level + ,sysname + ,sysvalue + from dictionary.libnames + order by libname, level,engine,path; + +data libs2; + set libs1; + length tran $1024; + if missing(sysname) then sysname='Missing'; + select(sysname); + when('Access Permission') tran='Permissions'; + when('Owner Name') tran='Owner'; + when('Schema/Owner') tran='schema'; + otherwise tran=sysname; + end; +run; + +proc transpose data=libs2 out=libs3; +by libname level engine path; +var sysvalue; +id tran; +run; + +data libs4(rename=(libname=libref)); + length paths $8192 perms owners schemas $500 permissions owner schema $1024; + if _n_=1 then call missing (of _all_); + set libs3; + by libname; + if engine='V9' then engine='BASE'; + if first.libname then do; + retain paths perms owners schemas; + paths='('!!quote(trim(path)); + perms=permissions; + owners=owner; + schemas=schema; + end; + else do; + paths=trim(paths)!!' '!!quote(trim(path)); + perms=trim(perms)!!','!!trim(permissions); + owners=trim(owners)!!','!!trim(owner); + schemas=trim(schemas)!!' '!!trim(schema); + end; + if last.libname then do; + paths=trim(paths)!!')'; + schemas=cats(schemas); + output; + end; + keep libname engine paths perms owners schemas; +run; + +proc sql; +create table libs5 as + select a.libref + ,coalescec(b.engine,a.engine) as engine length=32 + ,b.libraryname as libname + ,a.paths + ,a.perms + ,a.owners + ,a.schemas + ,b.libraryid as libid + from libs4 a + left join libs0 b + on upcase(a.libref)=upcase(b.libraryref) + where libref not in ('SASWORK','WORK','SASUSER','CASUSER','TEMP','STPSAMP' + ,'MAPSGFK'); + +%bitemporal_dataloader(base_lib=&dc_libref + ,base_dsn=MPE_DATACATALOG_LIBS + ,append_dsn=libs5 + ,PK=LIBREF + ,etlsource=&_program + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO + ,dclib=&dc_libref +) + +%mend mpe_refreshlibs; diff --git a/sas/sasjs/macros/mpe_refreshtables.sas b/sas/sasjs/macros/mpe_refreshtables.sas new file mode 100644 index 0000000..f19d515 --- /dev/null +++ b/sas/sasjs/macros/mpe_refreshtables.sas @@ -0,0 +1,336 @@ +/** + @file mpe_refreshtables.sas + @brief Refreshes the data catalog + @details Assumes library is already assigned. + Usage: + + %mpe_refreshtables(sashelp) + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mf_existfeature.sas + @li mf_getengine.sas + @li mf_getschema.sas + @li mp_getconstraints.sas + + @version 9.3 + @author 4GL Apps Ltd +**/ + +%macro mpe_refreshtables(lib,ds=#all); +%let lib=%upcase(&lib); +%let ds=%upcase(&ds); +%local engine; %let engine=%mf_getengine(&lib); +%local schema; %let schema=%mf_getschema(&lib); +%put running &sysmacroname &lib(&engine &schema) for &ds; +proc sql; +create table cols as + select libname as libref + ,upcase(memname) as dsn + ,memtype + ,upcase(name) as name + ,type + ,length + ,varnum + ,label + ,format + ,idxusage + ,notnull + from dictionary.columns + where upcase(libname)="&lib" +%if &ds ne #ALL %then %do; + and upcase(memname)="&ds" +%end; + ; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc afer &lib cols extraction) +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc afer &lib indexes extraction) +) + +%if &engine=SQLSVR %then %do; + proc sql; + connect using &lib; + create table work.indexes as + select * from connection to &lib( + select + s.name as SchemaName, + t.name as memname, + tc.name as name, + ic.key_ordinal as KeyOrderNr + from + sys.schemas s + inner join sys.tables t on s.schema_id=t.schema_id + inner join sys.indexes i on t.object_id=i.object_id + inner join sys.index_columns ic on i.object_id=ic.object_id + and i.index_id=ic.index_id + inner join sys.columns tc on ic.object_id=tc.object_id + and ic.column_id=tc.column_id + where i.is_primary_key=1 + and s.name=%str(%')&schema%str(%') + order by t.name, ic.key_ordinal ; + );disconnect from &lib; + create table finalcols as + select a.* + ,case when b.name is not null then 1 else 0 end as pk_ind + from work.cols a + left join work.indexes b + on a.dsn=b.memname + and upcase(a.name)=upcase(b.name) + order by libref,dsn; +%end; +%else %do; + %local dsn; + %if &ds = #ALL %then %let dsn=; + + %mp_getconstraints(lib=&lib.,ds=&dsn,outds=work.constraints) + + + /* extract cols that are clearly primary keys */ + proc sql; + create table work.pk4sure as + select libref + ,table_name + ,constraint_name + ,constraint_order + ,column_name as name + from work.constraints + where constraint_type='PRIMARY' + order by 1,2,3,4; + + /* extract unique constraints where every col is also NOT NULL */ + proc sql; + create table work.sum as + select a.libref + ,a.table_name + ,a.constraint_name + ,count(a.column_name) as unq_cnt + ,count(b.column_name) as nul_cnt + from work.constraints(where=(constraint_type ='UNIQUE')) a + left join work.constraints(where=(constraint_type ='NOT NULL')) b + on a.libref=b.libref + and a.table_name=b.table_name + and a.column_name=b.column_name + group by 1,2,3 + having unq_cnt=nul_cnt; + + + /* extract cols from the relevant unique constraints */ + create table work.pkdefault as + select a.libref + ,a.table_name + ,a.constraint_name + ,b.constraint_order + ,b.column_name as name + from work.sum a + left join work.constraints(where=(constraint_type ='UNIQUE')) b + on a.libref=b.libref + and a.table_name=b.table_name + and a.constraint_name=b.constraint_name + order by 1,2,3,4; + + /* extract cols from the relevant unique INDEXES */ + create table work.pkfromindex as + select libname as libref + ,memname as table_name + ,indxname as constraint_name + ,indxpos as constraint_order + ,name + from dictionary.indexes + where nomiss='yes' and unique='yes' and upcase(libname)="&lib" + %if &ds ne #ALL %then %do; + and upcase(memname)="&ds" + %end; + order by 1,2,3,4; + + /* create one table */ + data work.finalpks; + set pkdefault pk4sure pkfromindex; + pk_ind=1; + /* if there are multiple unique constraints, take the first */ + by libref table_name constraint_name; + retain keepme; + if first.table_name then keepme=1; + if first.constraint_name and not first.table_name then keepme=0; + if keepme=1; + run; + + /* join back to starting table */ + proc sql; + create table finalcols as + select a.* + ,b.constraint_order + ,case when b.pk_ind=1 then 1 else 0 end as pk_ind + from work.cols a + left join work.finalpks b + on a.libref=b.libref + and a.dsn=b.table_name + and upcase(a.name)=upcase(b.name) + order by libref,dsn,constraint_order; + +%end; + +/* load columns */ +%bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=mpe_datacatalog_vars + ,append_dsn=finalcols + ,PK=LIBREF DSN NAME + ,etlsource=&sysmacroname + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO +%if &ds ne #ALL %then %do; + ,close_vars=LIBREF DSN +%end; + ,dclib=&mpelib +) + +/* prepare tables */ +proc sql; +create table work.tabs as select + libname as libref + ,upcase(memname) as dsn + ,memtype +%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do; + ,dbms_memtype +%end; +%else %do; + ,'n/a' as dbms_memtype format=$32. +%end; + ,typemem + ,memlabel + ,nvar + ,compress +from dictionary.tables + where upcase(libname)="&lib" +%if &ds ne #ALL %then %do; + and upcase(memname)="&ds" +%end; + ; +data tabs2; + set finalcols; + length pk_fields $512; + retain pk_fields; + by libref dsn; + if first.dsn then pk_fields=''; + if pk_ind=1 then pk_fields=catx(' ',pk_fields,name); + if last.dsn then output; +run; + +proc sql; +create table work.finaltabs as + select a.libref + ,a.dsn + ,a.memtype + ,a.dbms_memtype + ,a.typemem + ,a.memlabel + ,a.nvar + ,a.compress + ,b.pk_fields + from work.tabs a + left join work.tabs2 b + on a.libref=b.libref + and a.dsn=b.dsn; + +%bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=mpe_datacatalog_tabs + ,append_dsn=finaltabs + ,PK=LIBREF DSN + ,etlsource=&sysmacroname + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO + ,dclib=&mpelib +%if &ds ne #ALL %then %do; + ,close_vars=LIBREF +%end; +) + +/* prepare table frequently changing attributes */ +proc sql; +%if &engine=SQLSVR %then %do; + connect using &lib; + create table work.attrs as select * from connection to &lib( + SELECT SCHEMA_NAME(schema_id) as 'schema', name, create_date, modify_date + FROM sys.tables ; + ); + create table work.nobs as select * from connection to &lib( + SELECT SCHEMA_NAME(A.schema_id) AS 'schema' + ,A.Name, AVG(B.rows) AS 'RowCount' + FROM sys.objects A + INNER JOIN sys.partitions B ON A.object_id = B.object_id + WHERE A.type = 'U' + GROUP BY A.schema_id, A.Name + ); + disconnect from &lib; + create table statustabs as select + a.libref + ,a.dsn + ,b.create_date as crdate + ,b.modify_date as modate + ,. as filesize + ,c.RowCount as nobs + from work.tabs a + left join work.attrs(where=(schema="&schema")) b + on upcase(a.dsn)=upcase(b.name) + left join work.nobs(where=(schema="&schema")) c + on upcase(a.dsn)=upcase(c.name); +%end; +%else %do; + create table statustabs as select + libname as libref + ,upcase(memname) as dsn + ,crdate + ,modate + ,filesize + ,nobs + from dictionary.tables + where upcase(libname)="&lib" + %if &ds ne #ALL %then %do; + and upcase(memname)="&ds" + %end; + ; +%end; + +%bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=mpe_datastatus_tabs + ,append_dsn=statustabs + ,PK=LIBREF DSN + ,etlsource=&sysmacroname + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO + ,dclib=&mpelib +%if &ds ne #ALL %then %do; + ,close_vars=LIBREF +%end; +) + +%if &ds = #ALL %then %do; + proc sql; + create table statuslibs as select + libref + ,sum(filesize) as libsize + ,count(*) as table_cnt + from statustabs + group by 1; + + %bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=mpe_datastatus_libs + ,append_dsn=statuslibs + ,PK=LIBREF + ,etlsource=&sysmacroname + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO + ,dclib=&mpelib + ) +%end; + +%mend mpe_refreshtables; diff --git a/sas/sasjs/macros/mpe_runhook.sas b/sas/sasjs/macros/mpe_runhook.sas new file mode 100644 index 0000000..bb376e1 --- /dev/null +++ b/sas/sasjs/macros/mpe_runhook.sas @@ -0,0 +1,57 @@ +/** + @file + @brief Runs a hook from MPE_TABLES + @details Takes a hook script, identifies whether it is a + SAS Program or Logical Job / STP and executes the corresponding + code. + +

SAS Macros

+ @li dc_getservicecode.sas + @li mf_getapploc.sas + @li mp_abort.sas + @li mp_include.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%macro mpe_runhook(hookvar); +%local pgmloc pgmtype; +%let pgmtype=0; +%put &sysmacroname: &=hookvar; +%if %length(&&&hookvar)>0 %then %do; + %put &sysmacroname: Executing &&&hookvar; + data _null_; + rule_value=symget("&hookvar"); + if scan(upcase(rule_value),-1,'.')='SAS' then do; + call symputx('pgmtype','PGM'); + call symputx('pgmloc',rule_value); + end; + else do; + apploc="%mf_getapploc()"; + if substr(rule_value,1,1) ne '/' + then rule_value=cats(apploc,'/',rule_value); + call symputx('pgmloc',rule_value); + call symputx('pgmtype','JOB'); + end; + run; + + %if &pgmtype=PGM %then %do; + filename sascode "&pgmloc"; + %end; + %else %do; + %dc_getservicecode(loc=&pgmloc + ,outref=sascode + ) + %end; + + /* the below script will need to modify work.STAGING_DS */ + %local x; %let x=; /* legacy feature */ + %mp_include(sascode) + +%end; + +%mend mpe_runhook; diff --git a/sas/sasjs/macros/mpe_targetloader.sas b/sas/sasjs/macros/mpe_targetloader.sas new file mode 100755 index 0000000..49ee35c --- /dev/null +++ b/sas/sasjs/macros/mpe_targetloader.sas @@ -0,0 +1,221 @@ +/** + @file + @brief Generic loader for tables configured in &mpelib..mpe_tables + @details General wrapper for loading tables using ALL load types. + + Called by admin/postdata. The dclib should already be assigned. + + @param [in] dclib= (NOTPROVIDED) The data controller control library + @param [in] libds= the library.dataset to load + @param [in] now= (%sysfunc(datetime())) Static processed timestamp + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mf_existvar.sas + @li mp_abort.sas + @li mp_loadformat.sas + @li mp_lockanytable.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%macro mpe_targetloader(libds= /* library.dataset to LOAD (target) */ + ,now= %sysfunc(datetime()) /* static processed timestamp */ + ,etlsource= /* process from whence the data came */ + ,STAGING_DS= STAGING_DS /* name of staging (work) dataset which should + be appended into the target. */ + ,LOADTARGET=NO /* set to yes to actually load the target */ + ,CLOSE_VARS= /* provide close vars to override defaults */ + ,dclib=NOTPROVIDED + ,mdebug=0 + ,dc_dttmtfmt=E8601DT26.6 + ); +%local lib ds nobs; + +/** + * if a format catalog (suffix "-FC") we assume the catalog has already been + * created by the calling program with a libds of work.fmtextract +*/ +%let orig_lib=%upcase(%scan(&libds,1,.)); +%let orig_ds=%upcase(%scan(&libds,2,.)); +%let orig_libds=&libds; +%if %scan(&libds,2,-)=FC %then %do; + %let lib=WORK; + %let ds=FMTEXTRACT; + %let libds=&lib..&ds; +%end; +%else %do; + %let lib=&orig_lib; + %let ds=&orig_ds; +%end; + +%mp_abort(iftrue= (&dclib=NOTPROVIDED) + ,mac=&sysmacroname + ,msg=%str(dclib=NOTPROVIDED) +) + +/* get table attributes */ +%let nobs=0; +data work.sumo_config; + set &mpelib..mpe_tables; + where &dc_dttmtfmt. lt tx_to + and libref="&orig_lib" + and dsn="&orig_ds"; + call symputx('LOADTYPE',loadtype,'l'); + call symputx('BUSKEY',buskey,'l'); + call symputx('VAR_TXFROM',var_txfrom,'l'); + call symputx('VAR_TXTO',var_txto,'l'); + call symputx('VAR_BUSFROM',var_busfrom,'l'); + call symputx('VAR_BUSTO',var_busto,'l'); + call symputx('VAR_PROCESSED',VAR_PROCESSED,'l'); + call symputx('RK_UNDERLYING',RK_UNDERLYING,'l'); + %if %length(&CLOSE_VARS)=0 %then %do; + call symputx('CLOSE_VARS',CLOSE_VARS,'l'); + %end; + call symputx('nobs',_n_,'l'); + if missing(AUDIT_LIBDS) then AUDIT_LIBDS="&dclib..MPE_AUDIT"; + call symputx('AUDIT_LIBDS',AUDIT_LIBDS,'l'); + put (_all_)(=); +run; + +/* check if table is actually configured to load */ +%if &nobs ne 1 %then %do; + proc sql; + insert into &mpelib..mpe_loads + set USER_NM="%mf_getuser()" + ,STATUS='FAILED (BAD DS)' + ,CSV_DIR=symget('ETLSOURCE') + ,PROCESSED_DTTM=&now; +%end; +%mp_abort(iftrue= (&nobs=0) + ,mac=&sysmacroname + ,msg=%str(Table not registered in &mpelib..mpe_tables) +) +%mp_abort(iftrue= (&nobs>1) + ,mac=&sysmacroname + ,msg=%str(Something is very wrong with the PK in &mpelib..mpe_tables) +) + + +%if &LOADTYPE=TXTEMPORAL %then %do; + + %bitemporal_dataloader(bus_from=,bus_to= /* explicitly empty*/ + ,tech_from=&VAR_TXFROM + ,tech_to = &VAR_TXTO + ,base_lib=&lib + ,base_dsn=&ds + ,append_lib=WORK + ,append_dsn=&STAGING_DS + ,high_date='31DEC9999:23:59:59'dt + ,PK= &buskey + ,ETLSOURCE=&ETLSOURCE + ,LOADTYPE=&loadtype + ,RK_UNDERLYING=&RK_UNDERLYING + ,LOADTARGET=&LOADTARGET + ,RK_UPDATE_MAXKEYTABLE=&LOADTARGET + ,CLOSE_VARS=&CLOSE_VARS + ,processed=&VAR_PROCESSED + ,dclib=&dclib + ,outds_audit=&AUDIT_LIBDS + ) +%end; +%else %if &loadtype=REPLACE %then %do; + %if &LOADTARGET=YES %then %do; + %mp_lockanytable(LOCK,lib=&lib,ds=&ds,ref=%str(&etlsource), + ctl_ds=&dclib..mpe_lockanytable + ) + data WORK.&STAGING_DS; + set WORK.&STAGING_DS; + %if %mf_existvar(&libds,&VAR_PROCESSED) %then %do; + &VAR_PROCESSED = &now; + %end; + drop _____DELETE__THIS__RECORD_____; + run; + proc sql; delete * from &libds; + proc append base=&libds data=WORK.&STAGING_DS force nowarn;run; + + %mp_lockanytable(UNLOCK,lib=&lib,ds=&ds,ctl_ds=&dclib..mpe_lockanytable) + %end; +%end; +%else %if &loadtype=UPDATE %then %do; + %bitemporal_dataloader(bus_from=,bus_to= + ,tech_from= ,tech_to = /* explicitly empty*/ + ,base_lib=&lib + ,base_dsn=&ds + ,append_lib=WORK + ,append_dsn=&STAGING_DS + ,high_date='31DEC9999:23:59:59'dt + ,PK= &buskey + ,ETLSOURCE=%superq(etlsource) + ,LOADTYPE=UPDATE + ,RK_UNDERLYING=&RK_UNDERLYING + ,LOADTARGET=&LOADTARGET + ,RK_UPDATE_MAXKEYTABLE=&LOADTARGET + ,processed=&VAR_PROCESSED + ,dclib=&dclib + ,outds_audit=&AUDIT_LIBDS + ) +%end; +%else %if &loadtype=FORMAT_CAT %then %do; + /** + * run mp_formatload + * inputs: + * - LOADTARGET + * - CATALOG + * - STAGEDATA + * - LOADAUDIT + * outputs: + * work.outds_add + * work.outds_del + * work.outds_mod + */ + %mp_loadformat(&orig_libds + ,&staging_ds + ,loadtarget=&LOADTARGET + ,auditlibds=&AUDIT_LIBDS + ,locklibds=&dclib..mpe_lockanytable + ,delete_col=_____DELETE__THIS__RECORD_____ + ,outds_add=outds_add + ,outds_del=outds_del + ,outds_mod=outds_mod + ,mdebug=&mdebug + ) +%end; +%else %if &loadtype=BITEMPORAL %then %do; + %bitemporal_dataloader(bus_from=&VAR_BUSFROM,bus_to=&VAR_BUSTO + ,tech_from=&VAR_TXFROM + ,tech_to = &VAR_TXTO + ,base_lib=&lib + ,base_dsn=&ds + ,append_lib=WORK + ,append_dsn=&STAGING_DS + ,high_date='31DEC9999:23:59:59'dt + ,PK= &buskey + ,ETLSOURCE=%superq(etlsource) + ,LOADTYPE=BITEMPORAL + ,RK_UNDERLYING=&RK_UNDERLYING + ,LOADTARGET=&LOADTARGET + ,RK_UPDATE_MAXKEYTABLE=&LOADTARGET + ,CLOSE_VARS=&CLOSE_VARS + ,processed=&VAR_PROCESSED + ,dclib=&dclib + ,outds_audit=&AUDIT_LIBDS + ) +%end; +%else %do; + %put WARNING: LOADTYPE &LOADTYPE not supported; + %let syscc=4; + %mp_abort(msg=LOADTYPE &LOADTYPE not supported,mac=mpe_targetloader.sas) +%end; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc exiting MPE_TARGETLOADER macro) +) + +%mend mpe_targetloader; diff --git a/sas/sasjs/macros/mpe_validatefilter.sas b/sas/sasjs/macros/mpe_validatefilter.sas new file mode 100644 index 0000000..482d935 --- /dev/null +++ b/sas/sasjs/macros/mpe_validatefilter.sas @@ -0,0 +1,136 @@ +/** + @file + @brief Validates a filter clause and updates the source tables + @details Used to generate a FILTER_RK from an input query dataset. + Raw values are stored in dc.mpe_filtersource and the meta values are stored + in dc.mpe_filteranytable + + Input data format: + + |GROUP_LOGIC:$3|SUBGROUP_LOGIC:$3|SUBGROUP_ID:8.|VARIABLE_NM:$32|OPERATOR_NM:$10|RAW_VALUE:$32767| + |---|---|---|---|---|---| + |AND|AND|1|SOME_BESTNUM|>|1| + |AND|AND|1|SOME_TIME|=|77333| + + + @param [in] libds= The target dataset to be filtered (lib should be assigned) + @param [in] queryds= The input query dataset to be validated + @param [in] dclib= The control library for Data Controller + @param [out] outresult= The result table with the FILTER_RK + @param [out] outquery= The original query, taken as extract after table load + + + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li mf_getvalue.sas + @li mf_nobs.sas + @li mp_abort.sas + @li mp_filtercheck.sas + @li mp_hashdataset.sas + @li removecolsfromwork.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%macro mpe_validatefilter(libds=, + queryds=work.filterquery, + dclib=NOTPROVIDED, + outresult=work.result, + outquery=work.query +); + +%put &sysmacroname entry vars:; +%put _local_; + +%global _program; + +%mp_abort(iftrue= (&dclib=NOTPROVIDED) + ,mac=&sysmacroname + ,msg=%str(dclib=NOTPROVIDED) +) + +%mp_filtercheck(&queryds,targetds=&libds,abort=YES) + +%mp_hashdataset(&queryds,outds=myhash,salt=&libds) + +%local filter_hash; +%let filter_hash=%upcase(%mf_getvalue(work.myhash,hashkey)); + +%put &=filter_hash; +data _null_; + set work.myhash; + putlog (_all_)(=); +run; + +data &outresult; + set &dclib..mpe_filteranytable; + where filter_hash="&filter_hash"; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc ) +) +%mp_abort(iftrue= ("&filter_hash"=" ") + ,mac=&_program + ,msg=%str(problem with filter_hash generation) +) + +%if %mf_nobs(&outresult)=0 %then %do; + + /* update source table first */ + data work.filtersource; + set &queryds; + filter_hash="&filter_hash"; + filter_line=_n_; + run; + %bitemporal_dataloader(base_lib=&dclib + ,base_dsn=mpe_filtersource + ,append_dsn=filtersource + ,PK=filter_hash filter_line + ,etlsource=&_program + ,loadtype=UPDATE + ,processed=PROCESSED_DTTM + ,dclib=&dclib + ) + + data filter1; + if 0 then set &dclib..mpe_filteranytable; + filter_table=symget('libds'); + filter_hash="&filter_hash"; + output; + stop; + run; + + %bitemporal_dataloader(base_lib=&dclib + ,base_dsn=mpe_filteranytable + ,append_dsn=filter1 + ,PK=filter_rk + ,rk_underlying=filter_hash + ,etlsource=&_program + ,loadtype=UPDATE + ,processed=PROCESSED_DTTM + ,dclib=&dclib + ) + + data &outresult; + set &dclib..mpe_filteranytable; + where filter_hash="&filter_hash"; + run; + + %removecolsfromwork(___TMP___MD5) + +%end; + +proc sort data=&dclib..mpe_filtersource(where=(filter_hash="&filter_hash")) + out=&outquery(drop=filter_hash filter_line processed_dttm); + by filter_line; +run; + +%mend mpe_validatefilter; diff --git a/sas/sasjs/macros/mpeinit.sas b/sas/sasjs/macros/mpeinit.sas new file mode 100755 index 0000000..c82224b --- /dev/null +++ b/sas/sasjs/macros/mpeinit.sas @@ -0,0 +1,113 @@ +/** + @file mpeinit.sas + @brief Initialisation file for Data Controller- sets SASAUTOs etc + @details Runs at the beginning of every service. Used to configure settings, + options and macro variables. Requires the staging area and DC library to be + preconfigured. + +

SAS Macros

+ @li dc_getsettings.sas + @li mf_fmtdttm.sas + @li mf_getuser.sas + @li mp_abort.sas + @li mp_init.sas + + @param fetch= Fetch the SASjs tables. Use NO if not loading SASjs content, + eg for file upload. + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%macro mpeinit(fetch=YES); +%global mpeinit + mpeadmins /* group with unrestricted Meditor access */ + mpelocapprovals /* location for landing and staging files */ + mpelib /* location of configuration tables for DC */ + dc_repo_users /* location of user / group metadata */ + dc_licence_key /* extracted in dc_getsettings */ + dc_activation_key /* extracted in dc_getsettings */ + dc_locale /* extracted in dc_getsettings */ + dc_dttmtfmt /* can be overridden in dc_getsettings */ + _debug + ; + +%if &mpeinit=1 %then %return; +%else %let mpeinit=1; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Problem on service startup (&syswarningtext &syserrortext)) +) + +%mp_init() + +%if &fetch=YES %then %do; + %webout(FETCH) +%end; + +%global _CLIENTNAME; +%mp_abort(iftrue= (&_CLIENTNAME=SAS Enterprise Guide) + ,mac=&_program..sas + ,msg=%str(Data Controller is a web app and should not be executed from EG) +) + +options urlencoding=utf8 nobomfile lrecl=32767; + +%let perf=%sysfunc(datetime()); +%put perfdiff: 0; + +%let dc_locale=SYSTEM; /* default if not set */ + +/** + * E8601DT26.6 has widest database support - but not all SAS flavours can + * handle it. Override in the settings STP if needed. + */ +data _null_; + dc_dttmtfmt='"%sysfunc(datetime(),'!!"%mf_fmtdttm()"!!')"dt'; + call symputx('dc_dttmtfmt',dc_dttmtfmt); + put dc_dttmtfmt=; +run; + +%put &=dc_dttmtfmt; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc prior to dc_getsettings) +) + +%dc_getsettings() + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc after dc_getsettings) +) + +data _null_; + set &DC_LIBREF..mpe_config(where=( + var_scope="DC" + and &dc_dttmtfmt lt tx_to + and var_active=1 + )); + call symputx(var_name,var_value,'G'); + putlog var_name "=" var_value; +run; + +%let mpelib=&dc_libref; +%let mpeadmins=&dc_admin_group; +%let mpelocapprovals=&dc_staging_area; +%let dc_repo_users=&dc_repo_users; + +%if &dc_locale ne SYSTEM %then %do; + options locale=&dc_locale; +%end; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem during compilation or with STP precode (&syswarningtext)) +) + +%mend mpeinit; diff --git a/sas/sasjs/macros/mpeinit2.sas b/sas/sasjs/macros/mpeinit2.sas new file mode 100644 index 0000000..1627354 --- /dev/null +++ b/sas/sasjs/macros/mpeinit2.sas @@ -0,0 +1,40 @@ +/** + @file mpeinit2.sas + @brief Helper macro to enable interactive debugging + @details + + Just need two variables: + + %let apploc= + %let mpelib= + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +

SAS Macros

+ @li mf_fmtdttm.sas + +**/ + +%macro mpeinit2(lib); +%global mpeinit + mpeadmins /* group with unrestricted Meditor access */ + mpelocapprovals /* location for landing and staging files */ + mpelib /* location of configuration tables for DC */ + dc_repo_users /* location of user / group metadata */ + ; + %global _metauser; + %let _metauser=&sysuserid; + /* to mimic a "real" _program we need to give a dummy role and stp name */ + %let root=/dummyRole/dummyName; + + %global dc_repo_users; + %let dc_repo_users=foundation; + + %let dc_dttmtfmt="%sysfunc(datetime(),%mf_fmtdttm())"dt; + %put &=dc_dttmtfmt; + +%mend mpeinit2; diff --git a/sas/sasjs/macros/mpeterm.sas b/sas/sasjs/macros/mpeterm.sas new file mode 100644 index 0000000..76a43dc --- /dev/null +++ b/sas/sasjs/macros/mpeterm.sas @@ -0,0 +1,50 @@ +/** + @file + @brief Termination file for the 4GL Apps Editor + @details + enables tracking and performance logging + +

SAS Macros

+ @li mp_abort.sas + @li mf_getplatform.sas + + @version 9.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%macro mpeterm(); + +%local oldloc; +data _null_; + if symexist('SYSPRINTTOLOG') then oldloc=symget('SYSPRINTTOLOG'); + else oldloc=getoption('LOG'); + if subpad(oldloc,1,1) not in ('"',"'",' ') then oldloc=quote(cats(oldloc)); + call symputx('oldloc',oldloc,'l'); +run; + +%if %length(&oldloc)>0 %then %do; + proc printto log=log; + run; + data _null_; + infile &oldloc; + input; putlog _infile_; + run; +%end; +%if %sysfunc(exist(&dc_libref..mpe_requests)) and %mf_getplatform() ne SASVIYA +%then %do; + data ; + if 0 then set &dc_libref..mpe_requests; + request_dttm=%sysfunc(datetime()); + request_user="%mf_getuser()"; + request_service="%scan(&_program,-2,/)/%scan(&_program,-1,/)"; + request_params=''; + output;stop; + proc append base=&dc_libref..mpe_requests data=&syslast force nowarn; + run; +%end; + +%mend mpeterm; diff --git a/sas/sasjs/macros/removecolsfromwork.sas b/sas/sasjs/macros/removecolsfromwork.sas new file mode 100644 index 0000000..3bc9312 --- /dev/null +++ b/sas/sasjs/macros/removecolsfromwork.sas @@ -0,0 +1,37 @@ +/** + @file removecolsfromwork.sas + @brief Temp fix to remove md5 content from tables + @details +proc json cannot handle the special characters in the md5 hash + +

SAS Macros

+ @li mp_dropmembers.sas + @li mf_isblank.sas + + @version 9.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro removecolsfromwork(col); +/* only an issue if debug mode enabled */ +%global _debug; +%if &_debug ge 131 %then %do; + %let col=%upcase(&col); + + %local memlist; + proc sql noprint; + select distinct memname into: memlist + separated by ' ' + from dictionary.columns + where libname='WORK' and upcase(name)="&col"; + + %if %mf_isblank(&memlist) %then %return; + + %mp_dropmembers(list=&memlist) + +%end; +%mend removecolsfromwork; + diff --git a/sas/sasjs/sasjsconfig.json b/sas/sasjs/sasjsconfig.json new file mode 100644 index 0000000..35a6487 --- /dev/null +++ b/sas/sasjs/sasjsconfig.json @@ -0,0 +1,494 @@ +{ + "$schema": "https://raw.githubusercontent.com/sasjs/utils/main/src/types/sasjsconfig-schema.json", + "macroFolders": [ + "sasjs/macros" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/services/admin", + "sasjs/services/approvers", + "sasjs/services/auditors", + "sasjs/services/editors", + "sasjs/services/hooks", + "sasjs/services/public", + "sasjs/services/validations" + ] + }, + "binaryFolders": [ + "sasjs/binaryfiles" + ], + "docConfig": { + "displayMacroCore": true, + "doxyContent": { + "favIcon": "favicon.ico", + "footer": "new_footer.html", + "header": "new_header.html", + "layout": "DoxygenLayout.xml", + "logo": "data_controller.png", + "readMe": "README.md", + "stylesheet": "new_stylesheet.css", + "path": "sasjs/doxy" + }, + "outDirectory": "sasjsbuild/sasdocs" + }, + "testConfig": { + "initProgram": "sasjs/tests/testinit.sas", + "termProgram": "sasjs/tests/testterm.sas", + "testSetUp": "sasjs/tests/testsetup.sas", + "macroVars": {}, + "testTearDown": "" + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "web", + "webSourcePath": "../client/dist", + "streamServiceName": "clickme", + "streamLogo": "favicon.ico", + "assetPaths": [] + }, + "defaultTarget": "v4", + "targets": [ + { + "name": "sas9", + "serverUrl": "https://sas.4gl.io:8343", + "serverType": "SAS9", + "appLoc": "/30.SASApps/3030.Projects/303001.DataController/build2/DataController", + "macroFolders": [ + "sasjs/targets/sas9/macros_meta" + ], + "buildConfig": { + "buildOutputFileName": "mysas9deploy.sas", + "initProgram": "sasjs/utils/buildinitsas9.sas", + "buildResultsFolder": "sasjsresults", + "buildOutputFolder": "sasjsbuild" + }, + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/sas9/services_meta/admin", + "sasjs/targets/sas9/services_meta/lineage", + "sasjs/targets/sas9/services_meta/metanav", + "sasjs/targets/sas9/services_meta/usernav" + ], + "initProgram": "sasjs/utils/serviceinitsas9.sas", + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "web9", + "webSourcePath": "../client/dist", + "assetPaths": [], + "streamServiceName": "clickme" + }, + "deployConfig": { + "deployServicePack": true, + "deployScripts2": [ + "sasjs/utils/delete_metafolder.sh" + ] + }, + "serverName": "SASApp", + "repositoryName": "Foundation" + }, + { + "name": "viya", + "serverUrl": "https://sas.4gl.io", + "serverType": "SASVIYA", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/Public/app/dc", + "macroFolders": [ + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "binaryFolders": [], + "buildConfig": { + "initProgram": "sasjs/utils/buildinitviya.sas", + "termProgram": "sasjs/utils/buildtermviya.sas", + "buildResultsFolder": "sasjsresults", + "buildOutputFolder": "sasjsbuild", + "buildOutputFileName": "viya.sas" + }, + "serviceConfig": { + "initProgram": "sasjs/utils/serviceinitviya.sas", + "serviceFolders": [ + "sasjs/targets/viya/services_viya/viya_users", + "sasjs/targets/viya/services_viya/admin", + "sasjs/targets/viya/services_viya/public" + ] + }, + "deployConfig": { + "deployServicePack": true, + "deployScripts": [ + "sasjs/utils/viyadeploy.sh" + ] + }, + "contextName": "Datacontroller compute context" + }, + { + "name": "viyacloud", + "serverUrl": "https://4gl.viyacloud.sas.com", + "serverType": "SASVIYA", + "httpsAgentOptions": { + "rejectUnauthorized": false, + "allowInsecureRequests": true + }, + "appLoc": "/30.SASApps/app/dc", + "macroFolders": [ + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "buildConfig": { + "initProgram": "sasjs/utils/buildinitviya.sas", + "termProgram": "sasjs/utils/buildtermviya.sas", + "macroVars": { + "dcpath": "/opt/sas/viya/config/var/tmp/dc", + "adminGroup": "DataBuilders" + }, + "buildResultsFolder": "sasjsresults", + "buildOutputFolder": "sasjsbuild", + "buildOutputFileName": "viya.sas" + }, + "serviceConfig": { + "initProgram": "sasjs/utils/serviceinitviya.sas", + "serviceFolders": [ + "sasjs/targets/viya/services_viya/viya_users", + "sasjs/targets/viya/services_viya/admin", + "sasjs/targets/viya/services_viya/public" + ], + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "webv", + "webSourcePath": "../client/dist", + "streamServiceName": "clickme", + "assetPaths": [] + }, + "deployConfig": { + "deployServicePack": true + }, + "contextName": "Datacontroller compute context" + }, + { + "name": "vtest", + "appLoc": "/30.SASApps/app/vtest", + "serverType": "SASVIYA", + "serverUrl": "https://sas.4gl.io", + "contextName": "Datacontroller compute context", + "testConfig": { + "testSetUp": "sasjs/tests/testsetup.sas" + }, + "serviceConfig": { + "initProgram": "sasjs/utils/serviceinitviya.sas", + "serviceFolders": [ + "sasjs/targets/viya/services_viya/usernav", + "sasjs/targets/viya/services_viya/admin", + "sasjs/targets/viya/services_viya/public" + ] + }, + "macroFolders": [ + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "deployConfig": { + "deployServicePack": true + } + }, + { + "name": "4gl", + "serverUrl": "https://sas9.4gl.io", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/Public/app/dc", + "deployConfig": { + "deployServicePack": true, + "deployScripts": [] + }, + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas", + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "web", + "webSourcePath": "../client/dist", + "streamServiceName": "DataController", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + }, + { + "name": "server", + "serverUrl": "https://sas.4gl.io:5006", + "serverType": "SASJS", + "httpsAgentOptions": { + "rejectUnauthorized": false, + "allowInsecureRequests": true + }, + "appLoc": "/Public/app/dc", + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas", + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "web", + "streamServiceName": "DataController", + "webSourcePath": "../client/dist", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + }, + { + "name": "server-mihajlo", + "serverUrl": "https://sas9.4gl.io", + "serverType": "SASJS", + "httpsAgentOptions": { + "rejectUnauthorized": false, + "allowInsecureRequests": true + }, + "appLoc": "/Public/app/mihajlo", + "deployConfig": { + "deployServicePack": true, + "deployScripts": [] + }, + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas", + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": false, + "streamWebFolder": "webv", + "webSourcePath": "../client/dist", + "streamServiceName": "DataControllerMihajlo", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + }, + { + "name": "server-vlad", + "serverUrl": "https://sas.4gl.io:5000", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/30.SASApps/app/dc", + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas", + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "webv", + "streamServiceName": "DataController", + "webSourcePath": "../client/dist", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + }, + { + "name": "mihajlo", + "serverUrl": "https://sas.4gl.io", + "serverType": "SASVIYA", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/30.SASApps/app/mihajlo", + "macroFolders": [ + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "buildConfig": { + "initProgram": "sasjs/utils/buildinitviya.sas", + "termProgram": "sasjs/utils/buildtermviya.sas", + "buildOutputFileName": "viyaCi.sas", + "macroVars": {}, + "buildResultsFolder": "sasjsresults", + "buildOutputFolder": "sasjsbuild" + }, + "serviceConfig": { + "initProgram": "sasjs/utils/serviceinitviya.sas", + "serviceFolders": [ + "sasjs/targets/viya/services_viya/admin" + ], + "termProgram": "", + "macroVars": {} + }, + "streamConfig": { + "streamWeb": false, + "streamWebFolder": "webv", + "streamServiceName": "DataController", + "webSourcePath": "../client/dist", + "streamLogo": "favicon.ico", + "assetPaths": [] + }, + "contextName": "Datacontroller compute context" + }, + { + "name": "server-ci", + "serverUrl": "https://sas.4gl.io:5002", + "serverType": "SASJS", + "httpsAgentOptions": { + "allowInsecureRequests": false + }, + "appLoc": "/30.SASApps/app/devtest", + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas", + "termProgram": "", + "macroVars": {} + } + }, + { + "name": "productionCi", + "appLoc": "/30.SASApps/app/productionCi", + "serverUrl": "https://sas.4gl.io:5002", + "serverType": "SASJS", + "macroFolders": [ + "sasjs/targets/server/macros_server" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav" + ], + "initProgram": "sasjs/utils/serviceinitserver.sas" + }, + "streamConfig": { + "streamWeb": true, + "streamWebFolder": "web", + "streamServiceName": "DataController", + "webSourcePath": "../client/dist", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + }, + { + "name": "docs", + "appLoc": "/Public/dc/docs", + "serverType": "SASJS", + "macroFolders": [ + "sasjs/macros", + "sasjs/targets/server/macros_server", + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl", + "sasjs/tests" + ], + "serviceConfig": { + "serviceFolders": [ + "sasjs/targets/sas9/services_meta/admin", + "sasjs/targets/sas9/services_meta/lineage", + "sasjs/targets/sas9/services_meta/metanav", + "sasjs/targets/sas9/services_meta/usernav", + "sasjs/targets/server/services_server/admin", + "sasjs/targets/server/services_server/usernav", + "sasjs/targets/viya/services_viya/admin" + ] + } + }, + { + "name": "v4", + "serverUrl": "https://extviya4.emea.sas.com", + "serverType": "SASVIYA", + "appLoc": "/Viyademo08 Group Folder/4GL/dc", + "macroFolders": [ + "sasjs/targets/viya/macros_viya" + ], + "programFolders": [ + "sasjs/db/datactrl" + ], + "buildConfig": { + "initProgram": "sasjs/utils/buildinitviya.sas", + "termProgram": "sasjs/utils/buildtermviya.sas", + "buildOutputFileName": "viyaCi.sas", + "macroVars": {}, + "buildResultsFolder": "sasjsresults", + "buildOutputFolder": "sasjsbuild" + }, + "serviceConfig": { + "initProgram": "sasjs/utils/serviceinitviya.sas", + "serviceFolders": [ + "sasjs/targets/viya/services_viya/admin" + ] + }, + "streamConfig": { + "streamWeb": false, + "streamWebFolder": "webv", + "streamServiceName": "DataController", + "webSourcePath": "../client/dist", + "streamLogo": "favicon.ico", + "assetPaths": [] + } + } + ] +} \ No newline at end of file diff --git a/sas/sasjs/services/admin/exportconfig.sas b/sas/sasjs/services/admin/exportconfig.sas new file mode 100644 index 0000000..ca66329 --- /dev/null +++ b/sas/sasjs/services/admin/exportconfig.sas @@ -0,0 +1,159 @@ +/** + @file + @brief Downloads zip file of DC customer configurations + @details Zip contains several excel files, containing the customer specific + (non-DC) configurations. Useful when migrating to a new instance of + Data Controller. + + +

SAS Macros

+ @li mf_getuser.sas + @li mf_nobs.sas + @li mp_ds2cards.sas + @li mp_abort.sas + @li mp_binarycopy.sas + @li mp_streamfile.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() +%let work=%sysfunc(pathname(work)); + +/* excel does not work in all envs */ +%let mime=application/vnd.ms-excel; +%let dbms=EXCEL; + +%let mime=application/csv; +%let dbms=CSV; +%let ext=csv; + +%macro conditional_export(ds); +%if %mf_nobs(&ds)>0 %then %do; + PROC EXPORT DATA= &ds OUTFILE= "&work/&ds..&ext" + DBMS=&dbms REPLACE; + RUN; + ods package(ProdOutput) add file="&work/&ds..&ext" mimetype="&mime"; +%end; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%nrstr(syscc=&syscc after &ds prep) +) +%mend conditional_export; + + +ods package(ProdOutput) open nopf; + +data MPE_ALERTS; + set &mpelib..MPE_ALERTS; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_ALERTS) + + +data MPE_COLUMN_LEVEL_SECURITY; + set &mpelib..MPE_COLUMN_LEVEL_SECURITY; + where &dc_dttmtfmt. le tx_to; + where also CLS_LIBREF ne "&mpelib"; + drop tx_: ; +run; +%conditional_export(MPE_COLUMN_LEVEL_SECURITY) + +data MPE_CONFIG; + set &mpelib..MPE_CONFIG; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_CONFIG) + +data MPE_DATADICTIONARY; + set &mpelib..MPE_DATADICTIONARY; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; + if DD_SOURCE=:"&mpelib" then do; + /* nothing */ + end; + else output; +run; +%conditional_export(MPE_DATADICTIONARY) + +data MPE_EMAILS; + set &mpelib..MPE_EMAILS; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_EMAILS) + +data MPE_EXCEL_CONFIG; + set &mpelib..MPE_EXCEL_CONFIG; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_EXCEL_CONFIG) + +data MPE_GROUPS; + set &mpelib..MPE_GROUPS; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_GROUPS) + +data MPE_ROW_LEVEL_SECURITY; + set &mpelib..MPE_ROW_LEVEL_SECURITY; + where &dc_dttmtfmt. le tx_to; + drop tx_: ; +run; +%conditional_export(MPE_ROW_LEVEL_SECURITY) + + +data MPE_SECURITY; + set &mpelib..MPE_SECURITY; + where &dc_dttmtfmt. le TX_TO; + drop tx_: ; +run; +%conditional_export(MPE_SECURITY) + +data MPE_SELECTBOX; + set &mpelib..MPE_SELECTBOX; + where &dc_dttmtfmt. le ver_to_dttm; + where also select_lib ne "&mpelib"; + drop ver_: selectbox_rk; +run; +%conditional_export(MPE_SELECTBOX) + +data MPE_TABLES; + set &mpelib..MPE_TABLES; + where &dc_dttmtfmt. le TX_TO; + where also LIBREF ne "&mpelib"; + drop tx_: ; +run; +%conditional_export(MPE_TABLES) + +data MPE_VALIDATIONS; + set &mpelib..MPE_VALIDATIONS; + where &dc_dttmtfmt. le TX_TO; + where also BASE_LIB ne "&mpelib"; + drop tx_: ; +run; +%conditional_export(MPE_VALIDATIONS) + +/* finish up zip file */ +ods package(ProdOutput) publish archive properties + (archive_name="DCBACKUP.zip" archive_path="&work"); +ods package(ProdOutput) close; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%nrstr(syscc=&syscc after zip prep) +) + +/* now serve zip file to client */ +%mp_streamfile(contenttype=ZIP + ,inloc=%str(&work/DCBACKUP.zip) + ,outname=DCBACKUP.zip +) diff --git a/sas/sasjs/services/admin/exportdb.sas b/sas/sasjs/services/admin/exportdb.sas new file mode 100644 index 0000000..533772e --- /dev/null +++ b/sas/sasjs/services/admin/exportdb.sas @@ -0,0 +1,66 @@ +/** + @file + @brief Exports the data controller library in DB specific DDL + @details If user is in the administrator group, they can call this + service directly adding the following URL params: + + @li &flavour= (only PGSQL supported at this time) + @li &schema= (optional, if target schema is needed) + +

SAS Macros

+ @li mf_getuser.sas + @li mp_abort.sas + @li mp_getddl.sas + @li mp_lib2inserts.sas + @li mp_streamfile.sas + @li mpe_getgroups.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%global flavour schema; +/* if no flavour is specified, default to SAS */ +%let flavour=%sysfunc(coalescec(&flavour,SAS)); + +/* if no schema var provided, DC Libref is used */ +%let schema=%sysfunc(coalescec(&schema,&dc_libref)); + +/* check user is in admin group */ +%mpe_getgroups(user=%mf_getuser(),outds=work.usergroups) + +data work.admins; + set work.usergroups; + put (_all_)(=); +run; + +%let cnt=0; +proc sql noprint; +select count(*) into:cnt + from usergroups + where groupname="&mpeadmins"; +%put &=cnt; +%mp_abort(iftrue= (&cnt=0) + ,mac=&_program + ,msg=%str(The &DC_LIBREF library can only be exported by &mpeadmins members) +) + +%mp_getddl(&DC_LIBREF + ,flavour=&flavour + ,schema=&schema + ,applydttm=YES + ,fref=tmpref +) + +%mp_lib2inserts(&DC_LIBREF,flavour=&flavour,schema=&schema, outref=tmpref) + +%mp_streamfile(contenttype=TEXT + ,inref=tmpref + ,outname=&dc_libref..ddl +) diff --git a/sas/sasjs/services/admin/refreshcatalog.sas b/sas/sasjs/services/admin/refreshcatalog.sas new file mode 100644 index 0000000..05c6cdb --- /dev/null +++ b/sas/sasjs/services/admin/refreshcatalog.sas @@ -0,0 +1,26 @@ +/** + @file refreshcatalog.sas + @brief Refreshes the library data catalog + @details A library may be passed in a LIBREF url param. + +

SAS Macros

+ @li mpeinit.sas + @li dc_refreshcatalog.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%global libref; +%mpeinit() + +%dc_refreshcatalog(&libref) + + +data _null_; + file _webout; + put '

Catalog Refresh Complete

'; +run; diff --git a/sas/sasjs/services/admin/refreshlibs.sas b/sas/sasjs/services/admin/refreshlibs.sas new file mode 100644 index 0000000..2821c25 --- /dev/null +++ b/sas/sasjs/services/admin/refreshlibs.sas @@ -0,0 +1,20 @@ +/** + @file refreshlibs.sas + @brief Refreshes the library data catalog + @details + +

SAS Macros

+ @li mpeinit.sas + @li mpe_refreshlibs.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%mpe_refreshlibs() diff --git a/sas/sasjs/services/admin/registerkey.sas b/sas/sasjs/services/admin/registerkey.sas new file mode 100644 index 0000000..b45448e --- /dev/null +++ b/sas/sasjs/services/admin/registerkey.sas @@ -0,0 +1,91 @@ +/** + @file + @brief Register a new licence key + @details + +

SAS Macros

+ @li mpeinit.sas + @li bitemporal_dataloader.sas + @li mp_abort.sas + @li mf_getuser.sas + @li mpe_getgroups.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + + @test + + echo '{"keyupload":[{"activation_key":"slfdjasfda;dslf","licence_key":"asdfasdlfkajsfdas"}]}'>in.json + sasjs request admin/registerkey -d in.json + +**/ + +%mpeinit() + +/* determine users group membership */ +%mpe_getgroups(user=%mf_getuser(),outds=work.groups) +%global admin_check; +proc sql; +select count(*) into: admin_check + from groups where groupname="&mpeadmins"; + +%mp_abort(iftrue= (&admin_check = 0) + ,mac=%str(&_program) + ,msg=%str(Only members of &mpeadmins may register a key) +) + +%global licencekey activation_key; +data _null_; + set work.keyupload; + call symputx('activation_key',activation_key); + call symputx('licencekey',licence_key); + call symputx('activlen',length(activation_key)); + call symputx('liclen',length(licence_key)); +run; + +%mp_abort(iftrue= (&activlen< 10) + ,mac=%str(&_program) + ,msg=%str(Invalid activation_key) +) +%mp_abort(iftrue= (&liclen < 10) + ,mac=%str(&_program) + ,msg=%str(Invalid licencekey) +) + +data work.loadme; + if 0 then set &mpelib..mpe_config; + VAR_SCOPE='DC'; + VAR_NAME='DC_ACTIVATION_KEY'; + VAR_VALUE=symget('activation_key'); + VAR_ACTIVE=1; + output; + VAR_NAME='DC_LICENCE_KEY'; + VAR_VALUE=symget('licencekey'); + VAR_ACTIVE=1; + output; + keep VAR_: ; +run; + +%bitemporal_dataloader( + tech_from=tx_from + ,tech_to = tx_to + ,base_lib=&mpelib + ,base_dsn=mpe_config + ,append_lib=WORK + ,append_dsn=loadme + ,PK= VAR_SCOPE VAR_NAME + ,ETLSOURCE=%str(&_program STP) + ,LOADTYPE=TXTEMPORAL + ,dclib=&mpelib +) + +data work.return; + msg='SUCCESS'; +run; + +%webout(OPEN) +%webout(OBJ,return) +%webout(CLOSE) diff --git a/sas/sasjs/services/approvers/getapprovals.sas b/sas/sasjs/services/approvers/getapprovals.sas new file mode 100644 index 0000000..25b53c3 --- /dev/null +++ b/sas/sasjs/services/approvers/getapprovals.sas @@ -0,0 +1,89 @@ +/** + @file getapprovals.sas + @brief Returns a list of staged data items that need to be approved + @details + +

SAS Macros

+ @li mpe_getgroups.sas + @li mp_abort.sas + @li mf_getuser.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +/* determine users group membership */ +%let user=%mf_getuser(); +%mpe_getgroups(user=&user,outds=work.groups) + +PROC FORMAT; + picture yymmddhhmmss other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime); +RUN; + +proc sql noprint; +create table out1 (rename=(SUBMITTED_ON_DTTM1=SUBMITTED_ON_DTTM)) as + select table_id + ,submit_status_cd as REVIEW_STATUS_ID + ,SUBMITTED_BY_NM + ,cats(base_lib,'.',base_ds) as base_table + ,put(submitted_on_dttm,yymmddhhmmss.) as SUBMITTED_ON_DTTM1 + ,submitted_on_dttm as SUBMITTED_ON_DTTM2 + ,submitted_reason_txt + ,num_of_approvals_required + ,num_of_approvals_remaining + ,base_lib as libref + ,base_ds as dsn + from &mpelib..mpe_submit (where=(submit_status_cd='SUBMITTED')) + /* filter out any submits for which approval is already made */ + where table_id not in ( + select table_id from &mpelib..mpe_review where submitted_by_nm="&user" + ); + +%macro getapprovals(); + %local admin_check; + select count(*) into: admin_check + from groups + where groupname="&mpeadmins" + or groupname in ( + select sas_group from &mpelib..mpe_security + where libref='*ALL*' + and &dc_dttmtfmt. lt tx_to + and access_level in ('APPROVE') + ); + %if &admin_check >0 %then %do; + create table fromSAS as + select distinct * from out1 + order by SUBMITTED_ON_DTTM2 desc; + %end; + %else %do; + create table fromSAS as + select distinct a.* + from out1 a + inner join &mpelib..mpe_security b + on a.libref=b.libref + and (a.dsn=b.dsn or b.dsn='*ALL*') + and &dc_dttmtfmt. lt b.tx_to + and b.ACCESS_LEVEL ='APPROVE' + and b.SAS_GROUP in (select groupname from work.groups) + order by SUBMITTED_ON_DTTM2 desc; + %end; +%mend getapprovals; +%getapprovals() + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/approvers/getapprovals.test.sas b/sas/sasjs/services/approvers/getapprovals.test.sas new file mode 100644 index 0000000..a2f6ec9 --- /dev/null +++ b/sas/sasjs/services/approvers/getapprovals.test.sas @@ -0,0 +1,26 @@ +/** + @file + @brief testing gethistory service + +

SAS Macros

+ @li mp_assertdsobs.sas + +**/ + +%let _program=&appLoc/services/approvers/getapprovals; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + outlib=webout +) + + +data fromsas; + set webout.fromsas; +run; + +%mp_assertdsobs(work.fromsas, + desc=Fromsas table returned, + test=HASOBS, + outds=work.test_results +) \ No newline at end of file diff --git a/sas/sasjs/services/approvers/gethistory.sas b/sas/sasjs/services/approvers/gethistory.sas new file mode 100644 index 0000000..e694ef1 --- /dev/null +++ b/sas/sasjs/services/approvers/gethistory.sas @@ -0,0 +1,156 @@ +/** + @file + @brief Returns the list of previously approved / rejected items. + @details History is taken from MPE_SUBMIT (where status_cd ne 'SUBMITTED') and + filtered according to the groups in MPE_SECURITY (unless the user is in the + DC admin group). + +

SAS Macros

+ @li mpe_getvars.sas + @li mpe_getgroups.sas + @li mp_abort.sas + @li mf_getuser.sas + +

Service Inputs

+
BROWSERPARAMS
+ The following variables MAY be provided from frontend (HIST can also be set + in MPE_CONFIG): + + @li HIST - number of records to return + @li STARTROW - the starting row (default is 1) + +

Service Outputs

+ +
FROMSAS
+ This table is returned, starting from &STARTROW for &HIST rows (ordered + descending on SUBMITTED datetime) + @li TABLE_ID + @li BASE_TABLE + @li SUBMITTED + @li SUBMITTED_REASON_TXT + @li SUBMITTER + @li REVIEWED + @li STATUS + @li REVIEWED_ON_DTTM + @li APPROVER + +
HISTPARAMS
+ + @li HIST - rows returned + @li STARTROW - starting row used + @li NOBS - Number of observations (rows) available + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +/* hard coded HIST value */ +%let hist=40; +%let startrow=1; + +/* load parameters from frontend (HIST and STARTROW) */ +data _null_; + set &DC_LIBREF..mpe_config(where=( + var_scope="DC_REVIEW" + and var_name='HISTORY_ROWS' + and &dc_dttmtfmt. lt tx_to + and var_active=1 + )); + call symputx('hist',var_value,'G'); + putlog 'mpe_config: ' var_name "=" var_value; +run; + +/* load parameters (override HIST again if provided) */ +%mpe_getvars(BrowserParams, BrowserParams) + + +/* determine users group membership */ +%mpe_getgroups(user=%mf_getuser(),outds=work.usergroups) + +PROC FORMAT; + picture yymmddhhmmss other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime); +RUN; + +/* check to see if the user is an admin, or has *ALL* access rights */ +%let authcheck=0; +proc sql noprint; +create table work.authcheck + as select * + from usergroups + where upcase(groupname)="%upcase(&mpeadmins)" + or upcase(groupname) in ( + select upcase(sas_group) from &mpelib..mpe_security + where libref='*ALL*' and &dc_dttmtfmt. lt tx_to + ); +select count(*) into: authcheck from &syslast; + +%mp_abort(iftrue= (&syscc > 0) + ,mac=&_program + ,msg=%str(syscc=&syscc after auth check) +) + +/* now get the previous &hist records from mpe_submit */ +proc sql; +create view work.submits as + select distinct a.TABLE_ID + ,cats(a.base_lib,'.',a.base_ds) as base_table + ,put(a.SUBMITTED_ON_DTTM,yymmddhhmmss.) as submitted + ,a.submitted_reason_txt + ,a.submitted_by_nm as submitter + ,put(a.REVIEWED_ON_DTTM,yymmddhhmmss.) as REVIEWED + ,a.submit_status_cd as status + ,a.reviewed_on_dttm + ,a.reviewed_by_nm as approver + from &mpelib..mpe_submit(where=(submit_status_cd ne 'SUBMITTED')) a + +%macro gethistory(); +%if &authcheck=0 %then %do; + /* filter for allowed items */ + left join &mpelib..mpe_security(where=(&dc_dttmtfmt. lt tx_to)) b + on a.base_lib=b.libref + and (a.base_ds=b.dsn or b.dsn='*ALL*') + where upcase(b.SAS_GROUP) in (select upcase(groupname) from work.usergroups) + and b.access_level in ('VIEW','AUDIT','EDIT','APPROVE') +%end; +%mend gethistory; +%gethistory() + + order by a.submitted_on_dttm desc; + +%mp_abort(iftrue= (&syscc > 0) + ,mac=&_program + ,msg=%str(syscc=&syscc after fetching submits) +) + +data work.fromsas; + set work.submits; + if _n_ ge &startrow; + n+1; + if n>&hist then stop; + drop n; +run; + +proc sql noprint; +select count(*) into: nobs from work.submits; +data work.histparams; + hist=&hist; + startrow=&startrow; + nobs=&nobs; +run; + +%mp_abort(iftrue= (&syscc > 0) + ,mac=&_program + ,msg=%str(syscc=&syscc) +) +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(OBJ,histparams) +%webout(CLOSE) + +%mpeterm() \ No newline at end of file diff --git a/sas/sasjs/services/approvers/gethistory.test.sas b/sas/sasjs/services/approvers/gethistory.test.sas new file mode 100644 index 0000000..b83cd17 --- /dev/null +++ b/sas/sasjs/services/approvers/gethistory.test.sas @@ -0,0 +1,36 @@ +/** + @file + @brief testing gethistory service + +

SAS Macros

+ @li mp_assertdsobs.sas + +**/ + +%let _program=&appLoc/services/approvers/gethistory; + +filename fref1 temp; + +data _null_; + file fref1 termstr=crlf; + put 'HIST:best.'; + put '50'; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=fref1:BrowserParams , + outlib=webout, + debug=log +) + + +data fromsas; + set webout.fromsas; +run; + +%mp_assertdsobs(work.fromsas, + desc=Fromsas table returned, + test=HASOBS, + outds=work.test_results +) \ No newline at end of file diff --git a/sas/sasjs/services/approvers/rejection.sas b/sas/sasjs/services/approvers/rejection.sas new file mode 100644 index 0000000..23741e9 --- /dev/null +++ b/sas/sasjs/services/approvers/rejection.sas @@ -0,0 +1,141 @@ +/** + @file + @brief Removes a staged data package from approval screen + @details + +

SAS Macros

+ @li mf_getuser.sas + @li mf_getvarlist.sas + @li mf_verifymacvars.sas + @li mp_abort.sas + @li mp_lockanytable.sas + @li mpe_accesscheck.sas + @li mpe_alerts.sas + @li mpe_getvars.sas + @li removecolsfromwork.sas + +

Service Outputs

+
fromsas
+ + @li TABLE_ID + @li SUBMITTED_REASON_TXT + @li RESPONSE + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%global STP_ACTION TABLE STP_REASON; +%mpeinit() + +%mpe_getvars(BrowserParams, BrowserParams) + +PROC FORMAT; + picture yymmddhhmmss other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime); +RUN; + +/* get current status and base table */ +data _null_; + set &mpelib..mpe_submit(where=(TABLE_ID="&TABLE")); + call symputx('BASE_TABLE',cats(base_lib,'.',base_ds)); + call symputx('submit_status_cd',submit_status_cd); +run; + +%mp_abort( + iftrue=(%mf_verifymacvars(base_table)=0) + ,mac=&_program + ,msg=%str(Missing: base_table) +) + +%mp_abort( + iftrue=(%quote(&submit_status_cd)=%quote(REJECTED)) + ,mac=&_program + ,msg=%str(&table is already rejected!) +) + +%mp_abort(iftrue= (&syscc ge 4) + ,mac=&_program + ,msg=%str(Issue on setup) +) + +/** + * determine if user is authorised to reject table + */ +%let user=%mf_getuser(); +%global authcheck; %let authcheck=0; +%mpe_accesscheck(&base_table,outds=authAPP,user=&user,access_level=APPROVE) +%let authcheck=%mf_getattrn(work.authAPP,NLOBS); + +%mp_abort(iftrue= (&authcheck=0) + ,mac=&_program..sas + ,msg=%str(User &user does not have APPROVE rights on &base_table and is not + in the &mpeadmins group) +) + +/* update the control table to show table as rejected (and why) */ +%let now=%sysfunc(datetime()); +data work.reject; + if 0 then set &mpelib..mpe_review; + TABLE_ID="&table"; + BASE_TABLE="&base_table"; + REVIEW_STATUS_ID="REJECTED"; + REVIEWED_BY_NM="&user"; + REVIEWED_ON_DTTM=&now; + REVIEW_REASON_TXT=symget('STP_REASON'); +run; + +%mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_review,ref=%str(&table rejection), + ctl_ds=&mpelib..mpe_lockanytable +) +proc append base=&mpelib..mpe_review data=work.reject; +run; +%mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_review, + ctl_ds=&mpelib..mpe_lockanytable +) + +%mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_submit,ref=%str(&table rejection), + ctl_ds=&mpelib..mpe_lockanytable +) +proc sql; +update &mpelib..mpe_submit + set submit_status_cd='REJECTED', + num_of_approvals_remaining=0, + reviewed_by_nm="&user", + reviewed_on_dttm=&now + where table_id="&table"; +%mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_submit, + ctl_ds=&mpelib..mpe_lockanytable +) + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc AFTER update...) +) + +%mpe_alerts(alert_event=REJECTED + , alert_lib=%scan(&BASE_TABLE,1,.) + , alert_ds=%scan(&BASE_TABLE,2,.) + , dsid=&TABLE +) + +data fromSAS; + RESPONSE='SUCCESS!'; + set REJECT; +run; + +%removecolsfromwork(___TMP___MD5) + +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/auditors/getauditfile.sas b/sas/sasjs/services/auditors/getauditfile.sas new file mode 100644 index 0000000..ccaa4e7 --- /dev/null +++ b/sas/sasjs/services/auditors/getauditfile.sas @@ -0,0 +1,86 @@ +/** + @file getauditfile.sas + @brief Downloads a zip file containing audit info. + @details The staging location from the &mpelocapprovals location + is zipped and returned as a file download. A user can only request the + audit pack if they have EDIT or APPROVE rights on the target table. + +

SAS Macros

+ @li mf_getuser.sas + @li mf_verifymacvars.sas + @li mpe_accesscheck.sas + @li mp_abort.sas + @li mp_dirlist.sas + @li mp_binarycopy.sas + @li mf_getattrn.sas + @li mp_streamfile.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() +options mprint; + +/* security checks */ +%let user=%mf_getuser(); + +proc sql noprint; +select cats(base_lib,'.',base_ds) into: libds + from &mpelib..mpe_submit + where table_id="&table"; + +%mp_abort( + iftrue=(%mf_verifymacvars(libds table)=0) + ,mac=&_program + ,msg=%str(Missing: libds table) +) + +%mpe_accesscheck(&libds,outds=authEDIT,user=&user,access_level=EDIT); +%mpe_accesscheck(&libds,outds=authAPP,user=&user,access_level=APPROVE); + +%mp_abort( + iftrue=( + %mf_getattrn(work.authEDIT,NLOBS)=0 & %mf_getattrn(work.authAPP,NLOBS)=0 + ) + ,mac=mpestp_audit + ,msg=%str(&user not authorised to download audit data for &table) +) + +ods package(ProdOutput) open nopf; + +options notes source2 mprint; +%let table=%unquote(&table); +%mp_dirlist(outds=dirs, path=&mpelocapprovals/&TABLE); +data _null_; + set dirs; + retain str1 + "ods package(ProdOutput) add file='&mpelocapprovals/&TABLE/"; + retain str2 "' mimetype='text/plain' path='contents/';"; + call execute(cats(str1,filename,str2)); +run; + +%let archive_path=%sysfunc(pathname(work)); + +ods package(ProdOutput) publish archive properties + (archive_name= "&table..zip" archive_path="&archive_path"); + +ods package(ProdOutput) close; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%nrstr(syscc=&syscc) +) + +/* now serve zip file to client */ +%mp_streamfile(contenttype=ZIP + ,inloc=%str(&archive_path/&table..zip) + ,outname=&table..zip +) + +%mpeterm() diff --git a/sas/sasjs/services/auditors/getdiffs.sas b/sas/sasjs/services/auditors/getdiffs.sas new file mode 100644 index 0000000..387732d --- /dev/null +++ b/sas/sasjs/services/auditors/getdiffs.sas @@ -0,0 +1,55 @@ +/** + @file getdiffs.sas + @brief Retrieves the diff file for viewing + @details + +

SAS Macros

+ @li mpe_getvars.sas + @li mpe_accesscheck.sas + @li mf_getattrn.sas + @li mp_abort.sas + @li mp_binarycopy.sas + @li mp_streamfile.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() +%mpe_getvars(BrowserParams, BrowserParams); + +/* security checks */ +%let user=%mf_getuser(); +%mpe_accesscheck(&libds,outds=authEDIT,user=&user,access_level=EDIT) +%mpe_accesscheck(&libds,outds=authAPP,user=&user,access_level=APPROVE) + +%macro mpestp_diffs(); + %if %mf_getattrn(work.authEDIT,NLOBS)=0 & %mf_getattrn(work.authAPP,NLOBS)=0 + %then %do; + %mp_abort(msg=%str( + &user not authorised to download diffs data for &stp_table) + ,mac=mpestp_diffs.sas); + %return; + %end; + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) + ) + + /* stream diffs csv to client */ + %mp_streamfile(contenttype=EXCEL + ,inloc=%str(&mpelocapprovals/&TABLE/&STP_DIFFS_CSV) + ,outname=&STP_DIFFS_CSV + ) + +%mend mpestp_diffs; +%mpestp_diffs() + + + +%mpeterm() diff --git a/sas/sasjs/services/auditors/getstagetable.sas b/sas/sasjs/services/auditors/getstagetable.sas new file mode 100644 index 0000000..a9f9184 --- /dev/null +++ b/sas/sasjs/services/auditors/getstagetable.sas @@ -0,0 +1,35 @@ +/** + @file getstagetable.sas + @brief Retrieves the actual table that is being sent for update + @details + +

SAS Macros

+ @li mf_getvalue.sas + @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%mpeinit() + +%let table_id=%mf_getvalue(work.iwant,table_id); +libname loc "&mpelocapprovals/&table_id"; +data stagetable; + set loc.&table_id; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,stagetable,missing=STRING) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/auditors/postdata.sas b/sas/sasjs/services/auditors/postdata.sas new file mode 100644 index 0000000..460f752 --- /dev/null +++ b/sas/sasjs/services/auditors/postdata.sas @@ -0,0 +1,710 @@ +/** + @file postdata.sas + @brief Either returns the file diffs or actually loads the data to target + @details Before loading the target, a check is made against the time the + target was last updated (backend) and the time the DIFF was generated + (frontend). If the target was updated whilst the DIFF was on the screen, + then the provided diff may have been incorrect and so a new DIFF should be + generated and approved before load. + + Only 100 rows (of each DIFF type) are displayed on the DIFF screen. + +

Service Inputs

+ +
SASCONTROLTABLE
+ |ACTION:$char10.|TABLE:$char32.|DIFFTIME:$char29.| + |---|---|---| + |SHOW_DIFFS|DC20220208T142124517_124703_1184|"Tue, 08 Feb 2022 14:23:05 GMT"| + +

SAS Macros

+ @li bitemporal_dataloader.sas + @li dc_assignlib.sas + @li mf_existds.sas + @li mf_existvar.sas + @li mf_getattrn.sas + @li mf_getengine.sas + @li mf_getquotedstr.sas + @li mf_getuniquelibref.sas + @li mf_getuser.sas + @li mf_getvarlist.sas + @li mf_nobs.sas + @li mf_verifymacvars.sas + @li mp_abort.sas + @li mp_cntlout.sas + @li mp_lockanytable.sas + @li mpe_accesscheck.sas + @li mpe_alerts.sas + @li mpe_runhook.sas + @li mpe_targetloader.sas + @li removecolsfromwork.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +/* this could be a config setting if required */ +%let maxdiff=100; + +%mpeinit() + +/* load parameters */ +data _null_; + set work.sascontroltable; + call symputx('ACTION',ACTION); + call symputx('TABLE',TABLE); + /* DIFFTIME is when the DIFF was generated on the frontend */ + call symputx('DIFFTIME',DIFFTIME); +run; + +%global action is_err err_msg; +%let is_err=0; + +%let user=%mf_getuser(); +%let sastime=%sysfunc(datetime()); +data sastime; + dt_sastime=&sastime; +run; + +PROC FORMAT; + picture yymmddhhmmss other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime); + picture flatdate other='%0Y%0m%0d_%0H%0M%0S' (datatype=datetime); +RUN; + +/* SHOW_DIFFS works by getting the temp tables from the bitemporal loader */ +/* so we share much of the logic from the actual load process */ +%let isfmtcat=0; +data APPROVE1; + set &mpelib..mpe_submit; + where TABLE_ID="&TABLE"; + /* fetch mpe_submit data */ + libds=cats(base_lib,'.',base_ds); + REVIEWED_ON=put(reviewed_on_dttm,datetime19.); + call symputx('REVIEW_STATUS_ID',submit_status_cd,'l'); + call symputx('NUM_OF_APPROVALS_REQUIRED',NUM_OF_APPROVALS_REQUIRED); + call symputx('num_of_approvals_remaining',num_of_approvals_remaining); + + /* other stuff that's useful to do in data step */ + call symputx('orig_libds',libds); + call symputx('libds',libds); + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + call symputx('isfmtcat',1); + libds='work.fmtextract'; + call symputx('libds',libds); + end; + putlog (_all_)(=); + /* convert provided string DIFFTIME back to a numeric SAS datetime */ + if "&action" ne "SHOW_DIFFS" then do; + call symputx('DIFFTIME',input(symget('DIFFTIME'),anydtdtm18.)); + end; + length difftime $32; + DIFFTIME=put(&sastime,datetime19.2); +run; + +%mp_cntlout( + iftrue=(&isfmtcat=1) + ,libcat=&orig_libds + ,fmtlist=0 + ,cntlout=work.fmtextract +) + +%mp_abort( + iftrue=(%mf_verifymacvars(difftime orig_libds libds table)=0) + ,mac=&_program + ,msg=%str(Missing: difftime orig_libds libds table) +) + +/* security checks */ +%mpe_accesscheck(&orig_libds,outds=authEDIT,user=&user,access_level=EDIT) +%mpe_accesscheck(&orig_libds,outds=authAPP,user=&user,access_level=APPROVE) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc Before entering postdata macro) +) + +%mp_abort( + iftrue=( + %mf_getattrn(work.authEDIT,NLOBS)=0 & %mf_getattrn(work.authAPP,NLOBS)=0 + ) + ,mac=&_program + ,msg=%str(&user not authorised to view approval screen for &orig_libds) +) + +%macro quickmacro(inds,outds); + data &outds ; + %if %length(&VAR_BUSFROM)>0 %then %do; + format &VAR_BUSFROM &VAR_BUSTO yymmddhhmmss.; + %end; + if 0 then set &emptybasetable; + set &inds; + %if %mf_existvar(&libds,&var_txfrom) %then %do; + drop &var_txfrom &var_txto; + %end; + %if %mf_existvar(&inds,_____DELETE__THIS__RECORD_____) %then %do; + drop _____DELETE__THIS__RECORD_____; + %end; + %if %mf_existvar(&inds,&VAR_PROCESSED) %then %do; + drop &VAR_PROCESSED; + %end; + run; +%mend quickmacro; + +%macro postdata(); + +%if %quote(&REVIEW_STATUS_ID)=%quote(REJECTED) + or %quote(&REVIEW_STATUS_ID)=%quote(APPROVED) %then +%do; + data params; set approve1; run; + %webout(OPEN) + %webout(OBJ,PARAMS) + %webout(CLOSE) + %return; +%end; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%if &action=APPROVE_TABLE %then %do; + + /* check user is authorised to approve table */ + /* user could be an editor but not an approver */ + %mp_abort(iftrue= (%mf_getattrn(work.authAPP,NLOBS)=0) + ,mac=&_program + ,msg=%str(&user may not APPROVE changes) + ) + + /* see if this user has already submitted an approval */ + %let prev_upload_check=1; + proc sql; + select count(*) into: prev_upload_check from &mpelib..mpe_review + where TABLE_ID="&TABLE" and REVIEWED_BY_NM="&user" + and REVIEW_STATUS_ID ne "SUBMITTED"; + %let authcheck=%mf_getattrn(work.authAPP,NLOBS); + %if &authcheck=0 or &prev_upload_check=1 %then %do; + %put WARNING: authcheck=&authcheck prev_upload_check=&prev_upload_check; + data apPARAMS; + AUTHORISED=&authcheck; + PREV_UPLOAD_CHECK=&prev_upload_check; + run; + %webout(OPEN) + %webout(OBJ,apPARAMS); + %webout(CLOSE) + %return; + %end; + + /* now check if table has been updated since DIFF screen shown */ + %local fmt_tm usernm last_load etlsource; + %let last_load=0; + proc sql noprint; + select max(processed_dttm) format=16.2 into: last_load + from &mpelib..mpe_dataloads + where libref="%scan(&orig_libds,1,.)" and dsn="%scan(&orig_libds,2,.)"; + select processed_dttm format=datetime19., user_nm, etlsource + into: fmt_tm, :usernm, :etlsource + from &mpelib..mpe_dataloads + where libref="%scan(&orig_libds,1,.)" and dsn="%scan(&orig_libds,2,.)" + and processed_dttm=&last_load; + %put TIMECHECK: &last_load>&difftime; + %if %sysevalf(&last_load>&difftime,boolean)=1 %then %do; + %let is_err=1; + %let err_msg=&orig_libds was updated in batch %trim(&etlsource + ) by %trim(&usernm) on &fmt_tm - please refresh the page!!; + %return; + %end; + %if &syscc ne 0 %then %do; + %let is_err=1; + %let err_msg=syscc=&syscc before logchange; + %return; + %end; + + /* upload about to commence so ensure logs */ + options notes mprint source2; + %local oldloc; + %if %symexist(SYSPRINTTOLOG) %then %let oldloc=&SYSPRINTTOLOG; + %else %let oldloc=%qsysfunc(getoption(LOG)); + %if %length(&oldloc)>0 %then %do; + proc printto + log="&mpelocapprovals/&TABLE/approval.log"; + run; + data _null_; + if _n_=1 then do; + length oldloc $1000; + oldloc=symget('oldloc'); + putlog "****** redirected:" oldloc " *****"; + end; + infile &oldloc; + input; putlog _infile_; + run; + %end; + %else %do; + proc printto + log="&mpelocapprovals/&TABLE/approval.log"; + run; + %end; + + %if &syscc ne 0 %then %do; + %let is_err=1; + %let err_msg=syscc=&syscc after logchange; + %return; + %end; +%end; + +/** + * upload the actual table + */ +%local libref ds; +%let libref=%scan(&orig_libds,1,.); +%let ds=%scan(&orig_libds,2,.); + +proc sql noprint; +select PRE_APPROVE_HOOK, POST_APPROVE_HOOK, LOADTYPE, var_txfrom, var_txto + ,BUSKEY, VAR_BUSFROM, VAR_BUSTO + ,AUDIT_LIBDS, NOTES, coalesce(NUM_OF_APPROVALS_REQUIRED,1) + ,VAR_PROCESSED + into: PRE_APPROVE_HOOK, :POST_APPROVE_HOOK, :LOADTYPE,:var_txfrom,:var_txto + ,:BUSKEY,:VAR_BUSFROM,:VAR_BUSTO + ,:AUDIT_LIBDS, :TABLE_DESC, :NUM_OF_APPROVALS_REQUIRED_TOT + ,:VAR_PROCESSED + from &mpelib..mpe_tables + where &dc_dttmtfmt. lt tx_to + and libref="&libref" + and dsn="&ds"; + +%mp_abort( + iftrue=(%mf_verifymacvars(mpelocapprovals orig_libds)=0) + ,mac=&_program + ,msg=%str(Missing: mpelocapprovals orig_libds) +) + +/* get dataset from approvals location */ +%let tmplib=%mf_getuniquelibref(); +libname &tmplib "&mpelocapprovals/&TABLE"; +data STAGING_DS; + set &tmplib..&TABLE; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc before preapprove) +) + +%dc_assignlib(WRITE,&libref) + +/* run pre-approve hook if approving */ +%mpe_runhook(PRE_APPROVE_HOOK) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc after preapprove) +) + +%if &num_of_approvals_remaining>1 and &action=APPROVE_TABLE %then %do; + + /* append to mpe_review table */ + %let apprno=%eval(&num_of_approvals_required-&num_of_approvals_remaining+1); + data work.append_review; + if 0 then set &mpelib..mpe_review; + TABLE_ID="&TABLE"; + BASE_TABLE="&orig_libds"; + REVIEW_STATUS_ID="APPROVED"; + REVIEWED_BY_NM="&user"; + REVIEWED_ON_DTTM=&sastime; + REVIEW_REASON_TXT="APPROVAL &apprno of &num_of_approvals_required"; + output; + stop; + run; + %mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_review,ref=%str(&table Approval), + ctl_ds=&mpelib..mpe_lockanytable + ) + proc append base=&mpelib..mpe_review data=work.append_review; + run; + %mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_review, + ctl_ds=&mpelib..mpe_lockanytable + ) + + /* update mpe_submit table */ + %mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_submit,ref=%str(&table Approval), + ctl_ds=&mpelib..mpe_lockanytable + ) + proc sql; + update &mpelib..mpe_submit + set num_of_approvals_remaining=&num_of_approvals_remaining-1, + reviewed_by_nm="&user", + reviewed_on_dttm=&sastime + where table_id="&table"; + %mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_submit, + ctl_ds=&mpelib..mpe_lockanytable + ) + + data apReqd; + AUTHORISED=1; + ALREADY_UPDATED=0; + ALREADY_UPDATED_DTTM=.; + set approve1; /* js will test for NUM_OF_APPROVALS_REQUIRED */ + run; + %removecolsfromwork(___TMP___MD5) + %webout(OPEN) + %webout(OBJ,apReqd); + %webout(CLOSE) + %return; + +%end; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc entering TARGETLOADER) +) +%mpe_targetloader(libds=&orig_libds + ,now= &sastime + ,etlsource=&TABLE + ,STAGING_DS=STAGING_DS + ,dclib=&mpelib +%if &action=APPROVE_TABLE %then %do; + ,LOADTARGET=YES +%end; +%else %do; + ,LOADTARGET=NO +%end; + ,dc_dttmtfmt=&dc_dttmtfmt. +) + + +%if %mf_getattrn(STAGING_DS,NLOBS)=0 %then %do; + /* empty dataset! */ + data out; + set STAGING_DS; + run; + %return; +%end; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc entering SHOWDIFFS) +) +%if &action=SHOW_DIFFS %then %do; + + /** + * Now prepare the SHOW DIFFS (approve) screen + */ + + /*To create the CURRENT diffs, we compare with the ACTUAL data. But first + need to find out what version TIME to query it for.. */ + proc sql noprint; + select max(processed_dttm)-1 format=datetime19. into: tstamp + from &mpelib..mpe_dataloads + where libref="&libref" and dsn="&ds" and ETLSOURCE="&TABLE"; + quit; + %if &tstamp=. %then %let tstamp=%sysfunc(datetime(),datetime19.); + + /** + * now create the DIFFS dataset + * If using a database, then utilise pass through! + * Create a temporary table inside the database for joins.. + */ + options mprint; + %let engine_type=%mf_getEngine(%scan(&libds,1,.)); + %put &libds engine type = &engine_type; + %local inner_table ; + %if &engine_type=OLEDB %then %do; + /* generate a unique ID for the temporary table */ + data _null_; + call symputx('UNIQUE_REF' + ,cats(round(datetime(),1) + ,'_' + ,round(ranuni(0)*100000,1) + ) + ,'l' + ); + run; + %let inner_table=&libref.."##DIFF_&UNIQUE_REF"n; + proc sql; + create table &inner_table as + select * from work.outds_mod; + %end; + %else %let inner_table=work.outds_mod; + proc sql; + create view work.originals2 as + select b.* + from &inner_table a + inner join &libds + %if &loadtype=BITEMPORAL or &loadtype=TXTEMPORAL %then %do; + (where=("&tstamp"dt < &VAR_TXTO)) + %end; + b + on 1 + %do idx_pk=1 %to %sysfunc(countw(&buskey)); + %let idx_val=%scan(&buskey,&idx_pk); + and a.&idx_val=b.&idx_val + %end; + order by %mf_getquotedstr(in_str=&buskey,dlm=%str(,),quote=) + ; + + create view bitemp5c_updates2 as + select * from work.outds_mod + order by %mf_getquotedstr(in_str=&buskey,dlm=%str(,),quote=) + ; + + data; set &libds;stop;run; + %let emptybasetable=&syslast; + + options varlenchk=nowarn; /* for small numerics (<8) */ + %quickmacro(work.outds_del,deleted) + %quickmacro(work.outds_add,new) + %quickmacro(bitemp5c_updates2,updates) + %quickmacro(originals2,originals) + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc in quickmacro) + ) + + /* extract colnames for md5 creation / change tracking */ + proc contents noprint data=work.updates + out=cols (keep=name type length varnum format); + run; + proc sort data=cols out=cols(drop=varnum); by varnum;run; + data cols; set cols; name=upcase(name);run; + %let tempDIFFS_CSV=tempDiffs_%trim( + %sysfunc(datetime(),flatdate.)).csv; + + /** + * Store temp tables so we have a record of diffs + * do not change this libname or table name as it is used in some + * post approve hooks + */ + + data TEMPDIFFS (compress=no) /* for realistic file size */; + length _____status $10; + set work.deleted (in=_____del) + work.new(in=_____new) + work.updates (in=_____upd) + work.originals2 (in=_____orig); + if _____del then _____status='DELETED '; + else if _____new then _____status='NEW'; + else if _____upd then _____status='UPDATED'; + else if _____orig then _____status='ORIGINAL'; + run; + proc export data=TEMPDIFFS dbms=csv replace + outfile="&mpelocapprovals/&TABLE/&tempDIFFS_CSV" ; + run; + proc sql noprint; + select filesize format=sizekmg10.1, filesize as filesize_raw + into: filesize,:filesize_raw + from dictionary.tables + where libname='WORK' and memtype='DATA' and memname='TEMPDIFFS'; + + data params; + set approve1; + DIFFS_CSV="&tempDIFFS_CSV"; + FILESIZE="&filesize"; + FILESIZE_RAW=&filesize_raw; + if %mf_nobs(work.originals)>&maxdiff + or %mf_nobs(work.new)>&maxdiff + or %mf_nobs(work.deleted)>&maxdiff + or %mf_nobs(work.updates)>&maxdiff + then TRUNCATED="YES"; + else TRUNCATED="NO"; + + NUM_ADDED=%mf_getattrn(work.new,NLOBS); + NUM_DELETED=%mf_getattrn(work.deleted,NLOBS); + NUM_UPDATED=%mf_getattrn(work.updates,NLOBS); + SUBMITTED_ON=put(submitted_on_dttm,datetime19.); + %if %mf_getattrn(work.authAPP,NLOBS)>0 %then %do; + ISAPPROVER='YES'; + %end; + %else %do; + ISAPPROVER='NO'; + %end; + run; + + /* + * The PRE_APPROVE_HOOK may have applied custom formats to the staged table. + * To ensure consistency in the DIFF screen, we should apply the same formats + * to the base table. Limit rows at the same time. + */ + data work.originals; + if 0 then set deleted new updates; + set work.originals; + if _n_>&maxdiff then stop; + run; + + /* get additional submits against the same base table */ + proc sort data=&mpelib..mpe_submit(where=( + submit_status_cd='SUBMITTED' + and cats(base_lib,'.',base_ds)="&orig_libds" + and table_id ne "&TABLE" + )) out=submits; + by descending submitted_on_dttm; + run; + + /* filter last 10 */ + data submits; + set submits; + if _n_>10 then stop; + run; + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc SHOWDIFFS prior to streamout) + ) + + %removecolsfromwork(___TMP___MD5) + %webout(OPEN) + %webout(OBJ,params) + %webout(OBJ,cols) + %webout(OBJ,submits) + %webout(OBJ,deleted,fmt=N,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,new,fmt=N,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,updates,fmt=N,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,ORIGINALS,fmt=N,missing=STRING) + /* need same for formatted view */ + %webout(OBJ,deleted,dslabel=fmt_deleted,fmt=Y,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,new,dslabel=fmt_new,fmt=Y,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,updates,dslabel=fmt_updates,fmt=Y,missing=STRING,maxobs=&maxdiff) + %webout(OBJ,originals,dslabel=fmt_ORIGINALS,fmt=Y,missing=STRING) + %webout(CLOSE) + + %if &engine_type=OLEDB %then %do; + proc sql; /* needs to be dropped AFTER view execution */ + drop table &inner_table; + %end; + + %return; +%end; + + +%if &action=APPROVE_TABLE %then %do; + %approve: + /** + * store temp tables so we have a record of diffs + * do not change this libname or table name as it is used in some + * post approve hooks + * for REPLACE loads, temp tables not made, so make them + */ + %if &LOADTYPE=REPLACE %then %do; + data work.outds_add; run; + data work.outds_mod; run; + %end; + libname approve "&mpelocapprovals/&TABLE"; + data; set &libds;stop;run; + %let emptybasetable=&syslast; + data approve.ActualDiffs; + length _____STATUS_____ $10; + if 0 then set &emptybasetable; + set work.outds_del (in=_____del) + work.outds_add (in=_____new) + work.outds_mod (in=_____upd); + if _____del then _____STATUS_____='DELETED'; + else if _____new then _____STATUS_____='NEW'; + else if _____upd then _____STATUS_____='UPDATED'; + + %if %mf_existvar(&libds,&var_txfrom) %then %do; + drop &var_txfrom &var_txto; + %end; + %if %mf_existvar(&libds,&VAR_PROCESSED) %then %do; + drop &VAR_PROCESSED; + %end; + run; + + proc export data=approve.ActualDiffs + outfile="&mpelocapprovals/&TABLE/ActualDiffs.csv" + dbms=csv + replace; + run; + + /* update the control table to show table as approved */ + /* append to mpe_review table */ + %let apprno=%eval(&num_of_approvals_required-&num_of_approvals_remaining+1); + data work.append_review; + if 0 then set &mpelib..mpe_review; + TABLE_ID="&TABLE"; + BASE_TABLE="&orig_libds"; + REVIEW_STATUS_ID="APPROVED"; + REVIEWED_BY_NM="&user"; + REVIEWED_ON_DTTM=&sastime; + REVIEW_REASON_TXT="APPROVAL &apprno of &num_of_approvals_required"; + output; + stop; + run; + %mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_review,ref=%str(&table Approval), + ctl_ds=&mpelib..mpe_lockanytable + ) + proc append base=&mpelib..mpe_review data=work.append_review; + run; + %mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_review, + ctl_ds=&mpelib..mpe_lockanytable + ) + + /* update mpe_submit table */ + %mp_lockanytable(LOCK, + lib=&mpelib,ds=mpe_submit,ref=%str(&table Approval in auditors/postdata), + ctl_ds=&mpelib..mpe_lockanytable + ) + proc sql; + update &mpelib..mpe_submit + set submit_status_cd='APPROVED', + num_of_approvals_remaining=&num_of_approvals_remaining-1, + reviewed_by_nm="&user", + reviewed_on_dttm=&sastime + where table_id="&table"; + %mp_lockanytable(UNLOCK, + lib=&mpelib,ds=mpe_submit, + ctl_ds=&mpelib..mpe_lockanytable + ) + + /* run post-approve hook */ + %mpe_runhook(POST_APPROVE_HOOK) + + data apPARAMS; + AUTHORISED=1; + ALREADY_UPDATED=0; + ALREADY_UPDATED_DTTM=.; + DIFFTIME="&difftime"; + if &syscc=0 then RESPONSE='SUCCESS!'; + else response="SYSCC=&syscc."; + run; + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program 582 + ,msg=%superq(msg) + ) + + %mpe_alerts(alert_event=APPROVED + , alert_lib=&libref + , alert_ds=&ds + , dsid=&TABLE + ) + + %removecolsfromwork(___TMP___MD5) + %webout(OPEN) + %webout(OBJ,apPARAMS) + %webout(CLOSE) + %return; +%end; +%mend postdata; + +%postdata() + +%mp_abort(mode=INCLUDE) + +%mp_abort(iftrue= (&is_err=1) + ,mac=&_program + ,msg=%superq(err_msg) +) + +%mpeterm() diff --git a/sas/sasjs/services/auditors/postdata.test.1.sas b/sas/sasjs/services/auditors/postdata.test.1.sas new file mode 100644 index 0000000..933d527 --- /dev/null +++ b/sas/sasjs/services/auditors/postdata.test.1.sas @@ -0,0 +1,103 @@ +/** + @file + @brief testing postdata with mpe_x_test + +

SAS Macros

+ @li mp_testservice.sas + @li mp_assert.sas + + +**/ + + +/** + * First part - stage some data (for diffing) + */ +data work.sascontroltable; + action='LOAD'; + message="getdiffs prep"; + libds="&dclib..MPE_X_TEST"; + output; + stop; +run; + +proc sql noprint; +select max(primary_key_field) into: maxpk + from &dclib..mpe_x_test; + +data work.jsdata; + set &dclib..mpe_x_test(rename=( + some_date=dt2 SOME_DATETIME=dttm2 SOME_TIME=tm2) + ); + /* for now, the adapter sends these as strings */ + some_date=put(dt2,date9.); + SOME_DATETIME=put(dttm2,datetime19.); + some_time=put(tm2,time.); + drop dt2 dttm2 tm2; + _____DELETE__THIS__RECORD_____='No'; + if _n_=1 then do; + primary_key_field=sum(&maxpk,1); + some_char=' leadingblanks'; + some_num=._; + output; + end; + else stop; +run; + +%mp_testservice(&appLoc/services/editors/stagedata, + viyacontext=&defaultcontext, + inputdatasets=work.jsdata work.sascontroltable, + outlib=web1 +) + +%let status=0; +data work.sasparams; + set web1.sasparams; + putlog (_all_)(=); + if status='SUCCESS' then call symputx('status',1); + call symputx('dsid',dsid); +run; + +%mp_assert( + iftrue=(&status=1 and &syscc=0), + desc=Checking successful submission +) + +/** + * Now run postdata with SHOW_DIFFS + */ +data work.sascontroltable; + ACTION='SHOW_DIFFS'; + TABLE="&dsid"; + DIFFTIME="%sysfunc(datetime(),B8601DT19.3)"; + output; + stop; +run; +%mp_testservice(&appLoc/services/auditors/postdata, + viyacontext=&defaultcontext, + inputdatasets=work.sascontroltable, + outlib=web2, + outref=wbout +) + +%let leadcheck=0; +%let speshcheck=0; +data _null_; + infile wbout; + input; + putlog _infile_; + /* the JSON libname option removes leading blanks!!!! */ + if index(_infile_,' leadingblanks') then call symputx('leadcheck',1); + /* there is no clean way to send a special missing - so is sent as string */ + if index(_infile_,',"SOME_NUM":"_"') then call symputx('speshcheck',1); +run; + + +%mp_assert( + iftrue=(&leadcheck=1), + desc=Checking leading blanks were applied +) +%mp_assert( + iftrue=(&leadcheck=1), + desc=Checking special characters were applied +) diff --git a/sas/sasjs/services/auditors/postdata.test.2.sas b/sas/sasjs/services/auditors/postdata.test.2.sas new file mode 100644 index 0000000..d563aba --- /dev/null +++ b/sas/sasjs/services/auditors/postdata.test.2.sas @@ -0,0 +1,76 @@ +/** + @file + @brief testing postdata with format table + +

SAS Macros

+ @li mp_testservice.sas + @li mp_assert.sas + + +**/ + + +/** + * First part - stage some data (for diffing) + */ +%let _program=&appLoc/services/editors/stagedata; + +data work.sascontroltable; + action='LOAD'; + MESSAGE='Testing upload of a format catalog'; + LIBDS="DCTEST.DCFMTS-FC"; +run; + +proc format lib=DCTEST.DCFMTS cntlout=work.fmtextract; +run; +data work.jsdata; + set work.fmtextract; + if _n_<5 then _____DELETE__THIS__RECORD_____='Yes'; + else _____DELETE__THIS__RECORD_____='No'; + if _n_>12 then label=cats('new!',label); + if _n_>20 then stop; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.sascontroltable work.jsdata, + outlib=web1 +) + +%let status=0; +data work.sasparams; + set web1.sasparams; + putlog (_all_)(=); + if status='SUCCESS' then call symputx('status',1); + call symputx('dsid',dsid); +run; + +%mp_assert( + iftrue=(&status=1 and &syscc=0), + desc=Checking successful submission +) + +/** + * Now run postdata with SHOW_DIFFS + */ +data work.sascontroltable; + ACTION='SHOW_DIFFS'; + TABLE="&dsid"; + DIFFTIME="%sysfunc(datetime(),B8601DT19.3)"; + output; + stop; +run; +%mp_testservice(&appLoc/services/auditors/postdata, + viyacontext=&defaultcontext, + inputdatasets=work.sascontroltable, + outlib=web2, + outref=wbout +) + + +data _null_; + infile wbout; + input; + putlog _infile_; +run; + diff --git a/sas/sasjs/services/editors/getdata.sas b/sas/sasjs/services/editors/getdata.sas new file mode 100755 index 0000000..16200ba --- /dev/null +++ b/sas/sasjs/services/editors/getdata.sas @@ -0,0 +1,770 @@ +/** + @file getdata.sas + @brief Returns a dataset to the editor front end + @details + +

Service Inputs

+ +
SASCONTROLTABLE
+ |LIBDS:$41.|FILTER_RK:$5.| + |---|---| + |DC258467.MPE_X_TEST|-1| + +

Service Outputs

+
sasdata
+
sasparams
+ Contains info on the request. One row is returned. + * CLS_FLG - set to 0 if there are no CLS rules (everything should be editable) + else set to 1 (CLS rules exist) + +
approvers
+
dqrules
+
dqdata
+
cols
+ Contains column level attributes. + @li NAME - column name + @li VARNUM - variable position. Source: https://core.sasjs.io/mp__getcols_8sas.html + @li LABEL - variable label. Source: https://core.sasjs.io/mp__getcols_8sas.html + @li FMTNAME - derived format name. Source: https://core.sasjs.io/mp__getcols_8sas.html + @li DDTYPE - derived dropdown type. Source: https://core.sasjs.io/mp__getcols_8sas.html + @li CLS_RULE - values include: + - EDIT - the column is editable + - READ - the column should be readonly + - HIDE - the column should be hidden + @li memlabel + @li desc- augmented with MPE_DATADICTIONARY if exists, else label + @li longdesc - from MPE_DATADICTIONARY + + +
maxvarlengths
+
xl_rules
+
query
+ + +

SAS Macros

+ @li dc_assignlib.sas + @li dc_getgroupmembers.sas + @li mf_existvar.sas + @li mf_getattrn.sas + @li mf_getvarlist.sas + @li mf_existds.sas + @li mf_getquotedstr.sas + @li mf_getuser.sas + @li mf_nobs.sas + @li mf_verifymacvars.sas + @li mf_wordsinstr1butnotstr2.sas + @li mp_abort.sas + @li mp_cntlout.sas + @li mp_dsmeta.sas + @li mp_getcols.sas + @li mp_getmaxvarlengths.sas + @li mp_validatecol.sas + @li mpe_accesscheck.sas + @li mpe_columnlevelsecurity.sas + @li mpe_getlabels.sas + @li mpe_filtermaster.sas + @li mpe_runhook.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +/** + * Validate inputs + */ +data work.intest; + length filter_rk 8; + set work.SASCONTROLTABLE; + + /* validate filter_rk */ + if filter_rk le 0 then filter_rk=-1; + + call symputx('orig_libds',upcase(libds)); + + is_fmt=0; + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + is_fmt=1; + libds='work.fmtextract'; + call symputx('libds',libds); + end; + call symputx('is_fmt',is_fmt); + putlog (_all_)(=); + + /* validate libds */ + %mp_validatecol(LIBDS,LIBDS,is_libds) + + if is_libds=0 then do; + putlog 'ERR' 'OR: Invalid libds:' libds; + stop; + end; + else do; + call symputx('filter_rk',filter_rk); + call symputx('libds',libds); + end; + output; + stop; +run; + +%mp_abort(iftrue= (%mf_nobs(work.intest)=0) + ,mac=&_program + ,msg=%str(Some err with service inputs) +) + +%mp_abort( + iftrue=(%mf_verifymacvars(libds filter_rk)=0) + ,mac=&_program + ,msg=%str(Missing: libds filter_rk) +) + +/* export format catalog */ +%mp_cntlout( + iftrue=(&is_fmt=1) + ,libcat=&orig_libds + ,fmtlist=0 + ,cntlout=work.fmtextract +) + +/* stream back meta info, further calls will return col metadata and actual data +*/ +%let libref=%upcase(%scan(&libds,1,.)); +%let dsn=%upcase(%scan(&libds,2,.)); +%dc_assignlib(WRITE,&libref) + +/** + * First check user has access permission to edit the table + */ +%put checking access; +%let user=%mf_getuser(); +%mpe_accesscheck(&orig_libds,outds=mw_auth,user=&user,access_level=EDIT) + + +%mp_abort(iftrue= (%mf_getattrn(work.mw_auth,NLOBS)=0) + ,mac=mpestp_getdata.sas + ,msg=&user is not authorised to edit &orig_libds %trim( + )in the &mpelib..MPE_SECURITY table +) + +%mp_abort(iftrue= ( %mf_existds(libds=&libds) ne 1) + ,mac=mpestp_getdata.sas + ,msg=dataset &libds does not exist!! +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc at line 60 ) +) + + +%global loadtype var_txfrom var_txto var_processed filter_text pk coltype + sortpk; + +%put getting table attributes; +proc sql noprint; +select upcase(loadtype) + ,var_txfrom,var_txto + ,var_busfrom,var_busto + ,var_processed,rk_underlying,buskey + ,coalesce(rk_underlying,buskey) + ,pre_edit_hook + ,case when missing(rk_underlying) then buskey else rk_underlying end + into: loadtype,:var_txfrom,:var_txto + ,:var_busfrom ,:var_busto + ,:var_processed,:rk_underlying,:buskey, :sortPK, :pre_edit_hook,:pk + from &mpelib..mpe_tables + where &dc_dttmtfmt. lt TX_TO + and upcase(dsn)="%scan(&orig_libds,2,.)" + and upcase(libref)="%scan(&orig_libds,1,.)"; + +%put preparing filter query:; +%mpe_filtermaster(EDIT,&orig_libds, + dclib=&mpelib, + filter_rk=&filter_rk, + outref=filtref, + outds=work.query +) + +%macro mpestp_getdata(); + %if not %symexist(DC_MAXOBS_WEBEDIT) %then %do; + %put NOTE:;%put NOTE- DC_MAXOBS_WEBEDIT not found!; + %put NOTE- Please add to &mpelib..MPE_CONFIG table; + %put NOTE-;%put NOTE-; + %global DC_MAXOBS_WEBEDIT; + %let DC_MAXOBS_WEBEDIT=500; + %end; + /* for tables which use RKs/SKs then we just expose the business key to + users - this lets uploads be sent to multiple environments (with + potentially different RK/SK values for the same business key). + Note that the config table has the RK column in the buskey field in + this scenario. */ + %if %length(&rk_underlying)>0 %then %let drop_rk=&buskey; + %else %let drop_rk=; + + /* always remove the PROCESSED_DTTM column, if it exists */ + %if %length(&var_processed)=0 %then %do; + %if %mf_existvar(&libds,PROCESSED_DTTM)>0 %then + %let var_processed=PROCESSED_DTTM; + %end; + + /** + * Now get the slice of the actual table + */ + options obs=10000; + + %if &loadtype=BITEMPORAL %then %do; + data out (drop=&var_txfrom &var_txto &var_processed &drop_rk ); + _____DELETE__THIS__RECORD_____="No"; + set &libds; + where %inc filtref;; + run; + proc sort data=out; + by &pk &var_busfrom; + run; + data out; + set out; + by &pk &var_busfrom; + if last.%scan(&pk,-1); + run; + %end; + %else %do; + data out (drop=&var_txfrom &var_txto &var_processed &drop_rk); + _____DELETE__THIS__RECORD_____="No"; + set &libds; + where %inc filtref;; + run; + %end; + options obs=max; + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Issue with filtering (line 165) ) + ) + + options obs=&DC_MAXOBS_WEBEDIT; + %let sortpk=%sysfunc(coalescec(&sortpk &var_busfrom,_ALL_)); + proc sort data=work.out; by &sortPK; run; + options obs=max; + + %mpe_runhook(PRE_EDIT_HOOK) + + %let obscnt=%mf_getattrn(work.out,NLOBS); + %mp_abort(iftrue=(&obscnt>&DC_MAXOBS_WEBEDIT) + ,mac=&_program + ,msg=Table is too big (&obscnt rows) - please filter and try again! + ) + + + /* order delete var and pk fields at start of table */ + %let sourcevars=%mf_wordsInStr1ButNotStr2( + Str1=%mf_getvarlist(work.out) + ,Str2= _____DELETE__THIS__RECORD_____ &pk + ); + %put sourcevars=&sourcevars; + data outdata; + /* delete & pk fields come first */ + attrib _____DELETE__THIS__RECORD_____ &pk label=''; + /* keep remaining variable order */ + %if %length(&sourcevars)>0 %then %do; + attrib &sourcevars label=''; + %end; + _____DELETE__THIS__RECORD_____="No "; + %if %mf_nobs(work.out)=0 %then %do; + /* send empty row if empty table to help with hot rendering */ + output; + %end; + set work.out ; + run; + + + + /* get list of variables and their formats */ + proc contents noprint data=outdata + out=vars(keep=name type length varnum format: label); + run; + + proc sort; + by varnum; + run; + + data vars3(keep=name type length format label pk varnum ctrloptions formatd); + set vars(rename=(format=format2 type=type2)); + name=upcase(name); + /* not interested in transaction or processing dates + (append table must be supplied without them) */ + if name not in ("&VAR_TXFROM","&VAR_TXTO","&VAR_PROCESSED"); + if type2=2 or type2=6 then do; + length format $49.; + if format2='' then format=cats('$',length,'.'); + else format=cats(format2,formatl,'.'); + type='char'; + end; + else do; + if format2='' then format=cats(length,'.'); + else if upcase(format2)='DATETIME' and formatl=0 then format='DATETIME.'; + else format=cats(format2,formatl,'.',formatd); + type='num'; + end; + + if name in ('',%upcase(%mf_getQuotedStr(&pk,dlm=%str(,),quote=S))) + then PK='YES'; + + length ctrlOptions $500; + if name="_____DELETE__THIS__RECORD_____" then ctrlOptions='["No","Yes"]'; + else ctrlOptions=''; + run; + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc at 242 (vars3 step) in &_program \n + %superq(syserrortext) + ) + ) + + %global jsdttmvars jsdtvars jstmvars; + data _null_; + set vars3 end=last; + if _n_>1 then comma=','; + length coltype $500.; + format=upcase(format); + coltype=cats(comma,'{"data":"',name,'"'); + if ctrlOptions ne '' then + colType=cats(coltype,',"type":"dropdown","source":',ctrlOptions,"}"); + else if type='num' then do; + if format=:'DATETIME' or format=:'E8601DT' then do; + colType=cats(coltype + ,',"type":"date","dateFormat":"YYYY-MM-DD HH:mm:ss"' + ,',"correctFormat":"true"}'); + /* build var list to reformat datetimes in javascript format */ + call symput('jsdttmvars',symget('jsdttmvars')!!' '!!name); + end; + else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY' + or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA' + or format=:'MONYY' + then do; + /* see bottom of file for more date formats!! */ + /* also when updating, update stagedata.sas and mp_getcols.sas + and mpe_loader.sas */ + colType=cats(coltype,',"type":"date","dateFormat":"YYYY-MM-DD"' + /*colType=cats(coltype,',"type":"date","dateFormat":"MM/DD/YYYY"'*/ + ,',"correctFormat":"true"}'); + /* build var list to reformat as javascript dates */ + call symput('jsdtvars',symget('jsdtvars')!!' '!!name); + end; + else if format=:'TIME' or format=:'HHMM' then do; + colType=cats(coltype,',"type":"time","timeFormat":"HH:mm:ss"' + ,',"correctFormat":"true"}'); + /* build var list to reformat as javascript times */ + call symput('jstmvars',symget('jstmvars')!!' '!!name); + end; + else do; + /* is standard numeric but need to ascertain precision */ + retain base '000000000000000000'; + if formatd>0 then numFormat=cats('.',substr(base,1,formatd)); + colType=cats(coltype,',"type":"numeric","format":"0',numFormat,'"}'); + end; + end; + else colType=cats(coltype,'}'); + length concatcoltype $32767; + retain concatcoltype; + concatcoltype=cats(concatcoltype,coltype); + if last then call symputx('colType',strip(concatcoltype),'g'); + putlog (_all_)(=); + run; + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc at 283 (null step) in &_program) + ) + + PROC FORMAT; + picture yymmddThhmmss (default=28) other='%0Y-%0m-%0d %0H:%0M:%0s' + (datatype=datetime); + picture JSyymmdd other='%0Y-%0m-%0d' (datatype=date); + picture JShhmmss (default=16) other='%0H:%0M:%0s' (datatype=time); + RUN; + /* before we send the data, need to rebuild all date & datetime vars as char*/ + %let finalvars=%mf_getvarlist(work.outdata); + data sasdata; + /* set formats & col order ahead of rename+import */ + informat &finalvars ; + /* read dataset and rename date / datetime vars as necessary */ + set outdata + %if %length(&jsdttmvars&jsdtvars&jstmvars)>0 %then %do; + (rename=( + %local dtvarnum dtvar tmvar; + /* temp datetime vars end in _____ */ + %do dtvarnum=1 %to %sysfunc(countw(&jsdttmvars,%str( ))); + %let dtvar=%scan(&jsdttmvars ,&dtvarnum); + &dtvar=_____&dtvarnum._____ + %end; + /* temp date vars do not end in _____ */ + %do dtvarnum=1 %to %sysfunc(countw(&jsdtvars,%str( ))); + %let dtvar=%scan( &jsdtvars,&dtvarnum); + &dtvar=_____&dtvarnum + %end; + /* temp time vars end in ___tm */ + %do tmvarnum=1 %to %sysfunc(countw(&jstmvars,%str( ))); + %let tmvar=%scan( &jstmvars,&tmvarnum); + &tmvar=_____&tmvarnum.___tm + %end; + )) + %end; + ; + %if %length(&jsdttmvars)>0 %then %do ; + %do dtvarnum=1 %to %sysfunc(countw(&jsdttmvars,%str( ))); + %let dtvar=%scan(&jsdttmvars,&dtvarnum); + &dtvar=cats(put(_____&dtvarnum._____,yymmddThhmmss28.)); + if &dtvar="ERROR" then call missing(&dtvar); + drop _____&dtvarnum._____; + %end; + %end; + %if %length(&jsdtvars)>0 %then %do; + %do dtvarnum=1 %to %sysfunc(countw(&jsdtvars,%str( ))); + %let dtvar=%scan(&jsdtvars,&dtvarnum); + &dtvar=cats(put(_____&dtvarnum,JSyymmdd.)); + if &dtvar="ERROR" then call missing(&dtvar); + drop _____&dtvarnum; + %end; + %end; + %if %length(&jstmvars)>0 %then %do; + %do tmvarnum=1 %to %sysfunc(countw(&jstmvars,%str( ))); + %let tmvar=%scan(&jstmvars,&tmvarnum); + &tmvar=cats(put(_____&tmvarnum.___tm,JShhmmss14.)); + if &tmvar="ERROR" then call missing(&tmvar); + drop _____&tmvarnum.___tm; + %end; + %end; + output; + run; + + /* get the relevant approvers for the drop down */ + %put getting approvers; + %local sas_groups sas_i sas_group; + proc sql noprint; + select distinct sas_Group into: sas_groups separated by "|" + from &mpelib..mpe_security + where libref="%scan(&orig_libds,1,.)" + and dsn="%scan(&orig_libds,2,.)" + and access_level='APPROVE' + and &dc_dttmtfmt. lt TX_TO; + + %if %length(&sas_groups)=0 %then %do; + %dc_getgroupmembers(&dc_admin_group,outds=work.access1) + %end; + %else %do sas_i=1 %to %sysfunc(countw(&sas_groups,%str(|))); + %let sas_group=%scan(&sas_Groups,&sas_i,%str(|)); + %dc_getgroupmembers(&sas_group,outds=work.temp&sas_i) + proc append base=work.access1 data=work.temp&sas_i;run; + %end; + +%mend mpestp_getdata; + +%mpestp_getdata() + +%mp_abort(mode=INCLUDE) + +/* extract column level security rules */ +%mpe_columnlevelsecurity(%scan(&libds,1,.),%scan(&libds,2,.),work.sasdata + ,mode=EDIT + ,clsds=&mpelib..mpe_column_level_security + ,groupds=work.groups /* was created in mpe_filtermaster */ + ,outds=work.sasdata1 + ,outmeta=work.cls_rules +) + +/* get labels */ +%mpe_getlabels(COLUMNS,sasdata1,outds=spec) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc extracting spec info) +) + +/* extract col info */ +%mp_getcols(&libds, outds=cols1) + +/* join with cls rules */ +proc sql; +create table work.cols as + select a.NAME + ,a.VARNUM + ,a.LABEL + ,a.FMTNAME + ,a.DDTYPE + ,case b.cls_hide + when 1 then 'HIDE' + when 0 then 'EDIT' + else 'READ' end as CLS_RULE + ,c.memlabel + ,c.desc + ,c.longdesc + from work.cols1 a + left join work.cls_rules b + on a.NAME=b.CLS_VARIABLE_NM + left join work.spec c + on a.NAME=c.NAME; + +proc sql; +create table approvers as select distinct membername as personname + ,membername as email, membername as userid + from work.access1; +/* +create table access3 as select b.userid,b.email + from access2 a + ,support.users b + where a.personname=b.userid + and a.personname ne "%mf_getuser()" + and %sysfunc(datetime()) lt b.tx_to_dttm + order by 1; +*/ +data _null_; + infile filtref end=eof; + input; + length filter_text $32767; + retain filter_text; + filter_text=catx(' ',filter_text,_infile_); + if eof then do; + if cats(filter_text)='1=1' then filter_text=''; + call symputx('filter_text',filter_text); + end; +run; + +%put params; +data sasparams; + length colHeaders $20000 filter_text $32767; + colHeaders=cats(upcase("%mf_getvarlist(sasdata1,dlm=%str(,))")); + pkCnt=countw("&pk"); + pk="&pk"; + dtvars=compbl("&jsdtvars"); + dttmvars=compbl("&jsdttmvars"); + tmvars=compbl("&jstmvars"); + length coltype $32000; + coltype=symget('coltype'); + loadtype=symget('loadtype'); + if trim(symget('rk_underlying')) ne '' then rk_flag=1; + else rk_flag=0; + filter_text=symget('filter_text'); + if %mf_nobs(work.cls_rules)=0 then cls_flag=0; + else cls_flag=1; + put (_all_)(=); +run; + +/* Extract validation DQ Rules */ +proc sort data=&mpelib..mpe_validations + (where=(&dc_dttmtfmt. le TX_TO + and BASE_LIB="%scan(&orig_libds,1,.)" and BASE_DS="%scan(&orig_libds,2,.)" + and rule_active=1)) + out=dqrules (keep=base_col rule_type rule_value); + by base_col rule_type rule_value; +run; + +/* merge with NOTNULL constraints in the physical table */ +proc sql; +create table _data_ as + select * from dqrules +union + select upcase(name) as base_col + ,'NOTNULL' as rule_type + ,'' as rule_value + from dictionary.columns + where upcase(libname)="%scan(&orig_libds,1,.)" + and upcase(memname)="%scan(&orig_libds,2,.)" + and upcase(name) in (select name from vars3) + and notnull='yes' + order by 1,2,3; +data dqrules; + set &syslast; + by base_col rule_type rule_value; + if last.rule_type; + if rule_type in ('HARDSELECT','SOFTSELECT') and countw(rule_value)=3 then + do; + retain x 0; x+1; + call symputx(cats('source',x),rule_value); + %let sourcecnt=0; + call symputx('sourcecnt',x); + call symputx(cats('base_col',x),base_col); + end; +run; + +proc sql; +create table dqdata as + select distinct base_column as base_col length=32 + ,upcase(base_column) as rule_value length=74 /* deprecated */ + ,selectbox_value as rule_data length=1000 + ,selectbox_order + from &mpelib..mpe_selectbox + where &dc_dttmtfmt. lt ver_to_dttm + and select_lib="%scan(&orig_libds,1,.)" + and select_ds="%scan(&orig_libds,2,.)"; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc during DQ rule validation) +) + +/* extract selectbox data */ +%macro dq_selects(); + %local x source lib ds col; + %do x=1 %to &sourcecnt; + %let source=&&source&x; + %let lib=%scan(&source,1,.); + %let ds=%scan(&source,2,.); + %let col=%scan(&source,3,.); + %put &=source; + %put &=lib; + %dc_assignlib(READ,&lib) + proc sql; + create table dqdata&x as + select distinct "&&base_col&x" as base_col length=32 + ,"&source" as rule_value length=74 + ,cats(&col) as rule_data length=1000 + ,0 as selectbox_order + from &lib..&ds + order by 1; + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc when selecting &&base_col&x from &orig_libds) + ) + proc append base=dqdata data=dqdata&x;run; + proc sql; drop table dqdata&x; + %end; +%mend dq_selects; +%dq_selects() + +proc sort data=dqdata; + by base_col selectbox_order; +run; + + + +%mp_getmaxvarlengths(work.sasdata1,outds=maxvarlengths) + +data maxvarlengths; + set maxvarlengths; + if name='_____DELETE__THIS__RECORD_____' then mAXLEN=3; +run; + +data xl_rules; + set &mpelib..mpe_excel_config; + where &dc_dttmtfmt. lt tx_to; + where also upcase(xl_libref)="%scan(&orig_libds,1,.)"; + where also upcase(xl_table)="%scan(&orig_libds,2,.)"; + where also xl_active=1; + keep xl_column xl_rule; +run; + +%mp_dsmeta(&libds, outds=dsmeta) + +/* send to the client */ +%webout(OPEN) +%webout(OBJ,approvers) +%webout(OBJ,cols) +%webout(OBJ,dqdata) +%webout(OBJ,dqrules) +%webout(OBJ,dsmeta) +%webout(OBJ,maxvarlengths) +%webout(OBJ,query) +%webout(OBJ,sasdata1,fmt=N,missing=STRING,showmeta=YES,dslabel=sasdata) +%webout(OBJ,sasparams) +%webout(OBJ,xl_rules) +%webout(CLOSE) + +/* +$N8601Bw +$N8601BAw +$N8601Ew +$N8601EAw +$N8601EHw +$N8601EXw +$N8601Hw +$N8601Xw +B8601DAw +B8601DNw +B8601DTw +B8601DZw +B8601LZw +B8601TMw +B8601TZw +DATEw +DATEAMPMw +DATETIMEw +DAYw +DDMMYYw +DDMMYYxw +DOWNAMEw +DTDATEw +DTMONYYw +DTWKDATXw +DTYEARw +DTYYQCw +E8601DAw +E8601DNw +E8601DTw +E8601DZw +E8601LZw +E8601TMw +E8601TZw +HHMMw +HOURw +JULDAYw +JULIANw +MMDDYYw +MMDDYYxw +MMSSw +MMYYw +MMYYxw +MONNAMEw +MONTHw +MONYYw +PDJULGw +PDJULIw +QTRw +QTRRw +TIMEw +TIMEAMPMw +TODw +WEEKDATEw +WEEKDATXw +WEEKDAYw +WEEKUw +WEEKVw +WEEKWw +WORDDATEw +WORDDATXw +YEARw +YYMMw +YYMMxw +YYMMDDw +YYMMDDxw +YYMONw +YYQw +YYQxw +YYQRw +YYQRxw +$N8601BAw +$N8601Ew +$N8601EAw +$N8601EHw +$N8601EXw +$N8601Hw +$N8601Xw +B8601DAw +B8601DNw +B8601DTw +B8601DZw +B8601LZw +B8601TMw +B8601TZw +E8601DAw +E8601DNw +E8601DTw +E8601DZw +E8601LZw +E8601TMw +E8601TZw +*/ +%mpeterm() diff --git a/sas/sasjs/services/editors/getdata.test.sas b/sas/sasjs/services/editors/getdata.test.sas new file mode 100644 index 0000000..9f7aec9 --- /dev/null +++ b/sas/sasjs/services/editors/getdata.test.sas @@ -0,0 +1,188 @@ +/** + @file + @brief testing gethistory service + +

SAS Macros

+ @li mp_assertcols.sas + @li mp_assertcolvals.sas + @li mp_assertdsobs.sas + @li mf_getuniquefileref.sas + @li mp_filterstore.sas + +**/ + +%let _program=&appLoc/services/editors/getdata; + +/** + * Test 1 - basic fetch + */ + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'LIBDS:$43.'; + put "&dclib..MPE_TABLES"; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:sascontroltable, + outlib=web1 +) +data _null_; + infile "%sysfunc(pathname(WEB1))" lrecl=32767; + input; + putlog _infile_; +run; + +data sasdata; + set web1.sasdata; +data sasparams; + set web1.sasparams; +data approvers; + set web1.approvers; +data dqrules; + set web1.dqrules; +data dqdata; + set web1.dqdata; +data spec; + set web1.spec; +data cols; + set web1.cols; +data maxvarlengths; + set web1.maxvarlengths; +data xl_rules; + set web1.xl_rules; +data query; + set web1.query; +run; + +%mp_assertcols(work.query, + desc=Query dataset is empty (test cols not obs as table has one row), + cols=VARIABLE_NM RAW_VALUE SUBGROUP_ID, + test=NONE, + outds=work.test_results +) +%mp_assertdsobs(work.sasdata, + desc=Test1 - data is returned, + test=HASOBS, + outds=work.test_results +) + + +/** + * Test 2 - filtered view + */ + +/* first, make filter */ +data work.inquery; + infile datalines4 dsd; + input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. + OPERATOR_NM:$10. RAW_VALUE:$4000.; +datalines4; +AND,AND,1,LIBREF,CONTAINS,"'DC'" +AND,OR,2,DSN,=,"'MPE_LOCK_ANYTABLE'" +;;;; +run; +%mp_filterstore( + libds=&dc_libref..MPE_TABLES, + filter_summary=&dc_libref..mpe_filteranytable, + filter_detail=&dc_libref..mpe_filtersource, + lock_table=&dc_libref..mpe_lockanytable, + maxkeytable=&dc_libref..mpe_maxkeyvalues, + queryds=work.inquery, + outresult=work.result, + outquery=work.query +) +data _null_; + set work.result; + call symputx('filter_rk',filter_rk); +run; + +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + put 'LIBDS:$43. FILTER_RK:8.'; + put "&dclib..MPE_TABLES,&filter_rk"; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f2:sascontroltable, + outlib=web2 +) + +data sasdata; + set web2.sasdata; +data query; + set web2.query; +run; + +%mp_assertdsobs(work.query, + desc=Test2 - query has rows, + test=HASOBS, + outds=work.test_results +) +%mp_assertdsobs(work.sasdata, + desc=Test2 - data has just one row, + test=EQUALS 1, + outds=work.test_results +) + + +/** + * Test 3 - format catalog + */ + +/* first, make filter */ +data work.inquery3; + infile datalines4 dsd; + input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. + OPERATOR_NM:$10. RAW_VALUE:$4000.; +datalines4; +AND,AND,1,FMTNAME,CONTAINS,"'MOR'" +;;;; +run; +%mp_filterstore( + libds=DCTEST.DCFMTS-FC, + filter_summary=&dc_libref..mpe_filteranytable, + filter_detail=&dc_libref..mpe_filtersource, + lock_table=&dc_libref..mpe_lockanytable, + maxkeytable=&dc_libref..mpe_maxkeyvalues, + queryds=work.inquery3, + outresult=work.result3, + outquery=work.query +) +data _null_; + set work.result3; + call symputx('filter_rk3',filter_rk); +run; + +%let f3=%mf_getuniquefileref(); +data _null_; + file &f3 termstr=crlf; + put 'LIBDS:$43. FILTER_RK:8.'; + put "DCTEST.DCFMTS-FC,&filter_rk3"; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f3:sascontroltable, + outlib=web3 +) + +data sasdata3; + set web3.sasdata; +data query3; + set web3.query; +run; + +%mp_assertdsobs(work.query3, + desc=Test3 - format query has rows, + test=HASOBS, + outds=work.test_results +) +%mp_assertdsobs(work.sasdata3, + desc=Test3 - format data has rows, + test=ATLEAST 5, + outds=work.test_results +) diff --git a/sas/sasjs/services/editors/getdynamiccolvals.sas b/sas/sasjs/services/editors/getdynamiccolvals.sas new file mode 100644 index 0000000..c185c88 --- /dev/null +++ b/sas/sasjs/services/editors/getdynamiccolvals.sas @@ -0,0 +1,192 @@ +/** + @file getdynamiccolvals.sas + @brief Provide dynamic list of values according to a SAS program or service + @details Configuration is made in the MPE_VALIDATIONS table, the dropdown + can be either a SOFTSELECT_HOOK or HARDSELECT_HOOK. + + Results are sent in ARRAY format for efficiency. + +

Service Inputs

+
SASCONTROLTABLE
+ + |LIBDS:$41.|VARIABLE_NM:$32.| + |---|---| + |DC258467.MPE_SECURITY|SAS_GROUP| + +
SOURCE_ROW
+ + This contains the raw values from the source table. + +

Service Outputs

+ + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + + +

SAS Macros

+ @li dc_assignlib.sas + @li dc_getservicecode.sas + @li mf_nobs.sas + @li mp_abort.sas + @li mp_include.sas + @li mp_validatecol.sas + @li mf_getapploc.sas + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +/** + * Validate inputs + */ +%let err_msg=; +data work.intest; + set work.SASCONTROLTABLE; + + /* validate libds */ + %mp_validatecol(LIBDS,LIBDS,is_libds) + + /* validate varname */ + is_name=nvalid(variable_nm,'v7'); + putlog (_all_)(=); + if is_libds ne 1 then do; + msg='ERR'!!'OR: Invalid libds:'!!libds; + call symputx('err_msg',msg); + stop; + end; + else if is_name ne 1 then do; + msg='ERR'!!'OR: Invalid name:'!!variable_nm; + call symputx('err_msg',msg); + stop; + end; + else do; + call symputx('variable_nm',variable_nm); + call symputx('libds',libds); + end; + output; + stop; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc after reading work.sascontroltable) +) +%mp_abort(iftrue= (%mf_nobs(work.intest)=0) + ,mac=&_program + ,msg=%str(&err_msg) +) + +%dc_assignlib(READ,%scan(&libds,1,.)) + +/* ensure that work.dynamic_extended_values exists */ +data work.dynamic_extended_values; +run; + +/** + * Get the code to execute + */ +data work.codetest; + set &mpelib..MPE_VALIDATIONS; + where &dc_dttmtfmt. lt tx_to + and base_lib="%scan(&libds,1,.)" + and base_ds="%scan(&libds,2,.)" + and base_col="&variable_nm" + and RULE_TYPE in ('HARDSELECT_HOOK','SOFTSELECT_HOOK') + and RULE_ACTIVE=1; + putlog (_all_)(=); + if length(rule_value)>1 then do; + call symputx('pgmloc',rule_value); + if scan(upcase(rule_value),-1,'.')='SAS' then do; + call symputx('pgmtype','PGM'); + call symputx('pgmloc',rule_value); + end; + else do; + apploc="%mf_getapploc()"; + if substr(rule_value,1,1) ne '/' + then rule_value=cats(apploc,'/',rule_value); + call symputx('pgmloc',rule_value); + call symputx('pgmtype','JOB'); + end; + output; + stop; + end; + else stop; +run; +%mp_abort(iftrue= (%mf_nobs(work.codetest)=0) + ,mac=&_program + ,msg=%str(Hook not found in &mpelib..mpe_validations for &libds..&variable_nm) +) + +%macro getdynamiccolvals(); +%if &pgmtype=PGM %then %do; + filename sascode "&pgmloc"; +%end; +%else %do; + %dc_getservicecode(loc=&pgmloc + ,outref=sascode + ) +%end; + +%mend getdynamiccolvals; +%getdynamiccolvals() + +/* execute the dynamic code */ +%mp_include(sascode) +%mp_abort(mode=INCLUDE) + +/* ensure that the DISPLAY_INDEX variable exists */ +data work.dynamic_values; + length DISPLAY_INDEX 8 DISPLAY_VALUE $32767; + if _n_=1 then call missing(of _all_); + set work.dynamic_values; + display_index=coalesce(display_index,_n_); + keep DISPLAY_INDEX DISPLAY_VALUE RAW_VALUE; +run; + +/* ensure that work.dynamic_extended_values exists with correct types */ +data work.dynamic_extended_values; + length DISPLAY_INDEX 8 EXTRA_COL_NAME $32 DISPLAY_VALUE $5000 DISPLAY_TYPE $1 + RAW_VALUE_NUM 8 RAW_VALUE_CHAR $5000 FORCED_VALUE 8; + if _n_=1 then call missing(of _all_); + set work.dynamic_extended_values; +run; + +%webout(OPEN) +%webout(ARR,dynamic_values,fmt=N) +%webout(ARR,dynamic_extended_values,fmt=N) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/editors/getdynamiccolvals.test.1.sas b/sas/sasjs/services/editors/getdynamiccolvals.test.1.sas new file mode 100644 index 0000000..32edcb4 --- /dev/null +++ b/sas/sasjs/services/editors/getdynamiccolvals.test.1.sas @@ -0,0 +1,105 @@ +/** + @file + @brief testing getdynamiccolvals service + +

SAS Macros

+ @li mp_assertcols.sas + @li mp_assertcolvals.sas + @li mp_assertdsobs.sas + @li mf_getuniquefileref.sas + @li mx_testservice.sas + +**/ + +%let _program=&appLoc/services/editors/getdynamiccolvals; + +/** + * Test 1 - basic fetch + */ + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'libds:$41. variable_nm:$32.'; + put "&dclib..MPE_SECURITY,SAS_GROUP"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + put '_____DELETE__THIS__RECORD_____:$2. LIBREF:$8. DSN:$10. ACCESS_LEVEL:$7.'; + put 'No,DC265453,MPE_X_TEST,APPROVE'; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:sascontroltable &f2:source_row, + outlib=web1, + mdebug=&sasjs_mdebug +) + +data work.DYNAMIC_VALUES; + set web1.DYNAMIC_VALUES; + if _n_=1 then do; + putlog '>>TEST1<<'; + putlog (_all_)(=); + end; +run; + +/* results are sent as ARRAY so there are no column names. Check for table, + and the three array alements +*/ +%mp_assertcols(work.DYNAMIC_VALUES, + cols=element1 element2 element3, + test=ALL, + desc=Check three columns exist in DYNAMIC_VALUES +) + +/** + * Test 2 - check libds + */ + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'libds:$41. variable_nm:$32.'; + put "&dclib..MPE_TABLES,LIBREF"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + put 'LIBREF:$char8. DSN:$char16. NUM_OF_APPROVALS_REQUIRED:best. LOADTYPE:$char10. '@; + put 'BUSKEY:$char35. VAR_TXFROM:$char7. VAR_TXTO:$char5. VAR_BUSFROM:$char1. '@; + put 'VAR_BUSTO:$char1. VAR_PROCESSED:$char1. CLOSE_VARS:$char1. PRE_EDIT_HOOK:$char1. '@; + put 'POST_EDIT_HOOK:$char1. PRE_APPROVE_HOOK:$char1. POST_APPROVE_HOOK:$char1. '@; + put 'SIGNOFF_COLS:$char1. SIGNOFF_HOOK:$char1. NOTES:$char55. RK_UNDERLYING:$char1. '@; + put 'AUDIT_LIBDS:$char1. _____DELETE__THIS__RECORD_____:$char2.'; + put 'DC266708,MPE_VALIDATIONSF,14,TXTEMPORAL,BASE_LIB BASE_DS BASE_COL RULE_TYPE,TX_FROM'@; + put ',TX_TO, , , , , , , , ,,,Configuration of data quality rules in Editor component, , ,No'; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:sascontroltable &f2:source_row, + outlib=web2, + mdebug=&sasjs_mdebug +) + +data DYNAMIC_VALUES; + set web2.DYNAMIC_VALUES; + if _n_=1 then do; + putlog '>>TEST2<<'; + putlog (_all_)(=); + end; +run; + +data work.check; + val="&dclib"; +run; +%mp_assertcolvals(work.dynamic_values.element2, + checkvals=work.check.val, + desc=DCLIB found in getdynamicgolvals DISPLAY_VALUE response, + test=ANYVAL +) +%mp_assertcolvals(work.dynamic_values.element3, + checkvals=work.check.val, + desc=DCLIB found in getdynamicgolvals RAW_VALUE response, + test=ANYVAL +) diff --git a/sas/sasjs/services/editors/getdynamiccolvals.test.2.sas b/sas/sasjs/services/editors/getdynamiccolvals.test.2.sas new file mode 100644 index 0000000..5a56797 --- /dev/null +++ b/sas/sasjs/services/editors/getdynamiccolvals.test.2.sas @@ -0,0 +1,64 @@ +/** + @file + @brief testing getdynamiccolvals service + +

SAS Macros

+ @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + @li mx_testservice.sas + +**/ + +%let _program=&appLoc/services/editors/getdynamiccolvals; + +/** + * check extended values + */ + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'libds:$41. variable_nm:$32.'; + put "&dclib..MPE_TABLES,DSN"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + put 'LIBREF:$char8. DSN:$char16. NUM_OF_APPROVALS_REQUIRED:best. LOADTYPE:$char10. '@; + put 'BUSKEY:$char35. VAR_TXFROM:$char7. VAR_TXTO:$char5. VAR_BUSFROM:$char1. '@; + put 'VAR_BUSTO:$char1. VAR_PROCESSED:$char1. CLOSE_VARS:$char1. PRE_EDIT_HOOK:$char1. '@; + put 'POST_EDIT_HOOK:$char1. PRE_APPROVE_HOOK:$char1. POST_APPROVE_HOOK:$char1. '@; + put 'SIGNOFF_COLS:$char1. SIGNOFF_HOOK:$char1. NOTES:$char55. RK_UNDERLYING:$char1. '@; + put 'AUDIT_LIBDS:$char1. _____DELETE__THIS__RECORD_____:$char2.'; + put "&dclib,MPE_VALIDATIONS,14,TXTEMPORAL,BASE_LIB BASE_DS BASE_COL RULE_TYPE,TX_FROM"@; + put ',TX_TO, , , , , , , , ,,,Configuration of data quality rules in Editor component, , ,No'; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:sascontroltable &f2:source_row, + outlib=web2, + mdebug=&sasjs_mdebug +) + +data DYNAMIC_VALUES; + set web2.DYNAMIC_VALUES; + if _n_<2 then putlog (_all_)(=); +run; + +data DYNAMIC_EXTENDED_VALUES; + set web2.DYNAMIC_EXTENDED_VALUES; + if _n_<5 then putlog (_all_)(=); +run; + +data work.check; + val='VAR_PROCESSED';output; + val='VAR_TXFROM';output; + val='VAR_TXTO';output; + val='VAR_BUSFROM';output; + val='VAR_BUSTO';output; +run; +%mp_assertcolvals(work.DYNAMIC_EXTENDED_VALUES.element2, + checkvals=work.check.val, + desc=Correct values found in EXTRA_COL_NAME response, + test=ALLVALS +) diff --git a/sas/sasjs/services/editors/getlog.sas b/sas/sasjs/services/editors/getlog.sas new file mode 100644 index 0000000..a6a3bd4 --- /dev/null +++ b/sas/sasjs/services/editors/getlog.sas @@ -0,0 +1,74 @@ +/** + @file getlog.sas + @brief Downloads the submission, useful if there is an error + @details + +

SAS Macros

+ @li mf_verifymacvars.sas + @li mf_getuser.sas + @li mp_abort.sas + @li mp_dirlist.sas + @li mp_binarycopy.sas + @li mp_streamfile.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%mp_abort( + iftrue=(%mf_verifymacvars(table)=0) + ,mac=&_program + ,msg=%str(Missing: table) +) + +/* security checks */ +%let user=%mf_getuser(); +%let check_access=0; + +proc sql noprint; +select count(*) into: check_access from &mpelib..mpe_loads + where csv_dir="&table" and user_nm="&user"; + +%mp_abort(iftrue= (&check_access=0 ) + ,msg=%str(&user not authorised to download audit data for &table) + ,mac=mpestp_getlog.sas +) + + +ods package(ProdOutput) open nopf; + +options notes source2 mprint; +%mp_dirlist(outds=dirs, path=&mpelocapprovals/&TABLE) +data _null_; + set dirs; + if scan(filename,-1,'.') not in ('sas7bdat','wpd'); + retain str1 + "ods package(ProdOutput) add file='&mpelocapprovals/&TABLE/"; + retain str2 "' mimetype='text/plain' path='contents/';"; + call execute(cats(str1,filename,str2)); +run; + +%let archive_path=%sysfunc(pathname(work)); + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) +ods package(ProdOutput) publish archive properties + (archive_name= "&table..zip" archive_path="&archive_path"); + +ods package(ProdOutput) close; + +/* now serve zip file to client */ +%mp_streamfile(contenttype=ZIP + ,inloc=%str(&archive_path/&table..zip) + ,outname=&table..zip +) + +%mpeterm() diff --git a/sas/sasjs/services/editors/getsubmits.sas b/sas/sasjs/services/editors/getsubmits.sas new file mode 100644 index 0000000..65fd2e2 --- /dev/null +++ b/sas/sasjs/services/editors/getsubmits.sas @@ -0,0 +1,50 @@ +/** + @file getsubmits.sas + @brief Returns a list of staged data items that need to be approved + @details + +

SAS Macros

+ @li mp_abort.sas + @li mf_getuser.sas + @li mpeinit.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +PROC FORMAT; + picture yymmddhhmmss other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime); +RUN; + +proc sql noprint; +create table work.fromsas (rename=(SUBMITTED_ON=SUBMITTED_ON_DTTM)) as + select table_id + ,cats(base_lib,'.',base_ds) as base_table + ,input_vars + ,input_obs + ,submitted_by_nm + ,submitted_reason_txt + ,'DEPRECATED' as approve_group + ,submit_status_cd as review_status_id + ,reviewed_by_nm + ,reviewed_on_dttm + ,cats(put(SUBMITTED_ON_DTTM,yymmddhhmmss.)) as SUBMITTED_ON + from &mpelib..mpe_submit + where submitted_by_nm="%mf_getuser()" and submit_status_cd='SUBMITTED' + order by submitted_on_dttm desc; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(CLOSE) + diff --git a/sas/sasjs/services/editors/loadfile.sas b/sas/sasjs/services/editors/loadfile.sas new file mode 100644 index 0000000..d11ec30 --- /dev/null +++ b/sas/sasjs/services/editors/loadfile.sas @@ -0,0 +1,305 @@ +/** + @file loadfile.sas + @brief Loads a file + @details + +

SAS Macros

+ @li mddl_sas_cntlout.sas + @li mp_abort.sas + @li mf_getplatform.sas + @li mf_getuser.sas + @li mf_getvarlist.sas + @li mf_mkdir.sas + @li mf_verifymacvars.sas + @li mf_wordsinstr1butnotstr2.sas + @li dc_assignlib.sas + @li mpe_getgroups.sas + @li mp_lockfilecheck.sas + @li mpe_loader.sas + @li mp_cleancsv.sas + @li mp_binarycopy.sas + @li mpeinit.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%global table dlm; +%mpeinit(fetch=NO) + +%global _WEBIN_FILENAME1 _WEBIN_FILENAME2 + _WEBIN_FILEREF _WEBIN_FILEREF1 _WEBIN_FILEREF2; +%macro load(); +%if %mf_getplatform()=SASVIYA %then %do; + %global _webin_fileuri _webin_fileuri1 _webin_fileuri2; + %let _webin_fileuri1=%sysfunc(coalescec(&_webin_fileuri1,&_webin_fileuri)); + %if "&_webin_fileuri1" ne "" %then %do; + %put &=_webin_fileuri1; + filename sjfref1 filesrvc "&_webin_fileuri1"; + %let _WEBIN_FILEREF1=sjfref1; + %end; + %if "&_webin_fileuri2" ne "" %then %do; + %put &=_webin_fileuri2; + filename sjfref2 filesrvc "&_webin_fileuri2"; + %let _WEBIN_FILEREF2=sjfref2; + %end; +%end; +%mend load; +%load() + +%let _WEBIN_FILENAME1=%sysfunc(coalescec(&_WEBIN_FILENAME1,&_WEBIN_FILENAME)); +%let _WEBIN_FILEREF1=%sysfunc(coalescec(&_WEBIN_FILEREF1,&_WEBIN_FILEREF)); + +%let abort=0; +/* we do not know if the excel file will be first or second fileref */ +data _null_; + ext1=upcase(scan(symget('_WEBIN_FILENAME1'),-1,'.')); + ext2=upcase(scan(symget('_WEBIN_FILENAME2'),-1,'.')); + if ext1='CSV' then do; + csvname=symget('_WEBIN_FILENAME1'); + csvref=symget('_WEBIN_FILEREF1'); + xlsname=symget('_WEBIN_FILENAME2'); + xlsref=symget('_WEBIN_FILEREF2'); + end; + else if ext2='CSV' then do; + csvname=symget('_WEBIN_FILENAME2'); + csvref=symget('_WEBIN_FILEREF2'); + xlsname=symget('_WEBIN_FILENAME1'); + xlsref=symget('_WEBIN_FILEREF1'); + end; + else call symputx('abort',1); + + call symputx('csvname',csvname); + call symputx('csvref',csvref); + call symputx('xlsname',xlsname); + call symputx('xlsref',coalescec(xlsref,'0')); +run; + +%mp_abort(iftrue= (&abort=1) + ,mac=&_program + ,msg=%str(File "&csvname" or "&xlsname" must be a CSV! + (Comma separated with .csv extension)) +) + + +%let user=%mf_getuser(); + +%mp_abort( + iftrue=(%mf_verifymacvars(table)=0) + ,mac=&_program + ,msg=%str(Missing: table) +) + +%let table=%upcase(%trim(&table)); + +/* load parameters */ +data _null_; + libds=upcase(symget('table')); + call symputx('orig_libds',libds); + call symputx('orig_lib',scan(libds,1,'.')); + call symputx('orig_ds',scan(libds,2,'.')); + is_fmt=0; + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + libds='work.fmtextract'; + call symputx('libds',libds); + call execute('%mddl_sas_cntlout(libds=work.fmtextract)'); + is_fmt=1; + end; + else call symputx('libds',libds); + call symputx('is_fmt',is_fmt); + putlog (_all_)(=); +run; + +/* check that the user has the requisite access */ +%mpe_getgroups(user=&user,outds=groups) + +proc sql; +create table accesscheck as +select * from groups + where groupname="&mpeadmins" + or groupname in (select sas_group from &mpelib..mpe_security + where &dc_dttmtfmt. lt tx_to + and access_level="EDIT" + and ( + (libref="&orig_lib" and dsn="&orig_ds") + or (libref="&orig_lib" and dsn="*ALL*") + or (libref="*ALL*" and dsn="*ALL*") + or (libref="*ALL*" and dsn="&orig_ds") + )); +%let nobs=; +select count(*) into: nobs from &syslast; +%mp_abort(iftrue= (&nobs=0) + ,mac=&sysmacroname + ,msg=%str(&user not authorised to load &orig_libds per &mpelib..mpe_security) +) + +%dc_assignlib(WRITE,&orig_lib) + +%mp_abort(iftrue= (&syscc ge 4) + ,mac=loadfile + ,msg=%str(Issue assigning library &orig_lib) +) + +%global txfrom txto processed; + +data _null_; + set &mpelib..MPE_TABLES; + where libref="&orig_lib" and dsn="&orig_ds"; + call symputx('txfrom',var_txfrom); + call symputx('txto',var_txto); + call symputx('processed',var_processed); +run; + +%mp_lockfilecheck(libds=&orig_libds) + +data compare; + set &libds(drop=&txfrom &txto &processed); + stop; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc line 80) +) + +/* get line terminator, assume it's the first cr, lf, or crlf */ +data _null_; + length text $32767 term $4; + call missing (of _all_); + fid=fopen("&csvref",'I',32767,'b'); + rc=fread(fid); + rc2=fget(fid,text,32767); + cr=find(text,'0D'x ); + lf=find(text,'0A'x ); + crlf=find(text,'0D0A'x); + rc=fclose(fid); + if crlf>0 & cr0 & crlf0 & cr>0 & lf0 then term='LF'; + else term='CR'; + call symputx('termstr',term); +run; + +data _null_; + infile &csvref lrecl=32000 dsd termstr=&termstr; + input; + length incols_unsorted $32000 dlm $1; + incols_unsorted=compress(upcase(_infile_),"'"!!'"'); + /* dlm has length 1 so will be the first non alpha / digit char */ + /* expectation is that there will not be any crazy characters in first col! */ + dlm=compress(incols_unsorted,'_ ','ad'); + incols_unsorted=compress(incols_unsorted,dlm!!'_','kado'); + incols_unsorted=tranwrd(incols_unsorted,dlm,' '); + call symputx('incols_unsorted',incols_unsorted); + call symputx('dlm',dlm); + putlog incols_unsorted=; + putlog dlm=; + stop; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc line 99) +) + +%let basecols=%upcase(%mf_getvarlist(work.compare,dlm=%str( ))); + +%let missing_cols=%trim( + %mf_wordsInStr1ButNotStr2( + Str1=&basecols + ,Str2=&incols_unsorted + )); + +%let msg= + Expected cols: &basecols +
Received cols: &incols_unsorted +
Missing cols: &missing_cols +; +%mp_abort(iftrue= (%length(%trim(&missing_cols)) > 1 or &syscc ne 0) + ,mac=mpestp_loadfile.sas + ,msg=%superq(msg) +) +%let msg=0; + + + +PROC FORMAT; + picture yymmddhhmmss other='%0Y%0m%0d_%0H%0M%0S' (datatype=datetime); +RUN; + +/* create a dataset key (datetime plus 6 digit random number plus PID) */ +%let mperef=DC%left(%sysfunc(datetime(),B8601DT19.3))_%substr( + %sysfunc(ranuni(0)),3,6)_%substr(%str(&sysjobid ),1,4); + +/* Create package folder and redirect the log */ +%let dir=&mpelocapprovals/&mperef; +%mf_mkdir(&dir) + +/* clean embedded line breaks and force CRLF line endings */ +%mp_cleancsv(in=&csvref, out=&dir/&orig_libds..csv) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(issue in mp_cleancsv) +) + +%put; %put; %put log is being redirected; +%let url=_program=%substr(&_program + ,1,%length(&_program)-8)getlog%nrstr(&)table=&mperef; +%put to retrieve, visit this url:; %put;%put; +%put &url; +%put; + +/* proc printto log="&dir/weblog.txt";run; */ +libname approve "&dir"; + +options mprint; +%put &=mperef; +%put &=termstr; +%put &=dlm; + +%mpe_loader(mperef=&mperef + ,submitted_reason_txt=%quote(File upload: %superq(csvname)) + ,dlm=%superq(dlm) + ,url=%superq(url) + ,termstr=CRLF + ,dc_dttmtfmt=&dc_dttmtfmt +) +%mp_abort(mode=INCLUDE) + +%mp_abort( + iftrue= (%sysfunc(fileexist(%sysfunc(pathname(work))/mf_abort.error)) ne 0) + ,mac=&_program + ,msg=%nrstr(Problem occurred in &sysmacroname (mf_abort.error file found)) +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=mpestp_loadfile.sas + ,msg=%str(syscc=&syscc) +) + +filename outref "&dir/BKP_&xlsname"; +%mp_binarycopy(iftrue=("&xlsref" ne "0"),inref=&xlsref,outref=outref) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc when backing up source file &xlsname) +) + +data sasparams; + STATUS='SUCCESS'; + DSID="&mperef"; +run; + +%webout(OPEN) +%webout(OBJ,sasparams) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/editors/stagedata.sas b/sas/sasjs/services/editors/stagedata.sas new file mode 100755 index 0000000..f3ccee7 --- /dev/null +++ b/sas/sasjs/services/editors/stagedata.sas @@ -0,0 +1,277 @@ +/** + @file + @brief Sends a changeset to staging area + @details This is the service that is called when submitting a new edit. + +

Service Inputs

+
jsdata
+ This is the staged data table, plus an _____DELETE__THIS__RECORD_____ column + +
SASControlTable
+ + |ACTION:$char4.|MESSAGE:$char1.|LIBDS:$char19.| + |---|---|---| + |LOAD|User-Provided message|LIBREF.DATASET_NAME| + +

SAS Macros

+ @li mf_getuser.sas + @li mf_nobs.sas + @li dc_assignlib.sas + @li mf_verifymacvars.sas + @li mf_mkdir.sas + @li mf_getuniquefileref.sas + @li mpe_loader.sas + @li mpe_filtermaster.sas + @li mp_abort.sas + @li mp_binarycopy.sas + @li mp_cntlout.sas + @li mp_ds2csv.sas + @li mf_getplatform.sas + @li removecolsfromwork.sas + @li mpeinit.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%global approver; %let approver=; +%global libref; %let libref=; +%global dsn; %let dsn=; +%global user; %let user=; +%let user=%mf_getuser(); + +/* load parameters */ +data _null_; + set work.sascontroltable; + call symputx('action',action); + call symputx('message',message); + libds=upcase(libds); + call symputx('orig_libds',libds); + is_fmt=0; + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + libds='work.fmtextract'; + call symputx('libds',libds); + is_fmt=1; + end; + else call symputx('libds',libds); + call symputx('is_fmt',is_fmt); + putlog (_all_)(=); +run; + +%mp_cntlout( + iftrue=(&is_fmt=1) + ,libcat=&orig_libds + ,fmtlist=0 + ,cntlout=work.fmtextract +) + +/* stream back meta info, further jquery calls will return col metadata and + actual data */ +%let libref=%upcase(%scan(&libds,1,.)); +%let dsn=%upcase(%scan(&libds,2,.)); +%dc_assignlib(WRITE,&libref) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc - unable to assign library &libref) +) + +%mp_abort( + iftrue=(%mf_verifymacvars(mpelocapprovals libds)=0) + ,mac=&_program + ,msg=%str(Missing: mpelocapprovals libds) +) + +%put Verify that the upload does not violate Row Level Security checks:; +%mpe_filtermaster(ULOAD,&libds, + dclib=&mpelib, + outref=filtref, + outds=work.query +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc during filtering process) +) + +/* prepare inverse query */ +%let tempref=%mf_getuniquefileref(); +data _null_; + infile filtref end=eof; + file &tempref; + if _n_=1 then put 'where not('; + input; + put _infile_; + if eof then put ')'; +run; +/* apply the query */ +data work.badrecords; + set work.jsdata; + %inc &tempref/source2;; + putlog (_all_)(=); +run; +%mp_abort(iftrue= (%mf_nobs(work.badrecords)>0) + ,mac=&_program + ,msg=%str( + Security Problem - %mf_nobs(work.badrecords) unauthorised records submitted + ) +) + +PROC FORMAT; + picture yymmddhhmmss other='%0Y%0m%0d_%0H%0M%0S' (datatype=datetime); +RUN; + +/** + * Create package folder and redirect the log + */ + +/* create a dataset key (datetime plus 6 digit random number plus PID) */ +%let mperef=DC%left(%sysfunc(datetime(),B8601DT19.3))_%substr( + %sysfunc(ranuni(0)),3,6)_%substr(%str(&sysjobid ),1,4); + +/* get web url */ +%global url; +%let url=localhost/SASStoredProcess; +%let platform=%mf_getplatform(); +%put &=platform; +data _null_; + length url $128; + +%macro stagedata(); + %if &platform=SASVIYA %then %do; + if symexist('_baseurl') then do; + url=symget('_baseurl'); + if subpad(url,length(url)-9,9)='SASStudio' + then url=substr(url,1,length(url)-11); + else url="&systcpiphostname/SASJobExecution"; + end; + else url="&systcpiphostname/SASJobExecution"; + %end; + %else %if &platform=SASMETA %then %do; + rc=METADATA_GETURI("Stored Process Web App",url); + %end; +%mend stagedata; +%stagedata() + + call symputx('url',url); + putlog url=; +run; + +/* Create package folder */ +%let dir=&mpelocapprovals/&mperef; +%mf_mkdir(&dir) + +/* redirect the log */ +%put; %put; %put log is being redirected; +%put to retrieve, visit this url:; %put;%put; +%let url=&url?_program=%substr(&_program + ,1,%length(&_program)-9)getlog%str(&)table=&mperef; +%put &url; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc prior to log redirection) +) + +proc printto log="&dir/weblog.txt";run; +options notes mprint; +libname approve "&dir"; + +/* take copy of webin file */ + +data _null_; + if symexist('_WEBIN_FILEREF1') + then ref=symget('_WEBIN_FILEREF1'); + else if symexist('sasjs_tables') then do; + rc=filename('ref',"%sysfunc(pathname(work))/&dsn.csv"); + ref='ref'; + end; + else ref='indata1'; + call symputx('ref',ref); + putlog ref=; +run; + +%mp_binarycopy(inref=&ref, outloc="&dir/_WEBIN_FILEREF1.txt") + + +/* take copy of macvars */ +data _null_; + file "&dir/macvars.sas"; + set sashelp.vmacro; + where scope='GLOBAL'; + put '%let ' name '=' value ';'; +run; + +data approve.jsdset; + length _____DELETE__THIS__RECORD_____ $3; + set jsdata; +run; + +/** + * mf_getvarXXX functions will fail if the target is locked - so take a copy + * and reference that (this will also explicitly throw the lock situation) + */ +%let dscopy=work.dscopy; +data &dscopy; + set &libds; + stop; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Issue getting lock on &libds) +) + +%mp_ds2csv(approve.jsdset + ,dlm=COMMA + ,outfile="&dir/&orig_libds..csv" + ,outencoding="UTF-8" + ,headerformat=NAME + ,termstr=CRLF +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=&syscc when writing the CSV) +) + +%mpe_loader(mperef=&mperef + ,submitted_reason_txt=%superq(message) + ,approver=%quote(%trim(&approver)) + ,url=%superq(url) + ,dc_dttmtfmt=&dc_dttmtfmt +) +%mp_abort(mode=INCLUDE) + +%mp_abort( + iftrue=(%sysfunc(fileexist(%sysfunc(pathname(work))/mf_abort.error))=1) + ,mac=&_program..sas + ,msg=%str(mf_abort.error=1) +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +/* send relevant SUCCESS values */ +data sasparams; +STATUS='SUCCESS'; +DSID="&mperef"; +url="&url"; +run; + +%removecolsfromwork(___TMP___MD5) + +%webout(OPEN) +%webout(OBJ,sasparams) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/editors/stagedata.test.1.sas b/sas/sasjs/services/editors/stagedata.test.1.sas new file mode 100644 index 0000000..7111676 --- /dev/null +++ b/sas/sasjs/services/editors/stagedata.test.1.sas @@ -0,0 +1,61 @@ +/** + @file + @brief testing stagedata with row_level_security table + +

SAS Macros

+ @li mf_getuniquefileref.sas + @li mx_testservice.sas + @li mp_assert.sas + + +**/ + +%let _program=&appLoc/services/editors/stagedata; + +/** + * Test 1 - basic send + */ + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'ACTION:$char4. MESSAGE:$char40. LIBDS:$char38.'; + put "LOAD,Testing upload of RLS table,&dclib..MPE_ROW_LEVEL_SECURITY"; +run; + +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + x=round(ranuni(0)*100000,1); + y=cats(x); + z=cats('"',"'",x,"'",'"'); + put 'RLS_SCOPE:$char3. RLS_GROUP:$char9. RLS_LIBREF:$char8. '@; + put 'RLS_TABLE:$char32. RLS_GROUP_LOGIC:$char3. RLS_SUBGROUP_LOGIC:$char2. '@; + put 'RLS_SUBGROUP_ID:best. RLS_VARIABLE_NM:$char32. RLS_OPERATOR_NM:$char2. '@; + put 'RLS_RAW_VALUE:$char40. RLS_ACTIVE:best. _____DELETE__THIS__RECORD_____:$char2.'; + put "ALL,dcviewers,&dclib,MPE_ROW_LEVEL_SECURITY,AND,OR,0,RLS_ACTIVE,NE,"@; + put y ",0,No"; + put "ALL,SASAdministrators,&dclib,MPE_ROW_LEVEL_SECURITY,AND,OR,0,RLS_SCOPE,NE,"@; + put z ",0,No"; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:sascontroltable &f2:jsdata, + outlib=web1, + mdebug=&sasjs_mdebug +) + +%let status=0; +data work.sasparams; + set web1.sasparams; + putlog (_all_)(=); + if status='SUCCESS' then call symputx('status',1); +run; + + +%mp_assert( + iftrue=(&status=1), + desc=Checking successful submission of a two row RLS table, + outds=work.test_results +) + diff --git a/sas/sasjs/services/editors/stagedata.test.2.sas b/sas/sasjs/services/editors/stagedata.test.2.sas new file mode 100644 index 0000000..ba52dbf --- /dev/null +++ b/sas/sasjs/services/editors/stagedata.test.2.sas @@ -0,0 +1,50 @@ +/** + @file + @brief testing stagedata with format table + +

SAS Macros

+ @li mp_testservice.sas + @li mp_assert.sas + + +**/ + +%let _program=&appLoc/services/editors/stagedata; + +/** + * Test 1 - basic send + */ +data work.sascontroltable; + action='LOAD'; + MESSAGE='Testing upload of a format catalog'; + LIBDS="DCTEST.DCFMTS-FC"; +run; + +proc format lib=DCTEST.DCFMTS cntlout=work.fmtextract; +run; +data work.jsdata; + set work.fmtextract; + if _n_<5 then _____DELETE__THIS__RECORD_____='Yes'; + else _____DELETE__THIS__RECORD_____='No'; + if _n_>20 then stop; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.sascontroltable work.jsdata, + outlib=web1 +) + +%let status=0; +data work.sasparams; + set web1.sasparams; + putlog (_all_)(=); + if status='SUCCESS' then call symputx('status',1); +run; + +%mp_assert( + iftrue=(&status=1), + desc=Checking successful submission of a format catalog table, + outds=work.test_results +) + diff --git a/sas/sasjs/services/hooks/mpe_column_level_security_postedit.sas b/sas/sasjs/services/hooks/mpe_column_level_security_postedit.sas new file mode 100644 index 0000000..0f9e14c --- /dev/null +++ b/sas/sasjs/services/hooks/mpe_column_level_security_postedit.sas @@ -0,0 +1,45 @@ +/** + @file + @brief Post Edit Hook script for the MPE_COLUMN_LEVEL_SECURITY table + @details Post edit hooks provide additional backend validation for user + provided data. The incoming dataset is named `work.staging_ds` and is + provided in mpe_loader.sas. + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBREF - The library of the dataset being edited (is assigned) + @li DS - The dataset being edited + + This validation checks the incoming column_level_security settings to ensure + each individual filter is valid + + +**/ + +/* check scope values and ensure uppercasing */ +%let errflag=0; +%let errmsg=; +data work.staging_ds; + set work.staging_ds; + cls_scope=upcase(cls_scope); + CLS_LIBREF=upcase(CLS_LIBREF); + cls_table=upcase(CLS_TABLE); + CLS_VARIABLE_NM=upcase(CLS_VARIABLE_NM); + + if cls_scope not in ('ALL','VIEW','EDIT') then do; + call symputx('errflag',1); + call symputx('errmsg',"Invalid scope: "!!cls_scope); + stop; + end; + + if cls_hide<1 then cls_hide=0; + else cls_hide=1; + if CLS_ACTIVE<1 then CLS_ACTIVE=0; + else CLS_ACTIVE=1; + +run; + +%mp_abort(iftrue=(&errflag=1) + ,mac=mpe_column_level_security_postedit + ,msg=%superq(errmsg) +) diff --git a/sas/sasjs/services/hooks/mpe_row_level_security_postedit.sas b/sas/sasjs/services/hooks/mpe_row_level_security_postedit.sas new file mode 100644 index 0000000..8d10d0e --- /dev/null +++ b/sas/sasjs/services/hooks/mpe_row_level_security_postedit.sas @@ -0,0 +1,70 @@ +/** + @file + @brief Post Edit Hook script for the MPE_ROW_LEVEL_SECURITY table + @details Post edit hooks provide additional backend validation for user + provided data. The incoming dataset is named `work.staging_ds` and is + provided in mpe_loader.sas. + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBREF - The library of the dataset being edited (is assigned) + @li DS - The dataset being edited + + This validation checks the incoming row_level_security settings to ensure + each individual filter is + +

SAS Macros

+ @li dc_assignlib.sas + @li mp_filtercheck.sas + +

Related Macros

+ @li mpe_loader.sas + +**/ + + +/* ignore scope and group for validation */ +proc sql; +create table work.batches as + select distinct upcase(rls_libref) as rls_libref, + upcase(rls_table) as rls_table, + rls_group_logic as group_logic, + rls_subgroup_logic as subgroup_logic, + rls_subgroup_id as subgroup_id, + rls_variable_nm as variable_nm, + rls_operator_nm as operator_nm, + rls_raw_value as raw_value + from work.staging_ds + where rls_active=1 + order by rls_libref, rls_table; + +%let cnt=0; +data _null_; + set work.batches; + by rls_libref rls_table; + putlog (_all_)(=); + if last.rls_table then do; + x+1; + call symputx(cats('libds',x),cats(rls_libref,'.',rls_table)); + call symputx('cnt',x); + end; +run; + +%macro quickloop(); +%do i=1 %to &cnt; + data work.inds&i; + set work.batches; + if cats(rls_libref,'.',rls_table)="&&libds&i"; + keep group_logic subgroup_logic subgroup_id variable_nm operator_nm + raw_value; + run; + %dc_assignlib(READ,%scan(&&libds&i,1,.)) + %mp_filtercheck(work.inds&i + ,targetds=&&libds&i + ,outds=work.badrecords + ,abort=YES + ) +%end; +%mend quickloop; + +%quickloop() \ No newline at end of file diff --git a/sas/sasjs/services/hooks/mpe_tables_postedit.sas b/sas/sasjs/services/hooks/mpe_tables_postedit.sas new file mode 100644 index 0000000..69e2b26 --- /dev/null +++ b/sas/sasjs/services/hooks/mpe_tables_postedit.sas @@ -0,0 +1,89 @@ +/** + @file + @brief Post Edit Hook script for the MPE_TABLES table + @details Post edit hooks provide additional backend validation for user + provided data. The incoming dataset is named `work.staging_ds` and is + provided in mpe_loader.sas. + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBREF - The library of the dataset being edited (is assigned) + @li DS - The dataset being edited + + This validation checks MPE_TABLES to ensure modified / added records are + valid. If a non-default AUDIT_LIBDS is being used, there is also a check + to ensure that this table already exists. + + +**/ + +%let errmsg=; +%let errflag=0; + +/* ensure uppercasing */ +data work.staging_ds; + set work.staging_ds; + LIBREF=upcase(LIBREF); + DSN=upcase(DSN); + loadtype=upcase(loadtype); + buskey=upcase(buskey); + var_txfrom=upcase(var_txfrom); + var_txto=upcase(var_txto); + var_busfrom=upcase(var_busfrom); + var_busto=upcase(var_busto); + var_processed=upcase(var_processed); + close_vars=upcase(close_vars); + audit_libds=upcase(audit_libds); + + /* check for valid loadtype */ + if LOADTYPE not in ('UPDATE','TXTEMPORAL','FORMAT_CAT','BITEMPORAL','REPLACE') + then do; + call symputx('errmsg',"Invalid LOADTYPE: "!!LOADTYPE); + call symputx('errflag',1); + end; + + /* force correct BUSKEY and DSN when loading format catalogs */ + if LOADTYPE='FORMAT_CAT' then do; + BUSKEY='TYPE FMTNAME FMTROW'; + if subpad(dsn,length(dsn)-3,3) ne '-FC' then dsn=cats(dsn,'-FC'); + end; +run; + +%mp_abort(iftrue=(&errflag=1) + ,mac=mpe_tables_postedit + ,msg=%superq(errmsg) +) + +/* get distinct list of audit libs */ +proc sql; +create table work.liblist as + select distinct audit_libds + from work.staging_ds + where audit_libds not in ('','0', "&dc_libref..MPE_AUDIT") + and upcase(_____DELETE__THIS__RECORD_____) ne "YES"; + +/* assign the libs */ +data _null_; + set work.liblist; + call symputx(cats('lib',_n_),audit_libds); + libref=scan(audit_libds,1,'.'); + call execute('%dc_assignlib(WRITE,'!!libref!!')'); +run; + +/* check the audit tables exist */ +data _null_; + set work.liblist; + + if exist(audit_libds,"DATA")=0 then do; + call symputx('errmsg', + "Audit Table "!!audit_libds!!" does not exist, or could not be assigned." + ); + call symputx('errflag',1); + end; +run; + +%mp_abort(iftrue=(&errflag=1) + ,mac=mpe_tables_postedit + ,msg=%superq(errmsg) +) + diff --git a/sas/sasjs/services/hooks/mpe_validations_postedit.sas b/sas/sasjs/services/hooks/mpe_validations_postedit.sas new file mode 100644 index 0000000..8d7ff3c --- /dev/null +++ b/sas/sasjs/services/hooks/mpe_validations_postedit.sas @@ -0,0 +1,72 @@ +/** + @file + @brief Post Edit Hook script for the MPE_VALIDATIONS table + @details Post edit hooks provide additional backend validation for user + provided data. The incoming dataset is named `work.staging_ds` and is + provided in mpe_loader.sas. + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBREF - The library of the dataset being edited (is assigned) + @li DS - The dataset being edited + + This validation checks the incoming mpe_validations settings to ensure + there are no columns that have both HARDSELECT_HOOK and SOFTSELECT_HOOK. + +

SAS Macros

+ @li mf_nobs.sas + +

Related Macros

+ @li mpe_loader.sas + +**/ + + +/** check to avoid a colum having both HARDSELECT_HOOK and SOFTSELECT_HOOK */ +/* need to merge with base table in the case of a single row being added */ +%global src_list1 src_list2; +%let src_list1=''; +proc sql noprint; +create table work.check1 as + select quote(catx('.',base_lib,base_ds,base_col)) as source + ,rule_type + from work.staging_ds + where rule_type in ('SOFTSELECT_HOOK','HARDSELECT_HOOK') + and upcase(_____DELETE__THIS__RECORD_____) ne "YES"; + +select distinct cats(source) into: src_list1 separated by ',' + from work.check1; + +create table work.check2 as + select quote(catx('.',base_lib,base_ds,base_col)) as source + ,rule_type + from &DC_LIBREF..MPE_VALIDATIONS + where rule_type in ('SOFTSELECT_HOOK','HARDSELECT_HOOK') + and &dc_dttmtfmt. lt tx_to + and catx('.',base_lib,base_ds,base_col) in (&src_list1); + +create table work.check3 as + select * from work.check1 +union + select * from work.check2; + +create table work.validation_checker as + select source + ,count(*) as cnt + from work.check3 + group by 1 + having cnt>1; + +select distinct source into: src_list2 from work.validation_checker; + +data _null_; + set work.validation_checker; + putlog (_all_)(=); +run; + + +%mp_abort(iftrue= (%mf_nobs(work.validation_checker)>0) + ,mac=mpe_validations_postedit + ,msg=%str(The following vars have duplicate HOOKS: &src_list2) +) + diff --git a/sas/sasjs/services/public/getchangeinfo.sas b/sas/sasjs/services/public/getchangeinfo.sas new file mode 100644 index 0000000..63a47eb --- /dev/null +++ b/sas/sasjs/services/public/getchangeinfo.sas @@ -0,0 +1,57 @@ +/** + @file getchangeinfo.sas + @brief Returns the details for an approval diff + @details + +

SAS Macros

+ @li mf_getengine.sas + @li dc_assignlib.sas + @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%let table=; +data _null_; + set SASControlTable; + call symputx('table',table); +run; + +%dc_assignlib(WRITE,%scan(&table,1,.)) + +%let max_ver_dttm=0; + +data APPROVE1; + set &mpelib..mpe_submit + (rename=(SUBMITTED_ON_DTTM=submitted_on REVIEWED_ON_DTTM=REVIEWED_ON)); + where TABLE_ID="&TABLE"; + TABLE_NM=cats(base_lib,'.',base_ds); + BASE_TABLE=table_nm; + call symputx('base_lib',base_lib); + REVIEWED_ON_DTTM=put(reviewed_on,datetime19.); + SUBMITTED_ON_DTTM=put(submitted_on,datetime19.); +run; + +data jsParams; + set approve1; + LIB_ENGINE="%mf_getEngine(&base_lib)"; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,jsParams) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/public/getcols.sas b/sas/sasjs/services/public/getcols.sas new file mode 100644 index 0000000..1636652 --- /dev/null +++ b/sas/sasjs/services/public/getcols.sas @@ -0,0 +1,62 @@ +/** + @file getcols.sas + @brief Retrieves column info to enable population of dropdowns + @details + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_getvalue.sas + @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%mpeinit() + + +%let ds=%mf_getvalue(work.iwant,libds); +%dc_assignlib(READ,%scan(&ds,1,.)) + +proc contents noprint data=&ds + out=droplist1 (keep=name type length label varnum format:); +run; +data cols(keep=name type length varnum format label); + set droplist1(rename=(format=format2 type=type2)); + name=upcase(name); + if type2=2 then do; + length format $49.; + if format2='' then format=cats('$',length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else format=cats(format2,formatl,'.'); + type='C'; + ddtype='CHARACTER'; + end; + else do; + if format2='' then format=cats(length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else if formatd=0 then format=cats(format2,formatl,'.'); + else format=cats(format2,formatl,'.',formatd); + type='N'; + if format=:'DATETIME' then ddtype='DATETIME'; + else if format=:'DATE' then ddtype='DATE'; + else if format=:'TIME' then ddtype='TIME'; + else ddtype='NUMERIC'; + end; + if label='' then label=name; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,cols) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/public/getcolvals.sas b/sas/sasjs/services/public/getcolvals.sas new file mode 100644 index 0000000..0a6e738 --- /dev/null +++ b/sas/sasjs/services/public/getcolvals.sas @@ -0,0 +1,183 @@ +/** + @file + @brief Retrieves column info to enable population of dropdowns + @details An optional filterquery may be provided, if so then it is validated + and then used to filter the subsequent results. + +

Service Inputs

+ +
IWANT
+ + The STARTROW and ROWS variables are used to fetch additional values beyond + the initial default (4000). + + |libds:$19.|col:$9.|STARTROW:8.|ROWS:8.| + |---|---|---|---| + |DC258467.MPE_X_TEST|SOME_TIME|4001|1000 + +
FILTERQUERY
+ |GROUP_LOGIC:$3|SUBGROUP_LOGIC:$3|SUBGROUP_ID:8.|VARIABLE_NM:$32|OPERATOR_NM:$10|RAW_VALUE:$32767| + |---|---|---|---|---|---| + |AND|AND|1|SOME_BESTNUM|>|1| + |AND|AND|1|SOME_TIME|=|77333| + +

Service Outputs

+
VALS
+ The type of this column actually depends on the underlying column type, so it can change + |FORMATTED|UNFORMATTED| + |---|---| + |$44.00|44| + +
META
+ |COLUMN:$32.|SASFORMAT:$32.|STARTROW:8.|ROWS:8.| + |---|---|---|---| + |COL_NAME|DOLLAR8.2|4001|1000 + +

SAS Macros

+ @li mf_existds.sas + @li mf_getvalue.sas + @li mf_verifymacvars.sas + @li dc_assignlib.sas + @li mf_getvarformat.sas + @li mp_abort.sas + @li mp_cntlout.sas + @li mp_filtercheck.sas + @li mp_filtergenerate.sas + + @version 9.2 + @author 4GL Apps Ltd. + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%mpeinit() + +/* input table may or may not exist */ +data work.initvars; + length GROUP_LOGIC $3 SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32 + OPERATOR_NM $10 RAW_VALUE $32767; + call missing(of _all_); + stop; +data work.filterquery; + set %sysfunc(ifc( + %mf_existds(work.filterquery)=1 + ,work.filterquery + ,work.initvars + )); +run; + +/* print data for debugging */ +data _null_; + set work.iwant; + put (_all_)(=); +run; +data _null_; + set work.filterquery; + put (_all_)(=); +run; + +%let libds=%mf_getvalue(work.iwant,libds); +%let col2=%mf_getvalue(work.iwant,col); +%let is_fmt=0; +%let startrow=1; +%let rows=4000; + +%put &=libds; +%put &=col2; + +%mp_abort(iftrue= (%mf_verifymacvars(libds col2)=0) + ,mac=&_program..sas + ,msg=%str(Missing inputs from iwant. Libds=&libds col=&col2 ) +) + +%dc_assignlib(WRITE,%scan(&libds,1,.)) + +data _null_; + call missing(startrow,rows); + set work.iwant; + /* check if the request is for a format catalog */ + call symputx('orig_libds',libds); + is_fmt=0; + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + call symputx('libds','work.fmtextract'); + is_fmt=1; + end; + call symputx('is_fmt',is_fmt); + call symputx('startrow',coalesce(startrow,&startrow)); + call symputx('rows',coalesce(rows,&rows)); + putlog (_all_)(=); +run; + +%mp_cntlout( + iftrue=(&is_fmt=1) + ,libcat=&orig_libds + ,fmtlist=0 + ,cntlout=work.fmtextract +) + + +/** + * Validate the filter query + */ +%mp_filtercheck(work.filterquery,targetds=&libds,abort=YES) + +/** + * Prepare the query + */ +%mp_filtergenerate(work.filterquery,outref=myfilter) + +/* cannot %inc in a sql where clause, only data step, so - use a view */ +data work.vw_vals/view=work.vw_vals; + set &libds; + where %inc myfilter;; +run; + +proc sql; +create view work.vw_vals_sorted as + select distinct + put(&col2,%mf_getVarFormat(&libds,&col2,force=1)) as formatted, + &col2 as unformatted + from work.vw_vals; + +/* restrict num of output values */ +data work.vals; + set work.vw_vals_sorted; + if _n_ ge &startrow; + x+1; + if x>&rows then stop; + drop x; +run; + +data vals; + /* ensure empty value if table is empty, for dropdowns */ + if nobs=0 then output; + set vals nobs=nobs; + format unformatted ; + output; +run; + +proc sql noprint; +select count(*) into: nobs from work.vw_vals_sorted; +data meta; + column="&col2"; + sasformat="%mf_getVarFormat(&libds,&col2)"; + startrow=&startrow; + rows=&rows; + nobs=&nobs; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,vals,missing=STRING,showmeta=YES) +%webout(OBJ,meta) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/public/getcolvals.test.1.sas b/sas/sasjs/services/public/getcolvals.test.1.sas new file mode 100644 index 0000000..b19a73d --- /dev/null +++ b/sas/sasjs/services/public/getcolvals.test.1.sas @@ -0,0 +1,37 @@ +/** + @file + @brief testing getcolvals service + +

SAS Macros

+ @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + +**/ + +%let _program=&appLoc/services/public/getcolvals; + +%let f3=%mf_getuniquefileref(); +data _null_; + file &f3 termstr=crlf; + put 'LIBDS:$43. COL:$32.'; + put "&dclib..MPE_X_TEST,SOME_TIME"; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f3:iwant, + outlib=web3 +) + +data work.vals; + set web3.vals; + putlog (_all_)(=); +run; +data work.check; + val=1;output; + val=2;output; +run; +%mp_assertcolvals(work.vals.unformatted, + checkvals=work.check.val, + desc=DCLIB found in unfiltered getgolvals response, + test=ANYVAL +) diff --git a/sas/sasjs/services/public/getcolvals.test.2.sas b/sas/sasjs/services/public/getcolvals.test.2.sas new file mode 100644 index 0000000..90efb5e --- /dev/null +++ b/sas/sasjs/services/public/getcolvals.test.2.sas @@ -0,0 +1,56 @@ +/** + @file + @brief testing getcolvals service + +

SAS Macros

+ @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + +**/ + +%let _program=&appLoc/services/public/getcolvals; + +%let f1=%mf_getuniquefileref(); +%let f2=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'LIBDS:$43. COL:$32.'; + put "&dclib..MPE_TABLES,LOADTYPE"; +run; +data _null_; + file &f2 termstr=crlf; + infile datalines4 dsd; + input; + if _n_=1 then do; + put 'GROUP_LOGIC:$char3. SUBGROUP_LOGIC:$char3. SUBGROUP_ID:8. '@; + put 'VARIABLE_NM:$char32. OPERATOR_NM:$char10. RAW_VALUE:$char4000.'; + end; + put _infile_; + putlog _infile_; +datalines4; +AND,OR,1,LIBREF,CONTAINS,"'DC'" +AND,OR,1,LIBREF,CONTAINS,"'VIYA'" +AND,OR,2,DSN,=,"'MPE_LOCK_ANYTABLE'" +AND,OR,2,DSN,=,"'MPE_X_TEST'" +;;;; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:iwant &f2:filterquery, + outlib=web2 +) + +data work.vals2; + set web2.vals; + putlog (_all_)(=); +run; + +data work.check; + type='UPDATE'; output; +run; +%mp_assertcolvals(work.vals2.unformatted, + checkvals=work.check.type, + desc=Checking loadtype for DCLIB in MPE_TABLES, + test=ALLVALS +) + diff --git a/sas/sasjs/services/public/getcolvals.test.3.sas b/sas/sasjs/services/public/getcolvals.test.3.sas new file mode 100644 index 0000000..cd9c5dc --- /dev/null +++ b/sas/sasjs/services/public/getcolvals.test.3.sas @@ -0,0 +1,53 @@ +/** + @file + @brief testing getcolvals service with FORMATS + +

SAS Macros

+ @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + +**/ + +%let _program=&appLoc/services/public/getcolvals; + + +data work.iwant; + LIBDS="DCTEST.DCFMTS-FC"; + COL="FMTNAME"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + infile datalines4 dsd; + input; + if _n_=1 then do; + put 'GROUP_LOGIC:$char3. SUBGROUP_LOGIC:$char3. SUBGROUP_ID:8. '@; + put 'VARIABLE_NM:$char32. OPERATOR_NM:$char10. RAW_VALUE:$char4000.'; + end; + put _infile_; + putlog _infile_; +datalines4; +AND,OR,1,FMTNAME,CONTAINS,"'MOR'" +;;;; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f2:filterquery, + inputdatasets=work.iwant, + outlib=web2 +) + +data work.vals2; + set web2.vals; + putlog (_all_)(=); +run; + +data work.check; + type='MORDOR'; output; +run; +%mp_assertcolvals(work.vals2.unformatted, + checkvals=work.check.type, + desc=Checking fmtname for filtered format query(DCTEST.DCFMTS-FC), + test=ALLVALS +) + diff --git a/sas/sasjs/services/public/getcolvals.test.sas b/sas/sasjs/services/public/getcolvals.test.sas new file mode 100644 index 0000000..e2a6043 --- /dev/null +++ b/sas/sasjs/services/public/getcolvals.test.sas @@ -0,0 +1,38 @@ +/** + @file + @brief testing gethistory service + +

SAS Macros

+ @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + +**/ + +%let _program=&appLoc/services/public/getcolvals; + +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'LIBDS:$43. COL:$32.'; + put "&dclib..MPE_TABLES,LIBREF"; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:iwant, + outlib=web1 +) + +data work.vals1; + set web1.vals; + putlog (_all_)(=); +run; + + +data work.check; + val="&dclib"; +run; +%mp_assertcolvals(work.vals1.unformatted, + checkvals=work.check.val, + desc=DCLIB found in unfiltered getgolvals response, + test=ANYVAL +) diff --git a/sas/sasjs/services/public/getddl.sas b/sas/sasjs/services/public/getddl.sas new file mode 100644 index 0000000..a7574b8 --- /dev/null +++ b/sas/sasjs/services/public/getddl.sas @@ -0,0 +1,55 @@ +/** + @file + @brief Download DDL for a table or entire library in a particular flavour. + @details + +

SAS Macros

+ @li mddl_sas_cntlout.sas + @li dc_assignlib.sas + @li mf_existds.sas + @li mp_abort.sas + @li mp_getddl.sas + @li mp_streamfile.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%global libref ds flavour; + +%let flavour=%sysfunc(coalescec(&flavour,SAS)); + +%mpeinit() + +%dc_assignlib(READ,&libref) + +data _null_; + /* check if the request is for a format catalog */ + ds=symget('ds'); + if subpad(cats(reverse(ds)),1,3)=:'CF-' then do; + ds=scan(ds,1,'-'); + libds=cats(symget('libref'),'.',ds); + putlog "Format Catalog Captured"; + call execute('%mddl_sas_cntlout(libds=work.fmtextract)'); + call symputx('libref','work'); + call symputx('ds','fmtextract'); + end; + putlog (_all_)(=); +run; + +%mp_abort(iftrue=("exist&ds" ne "exist" and %mf_existds(libds=&libref..&ds)<1) + ,mac=&_program + ,msg=%str(Dataset &libref..&ds was not found) +) + +%let tmploc=%sysfunc(pathname(work))/temp.txt; +filename tmp "&tmploc"; +%mp_getddl(&libref,&ds,flavour=&flavour, fref=tmp, applydttm=YES) + +%mp_streamfile(contenttype=TEXT + ,inloc=%str(&tmploc) + ,outname=&libref._&ds..ddl +) diff --git a/sas/sasjs/services/public/getddl.test.sas b/sas/sasjs/services/public/getddl.test.sas new file mode 100644 index 0000000..c2907fe --- /dev/null +++ b/sas/sasjs/services/public/getddl.test.sas @@ -0,0 +1,81 @@ +/** + @file + @brief testing getddl service + +

SAS Macros

+ @li mp_assertdsobs.sas + @li mx_testservice.sas + +**/ + + +%let _program=&appLoc/services/public/getddl; + +/* test 1 */ +data work.params; + length name $32 value $1000; + name='libref';value="&dclib";output; + name='ds';value='';output; + name='flavour';value='TSQL';output; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputparams=work.params, + outref=webout, + viyaresult=WEBOUT_TXT, + mdebug=&sasjs_mdebug +) + +data work.results; + infile webout; + input; + putlog _infile_; + if _n_=2 then do; + if _infile_=:'/* TSQL Flavour DDL for' then do; + putlog 'test passed'; + output; + output; + end; + stop; + end; + else if _n_>2 then stop; +run; + +%mp_assertdsobs(work.results, + desc=DDL file is successfully returned, + test=EQUALS 2, + outds=work.test_results +) + +/* test 2 - format catalog */ +data work.params; + length name $32 value $1000; + name='libref';value="DCTEST";output; + name='ds';value='DCFMTS-FC';output; +run; +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputparams=work.params, + outref=web2, + viyaresult=WEBOUT_TXT, + mdebug=&sasjs_mdebug +) + +data work.results2; + infile web2; + input; + putlog _infile_; + if index(upcase(_infile_),'WORK.FMTEXTRACT') then do; + putlog 'test passed'; + output; + output; + stop; + end; + else if _n_>50 then stop; +run; + +%mp_assertdsobs(work.results2, + desc=DDL file is successfully returned from format catalog, + test=EQUALS 2, + outds=work.test_results +) diff --git a/sas/sasjs/services/public/getgroups.sas b/sas/sasjs/services/public/getgroups.sas new file mode 100644 index 0000000..7e605f7 --- /dev/null +++ b/sas/sasjs/services/public/getgroups.sas @@ -0,0 +1,30 @@ +/** + @file getgroups.sas + @brief List all SAS Groups + @details Gets a list of all SAS Groups. Runs without mpeinit() so that it + can be available to the sasjs/server configurator + +

SAS Macros

+ @li dc_getgroups.sas + +

Data Outputs

+
groups
+ |NAME:$32.|DESCRIPTION:$64.|GROUPID:best.| + |---|---|---| + |`SomeGroup `|`A group `|`1`| + |`Another Group`|`this is a different group`|`2`| + |`admin`|`Administrators `|`3`| + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%dc_getgroups(outds=groups) + +%webout(OPEN) +%webout(OBJ,groups) +%webout(CLOSE) + diff --git a/sas/sasjs/services/public/getgroups.test.sas b/sas/sasjs/services/public/getgroups.test.sas new file mode 100644 index 0000000..055acd5 --- /dev/null +++ b/sas/sasjs/services/public/getgroups.test.sas @@ -0,0 +1,33 @@ +/** + @file + @brief testing getgroups service. + +

SAS Macros

+ @li mf_getuser.sas + @li mp_assertcols.sas + @li mp_testservice.sas + +**/ + +%let _program=&appLoc/services/public/getgroups; + +/* add user */ +%put &=sasjs_mdebug; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + outlib=webout, + mdebug=1, + debug=131 +) + + +data work.return; + set webout.groups; + putlog (_all_)(=); +run; + +%mp_assertcols(work.return, + cols=groupuri groupname groupdesc, + test=ALL +) + diff --git a/sas/sasjs/services/public/getrawdata.sas b/sas/sasjs/services/public/getrawdata.sas new file mode 100644 index 0000000..158568c --- /dev/null +++ b/sas/sasjs/services/public/getrawdata.sas @@ -0,0 +1,175 @@ +/** + @file + @brief Downloads data in a variety of formats + @details To enable direct download, this service runs in a dedicated stream + as a GET request using URL parameters as inputs. + + The inputs are: + + @li table - the libds of the table to be downloaded + @li type - either SAS, CSV, EXCEL, MARKDOWN, WEBCSV or WEBTAB + @li filter - the filter RK if used + +

SAS Macros

+ @li mf_verifymacvars.sas + @li mf_getuser.sas + @li mf_existfeature.sas + @li dc_assignlib.sas + @li mp_ds2cards.sas + @li mp_abort.sas + @li mp_binarycopy.sas + @li mp_cntlout.sas + @li mp_streamfile.sas + @li mpe_filtermaster.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%global table type filter ds format is_fmt txfrom txto; +%mpeinit() + +%let user=%mf_getuser(); +%let is_fmt=0; + +%mp_abort(iftrue= (%mf_verifymacvars(type table)=0) + ,mac=&_program..sas + ,msg=%str(Invalid inputs: type table) +) + +%let libds=%upcase(&table); /* actual source */ +%let table=%upcase(&table); /* used as label for fmt catalogs */ +%let lib=%scan(&table,1,.); +%let ds=%scan(&table,2,.); +%dc_assignlib(READ,&lib) + +data _null_; + set &mpelib..MPE_TABLES; + where upcase(libref)="&lib" and upcase(dsn)="&ds"; + + /* if a TXTEMPORAL table then filter as such */ + call symputx('txfrom',var_txfrom); + call symputx('txto',var_txto); + + ds=symget('ds'); + is_fmt=0; + if subpad(cats(reverse(ds)),1,3)=:'CF-' then do; + ds=scan(ds,1,'-'); + table=cats("&lib..",ds); + putlog "Format Catalog Captured"; + is_fmt=1; + call symputx('libds','work.fmtextract'); + call symputx('table',table); + end; + call symputx('is_fmt',is_fmt); + putlog (_all_)(=); +run; + +%mp_cntlout( + iftrue=(&is_fmt=1) + ,libcat=&table + ,fmtlist=0 + ,cntlout=work.fmtextract +) + +%put preparing query; +%mpe_filtermaster(DLOAD,&libds, + dclib=&mpelib, + filter_rk=&filter, + outref=filtref, + outds=work.query +) +%put printing generated filterquery:; +data _null_; + infile filtref; + input; + putlog _infile_; +run; + +options obs=200000;/* stop limit */ +data staged(drop=&txfrom &txto); + set &libds; + where %inc filtref;; +run; +options obs=max; + +options validvarname=upcase; + +%macro mpestp_getrawdata(); + %local outfile; + %if &type=SAS %then %do; + %let outfile=%sysfunc(pathname(work))/&table..sas; + %mp_ds2cards(base_ds=staged + , tgt_ds=&table + , cards_file= "&outfile" + , maxobs=100000) + %let ext=sas; + %let mimetype=text; + %end; + %else %if &type=CSV or (&type=EXCEL and %mf_existfeature(EXPORTXLS) ne 1) + /* cannot proc export excel if PC Files is not licensed */ + %then %do; + %let outfile=%sysfunc(pathname(work))/&table..csv; + PROC EXPORT DATA= staged + OUTFILE= "&outfile" + DBMS=csv REPLACE; + RUN; + %let ext=csv; + %let mimetype=csv; + %end; + %else %if &type=EXCEL %then %do; + %let ext=xlsx; + %let outfile=%sysfunc(pathname(work))/&table..&ext; + PROC EXPORT DATA= staged + OUTFILE= "&outfile" + DBMS=xlsx ; + RUN; + %let mimetype=XLSX; + %end; + %else %if &type=MARKDOWN %then %do; + %let ext=md; + %let outfile=%sysfunc(pathname(work))/&table..&ext; + filename mdref "&outfile" lrecl=32767; + + %mp_ds2md(staged,outref=mdref,showlog=NO) + + %let mimetype=MARKDOWN; + %end; + %else %if &type=WEBCSV %then %do; + PROC EXPORT DATA= staged + OUTFILE= _webout + DBMS=csv REPLACE; + RUN; + /* don't set headers */ + %return; + %end; + %else %if &type=WEBTAB %then %do; + PROC EXPORT DATA= staged + OUTFILE= _webout + DBMS=tab REPLACE; + RUN; + /* don't set headers */ + %return; + %end; + %else %do; + %mp_abort(msg=type &type not supported,mac=mpestp_getrawdata.sas); + %end; + + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) + ) + + %mp_streamfile(contenttype=&mimetype + ,inloc=%str(&outfile) + ,outname=&table..&ext + ) + +%mend mpestp_getrawdata; +%mpestp_getrawdata() + +%mpeterm() diff --git a/sas/sasjs/services/public/getrawdata.test.sas b/sas/sasjs/services/public/getrawdata.test.sas new file mode 100644 index 0000000..0210929 --- /dev/null +++ b/sas/sasjs/services/public/getrawdata.test.sas @@ -0,0 +1,78 @@ +/** + @file + @brief testing getrawdata service + +

SAS Macros

+ @li mp_assertdsobs.sas + @li mx_testservice.sas + +**/ + + +%let _program=&appLoc/services/public/getrawdata; + +/* test1 - regular table */ +data work.params; + length name $32 value $1000; + name='type';value='CSV';output; + name='table';value="&dclib..MPE_X_TEST";output; + name='filter';value='0';output; +run; + +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputparams=work.params, + outref=webout, + viyaresult=WEBOUT_TXT, + mdebug=&sasjs_mdebug +) + +data work.results; + infile webout; + input; + if _infile_=:'PRIMARY_KEY_FIELD,SOME_CHAR' then do; + output; + output; + stop; + end; +run; + +%mp_assertdsobs(work.results, + desc=CSV file is successfully returned, + test=EQUALS 2, + outds=work.test_results +) + +/* test 2 - format table */ +data work.params2; + length name $32 value $1000; + name='type';value='SAS';output; + name='table';value="DCTEST.DCFMTS-FC";output; + name='filter';value='0';output; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputparams=work.params2, + outref=web2, + viyaresult=WEBOUT_TXT +) + +data work.results2; + infile web2; + input; + putlog _infile_; + if _infile_=:'datalines4;' then do; + output; + output; + output; + stop; + end; + if _n_>100 then stop; +run; + +%mp_assertdsobs(work.results2, + desc=datalines file is successfully returned for format catalog, + test=EQUALS 3, + outds=work.test_results +) diff --git a/sas/sasjs/services/public/refreshlibinfo.sas b/sas/sasjs/services/public/refreshlibinfo.sas new file mode 100644 index 0000000..b971b29 --- /dev/null +++ b/sas/sasjs/services/public/refreshlibinfo.sas @@ -0,0 +1,85 @@ +/** + @file refreshlibinfo.sas + @brief Refresh the Data Catalog for a particular library + @details When showing library info in the VIEW menu, the data is taken from + the Data Catalog tables. These may be empty or outdated, and so this service + allows end users to run a refresh of the data. + +

Service Inputs

+
lib2refresh
+ Should contain the libref to be refreshed. + |libref:$8.| + |---| + |SOMELIB| + +

Service Outputs

+ +
libinfo
+ + |engine $|libname $|paths $|perms $|owners $|schemas $ |libid $|libsize $|table_cnt | + |---|---|---|---|---|---|---|---|---| + |V9|SOMELIB|"some/path"|rwxrwxr-x|sassrv|` `|` `|636MB|33| + +

SAS Macros

+ @li dc_assignlib.sas + @li dc_refreshcatalog.sas + @li mp_abort.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + + +%mpeinit() + +%webout(FETCH) + +%mp_abort(iftrue= (&syscc ne 0) + ,msg=%str(syscc=&syscc Problem on startup) +) + +%let libref=; +data _null_; + set work.lib2refresh; + call symputx('libref',libref); +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,msg=%str(syscc=&syscc Problem with inputs - was lib2refresh object sent?) +) + +%dc_assignlib(WRITE,&libref) + +%mp_abort(iftrue= (&syscc ne 0) + ,msg=%str(syscc=&syscc after lib assignment) +) + +%dc_refreshcatalog(&libref) + +%mp_abort(iftrue= (&syscc ne 0) + ,msg=%str(syscc=&syscc Problem when running the catalog refresh) +) + +/* get libinfo */ +proc sql; +create table work.libinfo as + select a.engine, + a.libname, + a.paths, + a.perms, + a.owners, + a.schemas, + a.libid, + b.libsize, + b.table_cnt + from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a + inner join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b + on a.libref=b.libref + where a.libref="&libref"; + +%webout(OPEN) +%webout(OBJ,libinfo) +%webout(CLOSE) diff --git a/sas/sasjs/services/public/refreshlibinfo.test.sas b/sas/sasjs/services/public/refreshlibinfo.test.sas new file mode 100644 index 0000000..d396e28 --- /dev/null +++ b/sas/sasjs/services/public/refreshlibinfo.test.sas @@ -0,0 +1,40 @@ +/** + @file + @brief testing public/refreshlibinfo service + +

SAS Macros

+ @li mp_assert.sas + @li mx_testservice.sas + +

Related Programs

+ @li refreshlibinfo.sas + +**/ + +%let _program=&appLoc/services/public/refreshlibinfo; + +data work.lib2refresh; + libref="&dclib"; +run; + +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.lib2refresh, + outlib=web1, + mdebug=&sasjs_mdebug +) + +%let libref=0; +data work.libinfo; + set web1.libinfo; + putlog (_all_)(=); + call symputx('libref',libref); +run; + +%mp_assert( + iftrue=(&libref=&dclib), + desc=Ensure the service ran without errors +) + + + diff --git a/sas/sasjs/services/public/registeruser.sas b/sas/sasjs/services/public/registeruser.sas new file mode 100644 index 0000000..03e6122 --- /dev/null +++ b/sas/sasjs/services/public/registeruser.sas @@ -0,0 +1,64 @@ +/** + @file registeruser.sas + @brief Registers a new user in Data Controller + @details New users are logged after accepting EULA terms. + +

SAS Macros

+ @li mf_getuser.sas + @li mp_abort.sas + @li mpeinit.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%let userid=%mf_getuser(); + +/* confirm the user is not registered */ +%let isRegistered=0; +proc sql noprint; +select count(*) into: isregistered + from &mpelib..mpe_users + where user_id="&userid"; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem accessing &mpelib..mpe_users table) +) +%mp_abort(iftrue= (&isregistered > 0) + ,mac=&_program..sas + ,msg=%str(User &userid is already registered on &mpelib..mpe_users!) +) + +data work.append; + if 0 then set &mpelib..mpe_users; + user_id=symget('userid'); + registered_dt=today(); + last_seen_dt=today(); +run; + +proc append base=&mpelib..mpe_users data=work.append; + +%let isRegistered=0; +proc sql noprint; +select count(*) into: isregistered + from &mpelib..mpe_users + where user_id="&userid"; + +%mp_abort(iftrue= (&syscc ne 0 or &isregistered ne 1) + ,mac=&_program..sas + ,msg=%str(Problem appending to &mpelib..mpe_users table) +) + +data work.return; + msg='SUCCESS'; +run; + +%webout(OPEN) +%webout(OBJ,return) +%webout(CLOSE) diff --git a/sas/sasjs/services/public/registeruser.test.sas b/sas/sasjs/services/public/registeruser.test.sas new file mode 100644 index 0000000..37db591 --- /dev/null +++ b/sas/sasjs/services/public/registeruser.test.sas @@ -0,0 +1,45 @@ +/** + @file + @brief testing registeruser service. Test will only work once (after deploy) + +

SAS Macros

+ @li mf_getuser.sas + @li mp_assertcolvals.sas + @li mx_testservice.sas + +**/ + +%let _program=&appLoc/services/public/registeruser; + +/* remove user */ +%let userid=%mf_getuser(); +proc sql noprint; +delete from &dc_libref..mpe_users + where user_id="&userid"; + +/* add user */ +%mx_testservice(&_program, + viyacontext=&defaultcontext, + outlib=webout, + mdebug=&sasjs_mdebug +) + +data _null_; + infile "%sysfunc(pathname(webout))" lrecl=999999; + input; + putlog _infile_; +run; + +data work.return; + set webout.return; + putlog (_all_)(=); +run; + +data work.check; + msg='SUCCESS'; +run; +%mp_assertcolvals(work.return.msg, + checkvals=work.check.msg, + desc=User successfully registered, + test=ALLVALS +) diff --git a/sas/sasjs/services/public/startupservice.sas b/sas/sasjs/services/public/startupservice.sas new file mode 100755 index 0000000..cd0ce08 --- /dev/null +++ b/sas/sasjs/services/public/startupservice.sas @@ -0,0 +1,138 @@ +/** + @file startupservice.sas + @brief List the libraries and tables the mp-editor user can access + @details If user is in a control group (&mpeadmins, configured in mpeinit.sas) + then they have access to all libraries / tables. Otherwise a join is made + to the &mpelib..mp_editor_access table. + + This service is also callable from EUCs - just add EUCDLM= parameter. + EUCDLM values: TAB or CSV + +

SAS Macros

+ @li mf_getuser.sas + @li mpe_getgroups.sas + @li mp_abort.sas + @li mpeinit.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Issue on startup in startupService) +) + +%let userid=%mf_getuser(); +%put userid is &userid; +%mpe_getgroups(user=&userid,outds=groups) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Issue with Groups syscc=&syscc for user &userid) +) + +/* check if user is an admin */ +%let admin_check=0; +proc sql noprint; +select count(*) into: admin_check + from groups + where groupname="&mpeadmins"; + +/* check if user is registered or not */ +%let isRegistered=0; +select count(*) into: isregistered + from &mpelib..mpe_users + where user_id="&userid"; + +/* get number of registered users */ +%let registerCount=0; +select count(*) into: registercount + from &mpelib..mpe_users + where last_seen_dt>%sysfunc(today())-365; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem accessing &mpelib..mpe_users table) +) + +%global dc_restrict_editrecord; +data work.globvars; + dclib="&mpelib"; + sas9lineage_enabled=1; + isadmin=&admin_check; + isregistered=&isregistered; + registercount=®isterCount; + dc_admin_group="&mpeadmins"; + /* fetched from mpe_config in dc_getsettings */ + licence_key="&dc_licence_key"; + activation_key="&dc_activation_key"; + dc_restrict_editrecord="&dc_restrict_editrecord"; +run; + + +%macro mstp_mpeditorstartup(); + data _null_; + putlog "entering &sysmacroname"; + run; + proc sql noprint; + /* update last seen, if seen */ + %if &isregistered>0 %then %do; + update &mpelib..mpe_users + set last_seen_dt=%sysfunc(today()) + where user_id="&userid"; + %end; + %mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem updating &mpelib..mpe_users table) + ) + + %local all_cnt; + select count(*) into: all_cnt + from &mpelib..mpe_security + where &dc_dttmtfmt. lt tx_to + and ACCESS_LEVEL in ('EDIT') + and libref='*ALL*' + and SAS_GROUP in (select groupname from groups); + %if &admin_check >0 or &all_cnt>0 %then %do; + create table sasDatasets as + select distinct libref, dsn + from &mpelib..mpe_tables + where &dc_dttmtfmt. lt tx_to + order by 1; + %end; + %else %do; + create table sasDatasets as + select distinct a.libref,a.dsn + from &mpelib..mpe_tables a + left join &mpelib..mpe_security b + on a.libref=b.libref + and a.dsn=b.dsn + where &dc_dttmtfmt. lt a.tx_to + and &dc_dttmtfmt. lt b.tx_to + and b.ACCESS_LEVEL in ('EDIT') + and b.SAS_GROUP in (select groupname from groups) + order by 1; + %end; +%mend mstp_mpeditorstartup; +%mstp_mpeditorstartup() + +create table saslibs as + select distinct libref + from &syslast; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(issue with security validation) +) + +%webout(OPEN) +%webout(OBJ,sasDatasets) +%webout(OBJ,saslibs) +%webout(OBJ,globvars) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/public/startupservice.test.sas b/sas/sasjs/services/public/startupservice.test.sas new file mode 100644 index 0000000..2869463 --- /dev/null +++ b/sas/sasjs/services/public/startupservice.test.sas @@ -0,0 +1,28 @@ +/** + @file + @brief testing gethistory service + +

SAS Macros

+ @li mp_assertdsobs.sas + @li mp_testservice.sas + +**/ + +%let _program=&appLoc/services/public/startupservice; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + outlib=webout +) + + +data globvars; + set webout.globvars; + putlog (_all_)(=); +run; + +%mp_assertdsobs(work.globvars, + desc=Fromsas table returned, + test=HASOBS, + outds=work.test_results +) diff --git a/sas/sasjs/services/public/validatefilter.sas b/sas/sasjs/services/public/validatefilter.sas new file mode 100644 index 0000000..364462e --- /dev/null +++ b/sas/sasjs/services/public/validatefilter.sas @@ -0,0 +1,67 @@ +/** + @file + @brief Validates a filter clause before it gets hashified, returns the RK + @details Used to generate a FILTER_RK from an input query dataset. + Raw values are stored in dc.mpe_filtersource and the meta values are stored + in dc.mpe_filteranytable + +

Service Inputs

+
IWANT
+ |FILTER_TABLE:$41.| + |---| + |DC258467.MPE_X_TEST| + +
FILTERQUERY
+ |GROUP_LOGIC:$3|SUBGROUP_LOGIC:$3|SUBGROUP_ID:8.|VARIABLE_NM:$32|OPERATOR_NM:$10|RAW_VALUE:$32767| + |---|---|---|---|---|---| + |AND|AND|1|SOME_BESTNUM|>|1| + |AND|AND|1|SOME_TIME|=|77333| + +

Service Outputs

+ +
result
+ @li FILTER_HASH + @li FILTER_RK + @li FILTER_TABLE + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_getvalue.sas + @li mp_filterstore.sas + @li removecolsfromwork.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%let ds=%upcase(%mf_getvalue(work.iwant,filter_table)); +%dc_assignlib(WRITE,%scan(&ds,1,.)) + +%mp_filterstore( + libds=&ds, + queryds=work.filterquery, + filter_summary=&dc_libref..mpe_filteranytable, + filter_detail=&dc_libref..mpe_filtersource, + lock_table=&dc_libref..mpe_lockanytable, + maxkeytable=&dc_libref..mpe_maxkeyvalues, + outresult=work.result, + outquery=work.query, /* not used */ + mdebug=1 +) + +%removecolsfromwork(___TMP___MD5) + +proc sql; +alter table work.result drop PROCESSED_DTTM; + +%webout(OPEN) +%webout(OBJ,result) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/public/validatefilter.test.sas b/sas/sasjs/services/public/validatefilter.test.sas new file mode 100644 index 0000000..f1c51c7 --- /dev/null +++ b/sas/sasjs/services/public/validatefilter.test.sas @@ -0,0 +1,78 @@ +/** + @file + @brief testing public/validatefilter service + +

SAS Macros

+ @li mp_assertdsobs.sas + @li mp_assertcolvals.sas + @li mf_getuniquefileref.sas + +**/ + +%let _program=&appLoc/services/public/validatefilter; + +/* filter for one record */ +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'filter_table:$41.'; + put "&dclib..MPE_TABLES"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + infile datalines4 dsd; + input; + put _infile_; +datalines4; +GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. OPERATOR_NM:$10. RAW_VALUE:$4000. +AND,AND,1,LIBREF,CONTAINS,"'DC'" +AND,OR,2,DSN,=,"'MPE_LOCK_ANYTABLE'" +;;;; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:iwant &f2:filterquery, + outlib=web1 +) +data result; + set web1.result; +run; +%mp_assertdsobs(work.result, + desc=Test1 result filter, + test=EQUALS 1 +) + +/* filter for one record */ + +data work.iwant; + filter_table='DCTEST.DCFMTS-FC'; +run; +data work.filterquery; +GROUP_LOGIC='AND'; +SUBGROUP_LOGIC='AND'; +SUBGROUP_ID=1; +VARIABLE_NM='FMTNAME'; +OPERATOR_NM='CONTAINS'; +RAW_VALUE="'MORD'"; +;;;; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.iwant work.filterquery, + outlib=web2, + outref=web2ref +) +data _null_; + infile web2ref; + input; + putlog _infile_; +run; +data result; + set web2.result; + putlog (_all_)(=); +run; +%mp_assertdsobs(work.result, + desc=Test2 result filter, + test=EQUALS 1 +) diff --git a/sas/sasjs/services/public/viewdata.sas b/sas/sasjs/services/public/viewdata.sas new file mode 100644 index 0000000..4c22eab --- /dev/null +++ b/sas/sasjs/services/public/viewdata.sas @@ -0,0 +1,364 @@ +/** + @file viewdata.sas + @brief Provide the raw view of the data + @details Pass a LIBDS and FILTER_RK to return a dataset for viewing. + VIEW datasets include all columns / rows (unlike EDIT, which are filtered + for current records and don't include the SCD2 etc cols). + +

Service Inputs

+ +
SASCONTROLTABLE
+ |LIBDS:$41.|FILTER_RK:$5.|SEARCHTYPE:$4|SEARCHVAL:$1000 + |---|---|---|--- + |DC258467.MPE_X_TEST|-1|CHAR|Some String| + +

Service Outputs

+ +
cols
+ @li DDTYPE + @li FORMAT + @li LABEL + @li LENGTH + @li NAME + @li TYPE + @li VARNUM + +
sasparams
+ @li FILTER_TEXT + @li NOBS + @li PK_FIELDS - string seperated list of primary key fields, if they exist + @li TABLENAME + @li TABLEURI + @li VARS + +
viewdata
+ The raw data from the target table. + +

SAS Macros

+ @li dc_assignlib.sas + @li dc_createdataset.sas + @li dc_gettableid.sas + @li mf_existds.sas + @li mf_getvarcount.sas + @li mf_nobs.sas + @li mf_verifymacvars.sas + @li mp_abort.sas + @li mp_cntlout.sas + @li mp_dsmeta.sas + @li mp_getcols.sas + @li mp_getpk.sas + @li mp_jsonout.sas + @li mp_searchdata.sas + @li mp_validatecol.sas + @li mpe_columnlevelsecurity.sas + @li mpe_filtermaster.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +/* configure macvars */ +%global LIBDS FILTER_RK SEARCHVAL SEARCHTYPE FMT_IND; + +%let maxrows=250; + +/* avoid code injection */ +%let FMT_IND=0; +%let SEARCHTYPE=; +%let SEARCHVAL=; +%let FILTER_RK=; +%let LIBDS=; + +/** + * Validate inputs + */ +data work.intest; + length libds $41 filter_rk 8. searchval $100 searchtype $4; + set work.SASCONTROLTABLE; + + /* validate filter_rk */ + if filter_rk le 0 then filter_rk=-1; + + /* check if the request is for a format catalog */ + if substr(cats(reverse(libds)),1,3)=:'CF-' then do; + libds=scan(libds,1,'-'); + putlog "Format Catalog Captured"; + call symputx('fmt_ind',1); + end; + putlog (_all_)(=); + + /* validate libds */ + %mp_validatecol(LIBDS,LIBDS,is_libds) + + if searchtype in ('CHAR','NUM') then do; + searchval=tranwrd(searchval,'%',''); + searchval=tranwrd(searchval,'&',''); + searchval=tranwrd(searchval,';',''); + searchval=tranwrd(searchval,'"',''); + call symputx('searchtype',searchtype); + call symputx('searchval',searchval); + end; + else if searchtype not in ('','NONE') then do; + putlog 'ERR' 'OR: Invalid searchtype:' searchtype; + stop; + end; + + if is_libds=0 then do; + putlog 'ERR' 'OR: Invalid libds:' libds; + stop; + end; + else do; + call symputx('filter_rk',filter_rk); + call symputx('libds',libds); + end; + output; + stop; +run; + +%mp_abort(iftrue= (%mf_verifymacvars(libds filter_rk fmt_ind)=0) + ,mac=&_program..sas + ,msg=%str(Problem with macro inputs) +) + +%mp_abort(iftrue= (%mf_nobs(work.intest)=0) + ,mac=&_program + ,msg=%str(Some err with service inputs) +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + + +/** + * assign the Library + */ +%dc_assignlib(READ,%scan(&LIBDS,1,.)) + +/* abort if looking for a format and the catalog doesn't exist */ +%mp_abort(iftrue= (&fmt_ind=1 and %sysfunc(exist(&libds,CATALOG))=0) + ,mac=&_program..sas + ,msg=%str(Catalog &libds does not exist!) +) + +/** + check if dataset can actually be opened - as library may exist but it may not + be possible to assign, and even if it can, the physical table may not exist +**/ +data _null_; + if &fmt_ind=0 then do; + dsid=open("&libds"); + rc=close(dsid); + end; + else dsid=42; + call symputx('existds',dsid,'l'); + putlog 'dataset exists check:' dsid; +run; + +/** + * get the data + */ +%global dsobs; +%let dsobs=0; +%macro x(); +%if &existds>0 %then %do; + + %if &fmt_ind=1 %then %do; + /* export format and point the libds to the output table from here on */ + %mp_cntlout( + libcat=&libds + ,fmtlist=0 + ,cntlout=work.fmtextract + ) + %let libds=WORK.FMTEXTRACT; + proc datasets lib=work noprint; + modify FMTEXTRACT; + index create + pk_cntlout=(type fmtname fmtrow) + /nomiss unique; + quit; + %end; + + proc sql noprint; + select count(*) into: dsobs from &libds; + + %put preparing query; + %mpe_filtermaster(VIEW,&libds, + dclib=&mpelib, + filter_rk=&filter_rk, + outref=filtref, + outds=work.query + ) + %put printing generated filterquery:; + data _null_; + infile filtref; + input; + putlog _infile_; + run; + + %if &searchtype=NONE or "%trim(&searchtype) " = " " %then %do; + /* get row count */ + filename rows temp; + data _null_; + file rows; + infile filtref end=eof; + input; + if _n_=1 then do; + put 'proc sql;'; + put "select count(*) into: dsobs from &libds where"; + end; + put _infile_; + if eof then put ';'; + run; + data _null_; + infile rows; + input; + putlog _infile_; + run; + + %inc rows; + + /* send actual data, filtered and row-capped */ + data work.viewdata; + set &libds; + where %inc filtref;; + if _n_>&maxrows then stop; + run; + %if %mf_nobs(work.viewdata)=0 %then %do; + data work.viewdata; + /* send empty row if empty table to help with hot rendering */ + output; + set work.viewdata; + run; + %end; + %end; + %else %do; + data work.vwsearch/view=work.vwsearch; + set &libds; + where %inc filtref;; + run; + %if %upcase(&searchtype)=CHAR %then %do; + %mp_searchdata(lib=work + ,ds=vwsearch + ,string=%superq(searchval) + ,outobs=&maxrows + ) + %end; + %else %if %upcase(&searchtype)=NUM %then %do; + %mp_searchdata(lib=work + ,ds=vwsearch + ,numval=%superq(searchval) + ,outobs=&maxrows + ) + %end; + %if %mf_existds(libds=MPSEARCH.vwsearch) %then %do; + %let dsobs=%mf_nobs(MPSEARCH.vwsearch); + data viewdata; + set MPSEARCH.vwsearch; + if _n_<&maxrows; + run; + %end; + %else %do; + %let dsobs=0; + data viewdata; + set &libds; + stop; + run; + %end; + %end; +%end; +%else %do; + /* physical table is not accessible so create from metatadata definition */ + %dc_createdataset(libds=&libds,outds=viewdata) + data viewData; + output; + set viewdata; + run; + + /* make filtref / work.query / work.groups to avoid downstream issues */ + filename filtref temp; + data work.query; + file filtref; + x=0; + put x; + run; + data work.groups; + length groupuri groupname $32 groupdesc $128 ; + output; + stop; + run; +%end; +%mend x; %x() + +/* apply column level security */ +%mpe_columnlevelsecurity(%scan(&libds,1,.),%scan(&libds,2,.),work.viewdata + ,mode=VIEW + ,clsds=&mpelib..mpe_column_level_security + ,groupds=work.groups /* was created in mpe_filtermaster */ + ,outds=work.viewdata2 + ,outmeta=work.cls_rules +) + + +/* get table uri (if sas 9) to enable linking direct to lineage */ +%dc_gettableid(libref=%scan(&libds,1,.) + ,ds=%scan(&libds,2,.) + ,outds=work.parambase +) + +data _null_; + infile filtref end=eof; + input; + length filter_text $32767; + retain filter_text; + filter_text=catx(' ',filter_text,_infile_); + if eof then do; + if cats(filter_text)='1=1' then filter_text=''; + call symputx('filter_text',filter_text); + end; +run; + +%mp_getpk(%scan(&libds,1,.), ds=%scan(&libds,2,.), outds=work.pk_fields) + +%let pk_fields=; +data _null_; + set work.pk_fields; + call symputx('pk_fields',pk_fields); +run; + +data work.sasparams; + set work.parambase; + format FILTER_TEXT $32767.; + FILTER_TEXT=symget('FILTER_TEXT'); + length PK_FIELDS $512; + PK_FIELDS=symget('PK_FIELDS'); + nobs=&dsobs; + vars=%mf_getvarcount(viewdata); + maxrows=&maxrows; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%mp_getcols(&libds, outds=cols) + +%mp_dsmeta(&libds, outds=dsmeta) + +%webout(OPEN) +%webout(OBJ,cls_rules) +%webout(OBJ,cols) +%webout(OBJ,dsmeta) +%webout(OBJ,query) +%webout(OBJ,sasparams) +%webout(OBJ,viewData2,fmt=Y,missing=STRING,showmeta=YES,dslabel=viewdata) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/public/viewdata.test.1.sas b/sas/sasjs/services/public/viewdata.test.1.sas new file mode 100644 index 0000000..73403fe --- /dev/null +++ b/sas/sasjs/services/public/viewdata.test.1.sas @@ -0,0 +1,89 @@ +/** + @file + @brief testing public/viewdata service for filtered rowcount + @details We had a situation where the row count for a filtered view was + the count for the entire table, not the filtered view. + + This test first makes a filter, then applies to to a table, and checks the + rowcount. + +

SAS Macros

+ @li mp_assert.sas + @li mp_testservice.sas + @li mf_getuniquefileref.sas + +**/ + +/* first, validate the filter and get the RK */ +%let _program=&appLoc/services/public/validatefilter; + +/* filter for one record */ +%let f1=%mf_getuniquefileref(); +data _null_; + file &f1 termstr=crlf; + put 'filter_table:$41.'; + put "&dclib..MPE_X_TEST"; +run; +%let f2=%mf_getuniquefileref(); +data _null_; + file &f2 termstr=crlf; + infile datalines4 dsd; + input; + put _infile_; +datalines4; +GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. OPERATOR_NM:$10. RAW_VALUE:$4000. +AND,AND,1,PRIMARY_KEY_FIELD,IN,"(1,2,3)" +;;;; +run; +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f1:iwant &f2:filterquery, + outlib=web1 +) +data result; + set web1.result; + putlog (_all_)(=); + call symputx('filter_rk',filter_rk); +run; + + +/* now use this to filter a viewtable for three records */ + +%let _program=&appLoc/services/public/viewdata; + +/* filter for one record */ +%let f3=%mf_getuniquefileref(); +data _null_; + file &f3 termstr=crlf; + put 'LIBDS:$char19. FILTER_RK:best.'; + put "&dclib..MPE_X_TEST,&filter_rk"; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputfiles=&f3:SASControlTable , + outlib=web2, + outref=rawfile, + mdebug=1 +) +%let nobs=0; +data sasparams; + set web2.sasparams; + putlog (_all_)(=); + call symputx('nobs',nobs); +run; + +%mp_assert( + iftrue=(&nobs=3), + desc=Checking the view table has 3 records returned, + outds=work.test_results +) + +%put viewdata raw:; +data _null_; + infile rawfile; + input; + putlog _infile_; +run; + + diff --git a/sas/sasjs/services/public/viewdata.test.2.sas b/sas/sasjs/services/public/viewdata.test.2.sas new file mode 100644 index 0000000..19889f7 --- /dev/null +++ b/sas/sasjs/services/public/viewdata.test.2.sas @@ -0,0 +1,37 @@ +/** + @file + @brief testing public/viewdata service for serving formats + @details Since v4 of DC we can support formats in VIEW and EDIT mode. + +

SAS Macros

+ @li mp_assert.sas + @li mp_testservice.sas + +**/ + +%let _program=&appLoc/services/public/viewdata; + +data work.sascontroltable; + libds='DCTEST.DCFMTS-FC'; + FILTER_RK=0; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.SASControlTable , + outlib=web2, + mdebug=1 +) +%let nobs=0; +data _null_; + set web2.viewdata nobs=nobs; + putlog (_all_)(=); + if _n_=1 then call symputx('nobs',nobs); + else if _n_>10 then stop; +run; + +%mp_assert( + iftrue=(&nobs>2), + desc=Checking the format table has records returned, + outds=work.test_results +) diff --git a/sas/sasjs/services/public/viewlibarray.sas b/sas/sasjs/services/public/viewlibarray.sas new file mode 100644 index 0000000..72a5d65 --- /dev/null +++ b/sas/sasjs/services/public/viewlibarray.sas @@ -0,0 +1,148 @@ +/** + @file viewlibarray.sas + @brief List the libraries for view access + @details + +

SAS Macros

+ @li dc_getlibs.sas + @li mp_abort.sas + @li mf_getuser.sas + @li mpe_getgroups.sas + @li mm_webout.sas + @li mf_existds.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%let keepvars=libraryref libraryname; +data _null_; + length keepvars $32; + set %sysfunc(ifc(%mf_existds(iwant),iwant,_null_)); + call symputx('keepvars',keepvars); +run; + +/** + * get full list of libraries + */ +%dc_getlibs(outds=work.mm_getLibs) + +/* get security groups */ +%mpe_getgroups(user=%mf_getuser(),outds=groups) + +/* get security settings */ +data sec; + set &mpelib..mpe_security; + where &dc_dttmtfmt. lt tx_to and ACCESS_LEVEL='VIEW'; +run; + +/* check for any matching groups */ +proc sql noprint; +create table matches as + select * from sec + where upcase(sas_group) in (select upcase(groupname) from groups); +select count(*) into: securitygroupscount from matches; +select count(*) into: ALL_CNT from matches where libref='*ALL*'; +%put securitygroupscount=&securitygroupscount; +%put ALL_CNT=&ALL_CNT; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%macro mpestp_viewlibs(); +%if not %symexist(DC_RESTRICT_VIEWER) %then %let DC_RESTRICT_VIEWER=NO; + +/* scenario 1 - user is in admin group, hence can view all libraries */ +proc sql noprint; +select count(*) into: scenario1 from groups where groupname="&mpeadmins"; +%if &scenario1>0 %then %do; + %put user in admin group (scenario1=&scenario1); + %return; +%end; +/* scenario 2 - viewer unrestricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=NO and &securitygroupscount=0 %then %do; + %put DC_RESTRICT_VIEWER=&DC_RESTRICT_VIEWER; + %put securitygroupscount=&securitygroupscount; + %return; +%end; + +/* scenario 3 - an *ALL* libref is listed */ +%if &all_cnt>0 %then %do; + %put all_cnt=&all_cnt; + %return; +%end; + +/* scenario 4 - specific librefs listed */ +%if &securitygroupscount>0 %then %do; + %put scenario 4; + %put securitygroupscount=&securitygroupscount; + proc sql; + delete from mm_getLibs + where upcase(libraryref) not in (select upcase(libref) from matches); + %return; +%end; + +/* viewer restricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=YES and &securitygroupscount=0 %then %do; + %put DC_RESTRICT_VIEWER=&DC_RESTRICT_VIEWER; + %put securitygroupscount=&securitygroupscount; + data mm_getlibs; + set mm_getlibs; + stop; + run; + %return; +%end; + +%mp_abort(iftrue= (1=1) + ,mac=&_program..sas + ,msg=%str(unhandled security logic error!) +) + +%mend mpestp_viewlibs; +%mpestp_viewlibs() + +%global dc_viewlib_check; + +/** +* deal with invalid and duplicate library definitions +*/ +proc sort data=mm_getlibs; + by libraryref libraryname; +run; + +data mm_getlibs; + set mm_getlibs; + by libraryref; + if symget('dc_viewlib_check')='YES' then do; + /* note - invalid libraries can result in exception errors. If this happens, + configure the dc_viewlib_check variable to NO in Data Controller Settings + */ + rc=libname(libraryref,,'meta',cats('library="',libraryname,'";')); + drop rc; + if rc ne 0 then do; + putlog "NOTE: Library " libraryname " does not exist!!"; + putlog (_all_) (=); + delete; + end; + end; + if not first.libraryref then delete; +run; + +proc sort data=mm_getlibs (keep=&keepvars); + by libraryname; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%mm_webout(OPEN) +%mm_webout(ARR, mm_getLibs) +%mm_webout(CLOSE) diff --git a/sas/sasjs/services/public/viewlibs.sas b/sas/sasjs/services/public/viewlibs.sas new file mode 100644 index 0000000..cad846e --- /dev/null +++ b/sas/sasjs/services/public/viewlibs.sas @@ -0,0 +1,142 @@ +/** + @file viewlibs.sas + @brief List the libraries for view access + @details + +

SAS Macros

+ @li dc_getlibs.sas + @li mp_abort.sas + @li mf_getuser.sas + @li mpe_getgroups.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +/** + * get full list of libraries + */ +%dc_getlibs(outds=work.mm_getLibs) + +/* get security groups */ +%mpe_getgroups(user=%mf_getuser(),outds=groups) + +/* get security settings */ +data sec; + set &mpelib..mpe_security; + where &dc_dttmtfmt.lt tx_to and ACCESS_LEVEL='VIEW'; +run; + +/* check for any matching groups */ +proc sql noprint; +create table matches as + select * from sec + where upcase(sas_group) in (select upcase(groupname) from groups); +select count(*) into: securitygroupscount from matches; +select count(*) into: ALL_CNT from matches where libref='*ALL*'; +%put securitygroupscount=&securitygroupscount; +%put ALL_CNT=&ALL_CNT; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%macro mpestp_viewlibs(); +%if not %symexist(DC_RESTRICT_VIEWER) %then %let DC_RESTRICT_VIEWER=NO; + +/* scenario 1 - user is in admin group, hence can view all libraries */ +proc sql noprint; +select count(*) into: scenario1 from groups where groupname="&mpeadmins"; +%if &scenario1>0 %then %do; + %put user in admin group (scenario1=&scenario1); + %return; +%end; +/* scenario 2 - viewer unrestricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=NO and &securitygroupscount=0 %then %do; + %put DC_RESTRICT_VIEWER=&DC_RESTRICT_VIEWER; + %put securitygroupscount=&securitygroupscount; + %return; +%end; + +/* scenario 3 - an *ALL* libref is listed */ +%if &all_cnt>0 %then %do; + %put all_cnt=&all_cnt; + %return; +%end; + +/* scenario 4 - specific librefs listed */ +%if &securitygroupscount>0 %then %do; + %put scenario 4; + %put securitygroupscount=&securitygroupscount; + proc sql; + delete from mm_getLibs + where upcase(libraryref) not in (select upcase(libref) from matches); + %return; +%end; + +/* viewer restricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=YES and &securitygroupscount=0 %then %do; + %put DC_RESTRICT_VIEWER=&DC_RESTRICT_VIEWER; + %put securitygroupscount=&securitygroupscount; + data mm_getlibs; + set mm_getlibs; + stop; + run; + %return; +%end; + +%mp_abort(iftrue= (1=1) + ,mac=&_program..sas + ,msg=%str(unhandled security logic err!) +) + +%mend mpestp_viewlibs; +%mpestp_viewlibs() + +%global dc_viewlib_check; + +/** +* deal with invalid and duplicate library definitions +*/ +proc sort data=mm_getlibs; + by libraryref libraryname; +run; + +data mm_getlibs; + set mm_getlibs; + by libraryref; + if symget('dc_viewlib_check')='YES' then do; + /* note - invalid libraries can result in exception errors. If this happens, + configure the dc_viewlib_check variable to NO in Data Controller Settings + */ + rc=libname(libraryref,,'meta',cats('library="',libraryname,'";')); + drop rc; + if rc ne 0 then do; + putlog "NOTE: Library " libraryname " does not exist!!"; + putlog (_all_) (=); + delete; + end; + end; + if not first.libraryref then delete; +run; + +proc sort data=mm_getlibs out=saslibs; + by libraryname; +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%webout(OPEN) +%webout(OBJ,saslibs) +%webout(CLOSE) + +%mpeterm() diff --git a/sas/sasjs/services/public/viewlibs.test.sas b/sas/sasjs/services/public/viewlibs.test.sas new file mode 100644 index 0000000..2e4d015 --- /dev/null +++ b/sas/sasjs/services/public/viewlibs.test.sas @@ -0,0 +1,35 @@ +/** + @file + @brief testing public/viewlibs service + +

SAS Macros

+ @li mp_assertdsobs.sas + @li mp_testservice.sas + +

Related Programs

+ @li viewlibs.sas + +**/ + +%let _program=&appLoc/services/public/viewlibs; + +data work.sascontroltable; + mplib="&dclib"; +run; + +%mp_testservice(&_program, + viyacontext=&defaultcontext, + outlib=web1 +) +data work.saslibs; + set web1.saslibs; +run; + +%mp_assertdsobs(work.saslibs, + desc=saslibs contains rows, + test=ATLEAST 2 +) + + + + diff --git a/sas/sasjs/services/public/viewtables.sas b/sas/sasjs/services/public/viewtables.sas new file mode 100644 index 0000000..d95d0ef --- /dev/null +++ b/sas/sasjs/services/public/viewtables.sas @@ -0,0 +1,183 @@ +/** + @file viewtables.sas + @brief List the tables and format catalogs the user can view + @details Provide a library and get list of tables and catalogs. Also return + the libinfo details. + +

Service Inputs

+
SASControlTable
+ Just one input - MPLIB (the libref to get tables and info for) + |MPLIB:$char8.| + |---| + |SOMELIB| + +

Service Outputs

+
work.mptables
+ + |MEMNAME:$char32.| + |---| + |DS1| + |DS2| + |DS3| + + etc + +
work.libinfo
+ If attributes are empty, they don't need to be shown on screen. + + |engine $|libname $|paths $|perms $|owners $|schemas $ |libid $|libsize $|table_cnt | + |---|---|---|---|---|---|---|---|---| + |V9|SOMELIB|"some/path"|rwxrwxr-x|sassrv|` `|` `|636MB|33| + + + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_getuser.sas + @li mpe_getgroups.sas + @li mpe_getvars.sas + @li mpeinit.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%global MPLIB; + +/* load parameters */ +%mpe_getvars(SASControlTable, SASControlTable) + +/** + * assign the Library + */ +%put &=MPLIB; +%dc_assignlib(READ,&MPLIB) + +%mp_abort(iftrue= (&syscc ne 0 ) + ,mac=&_program..sas + ,msg=%str(Unable to assign &mplib library) +) + +/** + * get the tables + */ +data members; /* empty table */ + name=''; + memtype=''; +run; +ods output Members=Members; +proc datasets library=&mplib ; +quit; + +/* cannot avoid the proc datasets warn!ng for an empty lib */ +/* nolist means no output and nowarn has no effect */ +%put &=syscc; +data _null_; + if "&syscc" ne "0" then do; + putlog "Library &mplib is empty, setting syscc to zero"; + call symputx('syscc',0); + end; +run; +%put &=syscc; + +proc sql; +create table work.mptables as + select distinct case when memtype='CATALOG' then cats(name,'-FC') + else name end as memname + from members; + +/* get security groups */ +%mpe_getgroups(user=%mf_getuser(),outds=groups) + +/* get security settings */ +data sec; + set &mpelib..mpe_security; + where &dc_dttmtfmt. lt tx_to and ACCESS_LEVEL='VIEW'; + where also libref in ('*ALL*',"%upcase(&mplib)"); +run; + +/* check for any matching groups */ +proc sql noprint; +create table matches as + select * from sec + where upcase(sas_group) in (select upcase(groupname) from groups); +select count(*) into: securitygroupscount from matches; +select count(*) into: ALL_CNT from matches + where libref='*ALL*' + or (libref="&mplib" and dsn='*ALL*'); + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%macro mpestp_viewtables(); +%if not %symexist(DC_RESTRICT_VIEWER) %then %let DC_RESTRICT_VIEWER=NO; + +/* scenario 1 - user is in admin group, hence can view all libraries */ +proc sql noprint; +select count(*) into: scenario1 from groups where groupname="&mpeadmins"; +%if &scenario1>0 %then %return; + +/* scenario 2 - viewer unrestricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=NO and &securitygroupscount=0 %then %return; + +/* scenario 3 - an *ALL* libref or DSN is listed */ +%if &all_cnt>0 %then %return; + +/* scenario 4 - specific tables listed */ +%if &securitygroupscount>0 %then %do; + proc sql; + delete from mptables + where upcase(memname) not in (select upcase(dsn) from sec); + %return; +%end; + +/* viewer restricted and no groups listed */ +%if &DC_RESTRICT_VIEWER=YES and &securitygroupscount=0 %then %do; + data mptables; + set mptables; + stop; + run; + %return; +%end; + +%mp_abort(iftrue= (1=1) + ,mac=&_program..sas + ,msg=%str(unhandled security logic error!) +) + +%mend mpestp_viewtables; +%mpestp_viewtables() + + +/* get libinfo */ +proc sql; +create table work.libinfo as + select a.engine, + a.libname, + a.paths, + a.perms, + a.owners, + a.schemas, + a.libid, + coalesce(b.libsize,0) as libsize, + coalesce(b.table_cnt,0) as table_cnt + from &mpelib..mpe_datacatalog_libs(where=(&dc_dttmtfmt. lt tx_to)) a + left join &mpelib..mpe_datastatus_libs(where=(&dc_dttmtfmt. lt tx_to)) b + on a.libref=b.libref + where a.libref="&MPLIB"; + + +%webout(OPEN) +%webout(OBJ,mptables) +%webout(OBJ,libinfo) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/services/public/viewtables.test.sas b/sas/sasjs/services/public/viewtables.test.sas new file mode 100644 index 0000000..e99885f --- /dev/null +++ b/sas/sasjs/services/public/viewtables.test.sas @@ -0,0 +1,71 @@ +/** + @file + @brief testing public/viewtables service + +

SAS Macros

+ @li dc_refreshcatalog.sas + @li mf_getengine.sas + @li mp_assert.sas + @li mp_assertdsobs.sas + @li mx_testservice.sas + +

Related Programs

+ @li viewtables.sas + +**/ + +%let _program=&appLoc/services/public/viewtables; + +/* ensure catalog is up to date */ +%dc_refreshcatalog(DCTEST) + +data work.sascontroltable; + mplib="DCTEST"; +run; + +%mx_testservice(&_program, + viyacontext=&defaultcontext, + inputdatasets=work.sascontroltable, + outlib=web1, + mdebug=&sasjs_mdebug +) +data work.mptables; + set web1.mptables; + putlog (_all_)(=); +run; + +%mp_assertdsobs(work.mptables, + desc=DCTEST contains tables, + test=ATLEAST 2 +) + +%let engine=0; +data work.libinfo; + set web1.libinfo; + putlog (_all_)(=); + call symputx('engine',engine); +run; + +%mp_assertdsobs(work.libinfo, + desc=LIBINFO contains one row, + test=EQUALS 1 +) +%mp_assert( + iftrue=(&engine=%mf_getengine(DCTEST)), + desc=Checking returned engine matches the one we put in +) + + +%let catcnt=0; +proc sql noprint; +select count(*) into: catcnt + from work.mptables + where substr(reverse(cats(upcase(memname))),1,3)='CF-'; + +%mp_assert( + iftrue=(&catcnt=1), + desc=Checking dclib cat was created +) + + + diff --git a/sas/sasjs/services/validations/columns_in_libds.sas b/sas/sasjs/services/validations/columns_in_libds.sas new file mode 100644 index 0000000..3dfe38e --- /dev/null +++ b/sas/sasjs/services/validations/columns_in_libds.sas @@ -0,0 +1,108 @@ +/** + @file + @brief Generic validator for table columns + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + +

Service Inputs

+
work.sourcerow
+ Has source table structure. + +

Service Outputs

+ + The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_getuniquename.sas + @li mp_abort.sas + @li mp_validatecol.sas + + +**/ + +/* send back the raw and formatted values */ +%let tgtlibds=0; +%let varlibds=%mf_getuniquename(); +%let vartgtlibds=%mf_getuniquename(); +%let var_is_libds=%mf_getuniquename(); + +data _null_; + length xl_libref base_lib select_lib rls_libref cls_libref libref $8 + xl_table base_ds select_ds rls_table cls_table dsn $32; + if _n_=1 then call missing(of _all_); + set work.source_row; + &varlibds=symget('libds'); + if &varlibds="&mpelib..MPE_EXCEL_CONFIG" + then &vartgtlibds=cats(xl_libref,'.',xl_table); + else if &varlibds="&mpelib..MPE_VALIDATIONS" + then &vartgtlibds=cats(BASE_LIB,'.',BASE_DS); + else if &varlibds="&mpelib..MPE_SELECTBOX" + then &vartgtlibds=cats(select_lib,'.',select_ds); + else if &varlibds="&mpelib..MPE_ROW_LEVEL_SECURITY" + then &vartgtlibds=cats(RLS_LIBREF,'.',RLS_TABLE); + else if &varlibds="&mpelib..MPE_COLUMN_LEVEL_SECURITY" + then &vartgtlibds=cats(CLS_LIBREF,'.',CLS_TABLE); + else if &varlibds="&mpelib..MPE_TABLES" + then &vartgtlibds=cats(LIBREF,'.',DSN); + + /* validate libds */ + %mp_validatecol(&vartgtlibds,LIBDS,&var_is_libds) + + if &var_is_libds=1 then call symputx('tgtlibds',&vartgtlibds); + putlog (_all_)(=); +run; + +%mp_abort(iftrue= ("&tgtlibds" ="0" ) + ,mac=&_program..sas + ,msg=%str(Unable to extract libds vars from &libds inputs for &variable_nm) +) + +%dc_assignlib(READ,%scan(&tgtlibds,1,.)) + +proc contents noprint data=&tgtlibds + out=work.DYNAMIC_VALUES (keep=name rename=(name=display_value) ); +run; + +data work.DYNAMIC_VALUES; + set work.DYNAMIC_VALUES; + raw_value=upcase(display_value); + format raw_value; +run; + + diff --git a/sas/sasjs/services/validations/libraries_all.sas b/sas/sasjs/services/validations/libraries_all.sas new file mode 100644 index 0000000..a814573 --- /dev/null +++ b/sas/sasjs/services/validations/libraries_all.sas @@ -0,0 +1,64 @@ +/** + @file + @brief Generic validator for libraries + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + +

SAS Macros

+ @li dc_getlibs.sas + + +**/ + +/** + * get full list of libraries + */ +%dc_getlibs(outds=work.mm_getLibs) + +proc sql; +create table work.DYNAMIC_VALUES as + select distinct libraryname as display_value, + upcase(libraryref) as raw_value + from work.mm_getLibs + order by 1; + + diff --git a/sas/sasjs/services/validations/libraries_editable.sas b/sas/sasjs/services/validations/libraries_editable.sas new file mode 100644 index 0000000..0d52a2a --- /dev/null +++ b/sas/sasjs/services/validations/libraries_editable.sas @@ -0,0 +1,57 @@ +/** + @file + @brief Generic validator for editable libraries + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + + +**/ + +/* send back the raw and formatted values */ +proc sql; +create table work.DYNAMIC_VALUES as + select distinct libref as display_value, + upcase(libref) as raw_value + from &mpelib..mpe_tables + where &dc_dttmtfmt. < tx_to + order by 1; + diff --git a/sas/sasjs/services/validations/mpe_alerts.alert_lib.sas b/sas/sasjs/services/validations/mpe_alerts.alert_lib.sas new file mode 100644 index 0000000..171a2d0 --- /dev/null +++ b/sas/sasjs/services/validations/mpe_alerts.alert_lib.sas @@ -0,0 +1,108 @@ +/** + @file + @brief fetch extended values for alert_lib + @details Fetches libraries from mpe_tables, creates extended values for + alert_ds, and marks "*ALL*" as the forced (default) value. + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ Output should be a single table called "work.dynamic_values" in the format + below. display_value should always be character, raw_value is unformatted + character/numeric. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + The FORCED_VALUE column can be used to force an extended value to be selected + by default when a particular value is chosen. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000|FORCED_VALUE| + |---|---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5||.| + |1|DISCOUNT_RT|"40%"|N|0.4||0| + |1|DISCOUNT_RT|"30%"|N|0.3||1| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"|.| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"|.| + |2|DISCOUNT_RT|"50%"|N|0.5||.| + |2|DISCOUNT_RT|"40%"|N|0.4||1| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"|.| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"|1| + +

SAS Macros

+ @li dc_getlibs.sas + + +**/ + +%mp_abort(iftrue= ("%upcase(&libds)" ne "&DC_LIBREF..MPE_ALERTS" ) + ,mac=&_program + ,msg=%str( + Invalid validation, expected MPE_ALERTS.ALERT_LIB, got %superq(libds) + ) +) + +proc sql; +create table work.source as + select libref,dsn + from &DC_LIBREF..MPE_TABLES + where tx_to > &dc_dttmtfmt. + order by 1,2; + +data work.DYNAMIC_VALUES (keep=display_index raw_value display_value); + set work.source end=last; + by libref; + if last.libref then do; + display_index+1; + raw_value=libref; + display_value=libref; + output; + end; + if last then do; + display_index+1; + raw_value='*ALL*'; + display_value='*ALL*'; + output; + end; +run; + + +data work.dynamic_extended_values(keep=display_index extra_col_name display_type + display_value RAW_VALUE_CHAR raw_value_num forced_value); + set work.source end=last; + by libref dsn; + retain extra_col_name 'ALERT_DS'; + retain display_type 'C'; + retain raw_value_num .; + raw_value_char=dsn; + display_value=dsn; + forced_value=0; + + if first.libref then display_index+1; + if last.libref then do; + display_value='*ALL*'; + raw_value_char='*ALL*'; + forced_value=1; + output; + end; + else output; + +run; diff --git a/sas/sasjs/services/validations/mpe_tables.dsn.sas b/sas/sasjs/services/validations/mpe_tables.dsn.sas new file mode 100644 index 0000000..1950aec --- /dev/null +++ b/sas/sasjs/services/validations/mpe_tables.dsn.sas @@ -0,0 +1,135 @@ +/** + @file + @brief fetch extended values for DSN + @details Fetches datasets in a library, and ALSO fetches a list of numeric + vars for each dataset for use in adjacent columns (such as VAR_PROCESSED, + TX_TO etc). + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ Output should be a single table called "work.dynamic_values" in the format + below. display_value should always be character, raw_value is unformatted + character/numeric. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + The FORCED_VALUE column can be used to force an extended value to be selected + by default when a particular value is chosen. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000|FORCED_VALUE| + |---|---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5||.| + |1|DISCOUNT_RT|"40%"|N|0.4||0| + |1|DISCOUNT_RT|"30%"|N|0.3||1| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"|.| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"|.| + |2|DISCOUNT_RT|"50%"|N|0.5||.| + |2|DISCOUNT_RT|"40%"|N|0.4||1| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"|.| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"|1| + +

SAS Macros

+ @li dc_getlibs.sas + + +**/ + + +/* send back the raw and formatted values */ +%let tgtlib=0; +%let varlibds=%mf_getuniquename(); +%let vartgtlib=%mf_getuniquename(); +%let var_is_lib=%mf_getuniquename(); +data _null_; + length &varlibds $41 &vartgtlib $8; + set work.source_row; + &varlibds=upcase(symget('libds')); + if &varlibds="&mpelib..MPE_TABLES" then &vartgtlib=LIBREF; + else putlog "something unexpected happened"; + + /* validate name */ + if nvalid(&vartgtlib,'v7') then call symputx('tgtlib',&vartgtlib); + call symputx('vartgtlib',&vartgtlib); + + putlog (_all_)(=); +run; + +%mp_abort(iftrue= ("&tgtlib" ="0" ) + ,mac=&_program..sas + ,msg=%str(Invalid library - %superq(vartgtlib)) + ,errds=work.dc_error_response +) + +%dc_assignlib(READ,&tgtlib) + + +proc sql; +create table work.source as + select upcase(memname) as memname + ,upcase(name) as name + ,type + from dictionary.columns + where libname="&TGTLIB" + and memtype='DATA'; + +create table work.members as + select distinct memname as display_value + from work.source; + +data work.DYNAMIC_VALUES; + set work.members; + raw_value=display_value; + display_index=_n_; +run; + +proc sql; +create table work.dynamic_extended_values as + select a.display_index + ,b.name as display_value + ,"C" as display_type + ,b.name as RAW_VALUE_CHAR + ,. as RAW_VALUE_NUM + from work.dynamic_values a + left join work.source b + on a.display_value=b.memname + where b.type='num'; + +data work.dynamic_extended_values; + set work.DYNAMIC_EXTENDED_VALUES; + extra_col_name='VAR_PROCESSED';output; + extra_col_name='VAR_TXFROM';output; + extra_col_name='VAR_TXTO';output; + extra_col_name='VAR_BUSFROM';output; + extra_col_name='VAR_BUSTO';output; +run; +/* set some force flags */ +data work.dynamic_extended_values; + set work.DYNAMIC_EXTENDED_VALUES; + forced_value=0; + if extra_col_name='VAR_TXFROM' & raw_value_char='TX_FROM' then forced_value=1; + if extra_col_name='VAR_TXTO' & raw_value_char='TX_TO' then forced_value=1; +run; + +proc sort; + by extra_col_name display_index; +run; \ No newline at end of file diff --git a/sas/sasjs/services/validations/mpe_x_test.some_num.sas b/sas/sasjs/services/validations/mpe_x_test.some_num.sas new file mode 100644 index 0000000..5aa91e0 --- /dev/null +++ b/sas/sasjs/services/validations/mpe_x_test.some_num.sas @@ -0,0 +1,35 @@ +/** + @file + @brief Generic validator for libraries + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li DC_LIBREF - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ Output should be a single table called "work.dynamic_values" in the format + below. display_value should always be character, raw_value is unformatted + character/numeric. + + |DISPLAY_VALUE:$|RAW_VALUE:??| + |---|---| + |$44.00|44| + +

SAS Macros

+ @li dc_getlibs.sas + + +**/ + +proc sql; +create table work.DYNAMIC_VALUES as + select distinct cats(some_num) as display_value, + some_num as raw_value + from &libds + order by 1; + + diff --git a/sas/sasjs/services/validations/sas_groups.sas b/sas/sasjs/services/validations/sas_groups.sas new file mode 100644 index 0000000..e58cfc2 --- /dev/null +++ b/sas/sasjs/services/validations/sas_groups.sas @@ -0,0 +1,61 @@ +/** + @file + @brief validating the mpe_security.sas_group column + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + + + +

SAS Macros

+ @li dc_getgroups.sas + + +**/ + + +%dc_getgroups(outds=groups) + +proc sql; +create table work.DYNAMIC_VALUES as + select distinct groupname as display_value, + groupname as raw_value + from work.groups + order by 1; diff --git a/sas/sasjs/services/validations/tables_all.sas b/sas/sasjs/services/validations/tables_all.sas new file mode 100644 index 0000000..2272dd4 --- /dev/null +++ b/sas/sasjs/services/validations/tables_all.sas @@ -0,0 +1,97 @@ +/** + @file + @brief Generic validator for tables in a library + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + + +

Service Outputs

+ The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|| + |1|DISCOUNT_RT|"40%"|N|0.4|| + |1|DISCOUNT_RT|"30%"|N|0.3|| + |1|CURRENCY_SYMBOL|"GBP"|C||"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C||"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|| + |2|DISCOUNT_RT|"40%"|N|0.4|| + |2|CURRENCY_SYMBOL|"EUR"|C||"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C||"HKD"| + +

SAS Macros

+ @li dc_assignlib.sas + +**/ + +/* send back the raw and formatted values */ +%let tgtlib=0; +%let varlibds=%mf_getuniquename(); +%let vartgtlib=%mf_getuniquename(); +%let var_is_lib=%mf_getuniquename(); +data _null_; + length &varlibds $41 &vartgtlib $8 libref $8 rls_libref $8; + if _n_=1 then call missing(of _all_); + set work.source_row; + &varlibds=upcase(symget('libds')); + if &varlibds="&mpelib..MPE_TABLES" then &vartgtlib=LIBREF; + else if &varlibds="&mpelib..MPE_ROW_LEVEL_SECURITY" + then &vartgtlib=RLS_LIBREF; + else if &varlibds="&mpelib..MPE_COLUMN_LEVEL_SECURITY" + then &vartgtlib=CLS_LIBREF; + + /* validate name */ + if nvalid(&vartgtlib,'v7') then call symputx('tgtlib',&vartgtlib); + call symputx('vartgtlib',&vartgtlib); + + putlog (_all_)(=); +run; + +%mp_abort(iftrue= ("&tgtlib" ="0" ) + ,mac=&_program..sas + ,msg=%str(Invalid library - %superq(vartgtlib)) + ,errds=work.dc_error_response +) + +%dc_assignlib(READ,&tgtlib) + +data members; /* empty table */ +name=' '; +run; +ods output Members=Members; +proc datasets library=&tgtlib ; +run; + +/* send back the raw and formatted values */ +proc sql; +create table work.DYNAMIC_VALUES as + select distinct name as display_value, + upcase(name) as raw_value + from work.members + where MemType='DATA' + order by 1; + diff --git a/sas/sasjs/services/validations/tables_editable.sas b/sas/sasjs/services/validations/tables_editable.sas new file mode 100644 index 0000000..f08e740 --- /dev/null +++ b/sas/sasjs/services/validations/tables_editable.sas @@ -0,0 +1,70 @@ +/** + @file + @brief Generic validator for editable libraries + @details The input table is simply one row from the target table in table + called "work.source_row". + + Available macro variables: + @li MPELIB - The DC control library + @li LIBDS - The library.dataset being filtered + @li VARIABLE_NM - The column being filtered + +

Service Inputs

+
work.source_row
+ |libref:$8| + |somelib| + +

Service Outputs

+ The values provided below are generic samples - we encourage you to replace + these with realistic values in your own deployments. + +
DYNAMIC_VALUES
+ The RAW_VALUE column may be charactor or numeric. If DISPLAY_INDEX is not + provided, it is added automatically. + + |DISPLAY_INDEX:best.|DISPLAY_VALUE:$|RAW_VALUE| + |---|---|---| + |1|$77.43|77.43| + |2|$88.43|88.43| + +
DYNAMIC_EXTENDED_VALUES
+ This table is optional. If provided, it will map the DISPLAY_INDEX from the + DYNAMIC_VALUES table to additional column/value pairs, that will be used to + populate dropdowns for _other_ cells in the _same_ row. + + Should be used sparingly! The use of large tables here can slow down the + browser. + + |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_VALUE:$|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000| + |---|---|---|---|---|---| + |1|DISCOUNT_RT|"50%"|N|0.5|` `| + |1|DISCOUNT_RT|"40%"|N|0.4|` `| + |1|DISCOUNT_RT|"30%"|N|0.3|` `| + |1|CURRENCY_SYMBOL|"GBP"|C|` `|"GBP"| + |1|CURRENCY_SYMBOL|"RSD"|C|` `|"RSD"| + |2|DISCOUNT_RT|"50%"|N|0.5|` `| + |2|DISCOUNT_RT|"40%"|N|0.4|` `| + |2|CURRENCY_SYMBOL|"EUR"|C|` `|"EUR"| + |2|CURRENCY_SYMBOL|"HKD"|C|` `|"HKD"| + +**/ + +/* send back the raw and formatted values */ +data _null_; + var=symget('variable_nm'); + libds=symget('libds'); + if libds="&mpelib..MPE_EXCEL_CONFIG" and var='XL_TABLE' then do; + call symputx('srccol','XL_LIBREF'); + end; + else call symputx('srccol','libref'); +run; + +proc sql; +create table work.DYNAMIC_VALUES as + select distinct dsn as display_value, + upcase(dsn) as raw_value + from &mpelib..mpe_tables + (where=(&dc_dttmtfmt. < tx_to)) + where libref in (select &srccol from work.source_row) + order by 1; + diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_assignlib.sas b/sas/sasjs/targets/sas9/macros_meta/dc_assignlib.sas new file mode 100644 index 0000000..b3145f5 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_assignlib.sas @@ -0,0 +1,71 @@ +/** + @file dc_assignlib.sas + @brief Assigns macros + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_assignlib.sas + @li mm_assigndirectlib.sas + @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_assignlib(type,libref,passthru=); +%put &sysmacroname entry vars:; +%put _local_; + +/* take current repository */ +%local repo repocnt x; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + where repositorytype in('CUSTOM','FOUNDATION') + & upcase(name) ne "%upcase(&repo)"; + keep id name ; + call symputx(cats('repo',_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; + +/* find out which of these repositories has the libref we are searching for */ +%local lib_uri; +%let lib_uri=NOTFOUND; +data _null_; /* check default repo first */ + length lib_uri $256; + call missing (of _all_); + rc=metadata_getnobj("omsobj:SASLibrary?@Libref ='&libref'",1,lib_uri); + call symputx('lib_uri',coalescec(lib_uri,'NOTFOUND'),'l'); +run; +%if &lib_uri=NOTFOUND %then %do; + %do x=1 %to &repocnt; + options metarepository=&&repo&x; + data _null_; + length lib_uri $256; + call missing (of _all_); + rc=metadata_getnobj("omsobj:SASLibrary?@Libref ='&libref'",1,lib_uri); + call symputx('lib_uri',coalescec(lib_uri,'NOTFOUND'),'l'); + run; + %if &lib_uri ne NOTFOUND %then %let x=%eval(&repocnt+1); + %end; +%end; + + +%if &type=READ %then %do; + %mm_assignlib(&libref) +%end; +%else %if &type=WRITE %then %do; + %mm_assigndirectlib(&libref,open_passthrough=&passthru) +%end; + +options metarepository=&repo; + +%mend dc_assignlib; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_createdataset.sas b/sas/sasjs/targets/sas9/macros_meta/dc_createdataset.sas new file mode 100644 index 0000000..3e6a921 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_createdataset.sas @@ -0,0 +1,18 @@ +/** + @file dc_createdataset.sas + +

SAS Macros

+ @li mm_createdataset.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_createdataset(libds=mm_getlibs,outds=viewdata); + + %mm_createdataset(libds=&libds,outds=viewdata) + +%mend dc_createdataset; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getgroupmembers.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getgroupmembers.sas new file mode 100644 index 0000000..a537500 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getgroupmembers.sas @@ -0,0 +1,21 @@ +/** + @file dc_getgroupmembers.sas + @brief Gets all the memers of a group + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getgroupmembers.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroupmembers(group,outds=dc_getgroupmembers); + + %mm_getgroupmembers(&group,outds=&outds) + +%mend dc_getgroupmembers; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getgroups.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getgroups.sas new file mode 100644 index 0000000..12e9042 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getgroups.sas @@ -0,0 +1,47 @@ +/** + @file dc_getgroups.sas + @brief Gets all groups + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getgroups.sas + @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroups(outds=mm_getlibs); + +%local repo repocnt x; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + where repositorytype in('CUSTOM','FOUNDATION') + & upcase(name) ne "%upcase(&repo)"; + keep id name ; + call symputx(cats('repo',_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; +%put _local_; + +%mm_getgroups(outds=&outds,repo=foundation) +%do x=1 %to &repocnt; + %mm_getgroups(outds=&outds.a, repo=&&repo&x) + proc append base=&outds data=&outds.a; + run; +%end; + +proc sort data=&outds noduprec; +by groupname; +run; + +%mend dc_getgroups; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getlibs.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getlibs.sas new file mode 100644 index 0000000..ba31bff --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getlibs.sas @@ -0,0 +1,47 @@ +/** + @file dc_getlibs.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getlibs.sas + @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getlibs(outds=mm_getlibs); + +/* take current repository */ +%local repo repocnt x; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + where repositorytype in('CUSTOM','FOUNDATION') + & upcase(name) ne "%upcase(&repo)"; + keep id name ; + call symputx('repo'!!cats(_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; +%put _local_; + +%mm_getlibs(outds=&outds) +%do x=1 %to &repocnt; + options metarepository=&&repo&x; + %mm_getlibs(outds=&outds.a) + proc append base=&outds data=&outds.a; + run; +%end; + +options metarepository=&repo; + +%mend dc_getlibs; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getroles.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getroles.sas new file mode 100644 index 0000000..14b466c --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getroles.sas @@ -0,0 +1,47 @@ +/** + @file dc_getroles.sas + @brief Gets all available roles + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getroles.sas + @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getroles(outds=mm_getroles); + +/* take current repository */ +%local repo repocnt x; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + where repositorytype in('CUSTOM','FOUNDATION') + & upcase(name) ne "%upcase(&repo)"; + keep id name ; + call symputx(cats('repo',_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; +%put _local_; + +%mm_getroles(outds=&outds) +%do x=1 %to &repocnt; + options metarepository=&&repo&x; + %mm_getroles(outds=&outds.a) + proc append base=&outds data=&outds.a; + run; +%end; + +options metarepository=&repo; + +%mend dc_getroles; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getservicecode.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getservicecode.sas new file mode 100644 index 0000000..92e448d --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getservicecode.sas @@ -0,0 +1,21 @@ +/** + @file + @brief Gets service code + +

SAS Macros

+ @li mm_getstpcode.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getservicecode(loc=,outref=); + + %mm_getstpcode(tree=&loc + ,outref=&outref + ) + +%mend dc_getservicecode; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getsettings.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getsettings.sas new file mode 100644 index 0000000..a7e492d --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getsettings.sas @@ -0,0 +1,64 @@ +/** + @file + @brief Get settings + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mf_getapploc.sas + @li mm_getstpcode.sas + @li mp_abort.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getsettings(); +%global _program; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc on entry (&syswarningtext &syserrortext)) +) + +%if %length(&_PROGRAM)>1 %then %let root=&_program; +%else %do; + %global _metauser; + %let _metauser=&sysuserid; + /* to mimic a "real" _program we need to give a dummy role and stp name */ + %let root=/dummyRole/dummyName; +%end; + + +/* the DC precode is stored in the Admin folder in the root of + the project. Lets find that root. */ +%put &=root; +%let root=%mf_getapploc(); +%put &=root; + +/* Now we know the root location we can retrieve the params */ +%let temploc=%sysfunc(pathname(work))/settings.txt; +%mm_getstpcode(tree=&root/services/public + ,name=Data_Controller_Settings + ,outloc=&temploc +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(Unable to run getstpcode) +) +filename _getsets "&temploc" lrecl=2000; +/* + Do not use mp_include here - this puts a copy in every service, which creates + compilation problems when calling services from mp_include +*/ +%inc _getsets/source2; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(Problem running &sysmacroname (&syswarningtext &syserrortext)) +) + +%mend dc_getsettings; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_gettableid.sas b/sas/sasjs/targets/sas9/macros_meta/dc_gettableid.sas new file mode 100644 index 0000000..479b6e0 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_gettableid.sas @@ -0,0 +1,31 @@ +/** + @file dc_gettableid.sas + @brief Gets the metadata table id + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_gettableid.sas + @li mf_nobs.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_gettableid(libref= + ,ds= + ,outds=); + +%mm_gettableid(libref=&libref,ds=&ds,outds=&outds) + +%if %mf_nobs(&outds)=0 %then %do; + data &outds; + tableuri=''; + tablename="&ds"; + run; +%end; + +%mend dc_gettableid; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getusergroups.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getusergroups.sas new file mode 100644 index 0000000..bcc958a --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getusergroups.sas @@ -0,0 +1,21 @@ +/** + @file dc_getgroups.sas + @brief Gets all groups + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getgroups.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusergroups(user=,outds=mm_getgroups); + %global dc_repo_users; + %if &dc_repo_users= %then %let dc_repo_users=foundation; + %mm_getgroups(user=&user,outds=&outds,repo=&dc_repo_users) +%mend dc_getusergroups; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_getusers.sas b/sas/sasjs/targets/sas9/macros_meta/dc_getusers.sas new file mode 100644 index 0000000..fe4b32d --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_getusers.sas @@ -0,0 +1,47 @@ +/** + @file dc_getusers.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mm_getusers.sas + @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusers(outds=mm_getlibs); + +/* take current repository */ +%local repo repocnt x; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + where repositorytype in('CUSTOM','FOUNDATION') + & upcase(name) ne "%upcase(&repo)"; + keep id name ; + call symputx(cats('repo',_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; +%put _local_; + +%mm_getusers(outds=&outds) +%do x=1 %to &repocnt; + options metarepository=&&repo&x; + %mm_getusers(outds=&outds.a) + proc append base=&outds data=&outds.a; + run; +%end; + +options metarepository=&repo; + +%mend dc_getusers; diff --git a/sas/sasjs/targets/sas9/macros_meta/dc_refreshcatalog.sas b/sas/sasjs/targets/sas9/macros_meta/dc_refreshcatalog.sas new file mode 100644 index 0000000..4fe8293 --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/dc_refreshcatalog.sas @@ -0,0 +1,80 @@ +/** + @file dc_refreshcatalog.sas + @brief Refresh catalog + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces are the same. This version is META. + + The MPELIB should be pre-assigned + +

SAS Macros

+ @li mpe_refreshlibs.sas + @li dc_assignlib.sas + @li mpe_refreshtables.sas + @li mm_getrepos.sas + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_refreshcatalog(libref); + +/* take current repository */ +%local repo repocnt xx; +%let repo=%sysfunc(getoption(metarepository)); + +/* get list of repositories and filter */ +%mm_getrepos(outds=repos) +%let repocnt=0; +data repos; + set repos; + put (_all_)(=); + where repositorytype in('CUSTOM','FOUNDATION'); + keep id name ; + call symputx(cats('repo',_n_),name,'l'); + call symputx('repocnt',_n_,'l'); +run; +%put &sysmacroname #&libref#; + +%if #&libref# ne ## %then %do; + %put &sysmacroname: assigning specific libref, &libref; + %dc_assignlib(WRITE,&libref) /* write just in order to assign direct lib */ + %mpe_refreshlibs(lib=&libref) + %mpe_refreshtables(&libref) +%end; +%else %do xx=1 %to &repocnt; + options metarepository=&&repo&xx; + %mpe_refreshlibs() + + /* get libs to be ignored */ + %local ignorelist; + proc sql noprint; + select var_value into: ignorelist + from &mpelib..MPE_CONFIG + where var_scope='DC_CATALOG' + and var_name="DC_IGNORELIBS" + and &dc_dttmtfmt. < TX_TO + and var_active=1; + + /* get all libs */ + %let libcnt=0; + data libraries; + set &mpelib..mpe_datacatalog_libs; + where &dc_dttmtfmt. le TX_TO; + if index("&ignorelist",'|'!!upcase(trim(libref))!!'|')=0; + i+1; + call symputx(cats('lib',i),libref); + call symputx('libcnt',i); + run; + %local i; + %do i=1 %to &libcnt; + %dc_assignlib(WRITE,&&lib&i) + %mpe_refreshtables(&&lib&i) + %end; +%end; + +options metarepository=&repo; +%mend dc_refreshcatalog; diff --git a/sas/sasjs/targets/sas9/macros_meta/meta_mapper.sas b/sas/sasjs/targets/sas9/macros_meta/meta_mapper.sas new file mode 100644 index 0000000..8b34cae --- /dev/null +++ b/sas/sasjs/targets/sas9/macros_meta/meta_mapper.sas @@ -0,0 +1,412 @@ +/** + @file + @brief Perform the metadata mapping + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%macro meta_mapper( + baseds=work.allmap /* base table to contain metamapping (two level) */ + , stageds=col_meta /* temp table to append to base*/ + , metaid=OMSOBJ:Column\A5HOSDWY.BF00LWQT + , direction=REVERSE /* either REVERSE or FORWARDS */ + , level=0 /* system var - show level of nesting */ + , job= /* system var - avoid looping same source */ + , levelcheck=50 /* system var - avoid going too deep down the rabbit hole */ + , append=NO /* system var - when YES means appending within nested loop */ + ); + %if &level>&levelcheck %then %return; + %put &sysmacroname entry vars:; + %put _local_; + + %if &direction=REVERSE %then %do; + %let start=Target; + %let finish=Source; + %end; + %else %do; + %let start=Source; + %let finish=Target; + %end; + + %if &append=NO %then %do; + proc datasets lib=work; + delete %scan(&baseds,2,.); + quit; + %let index_statement=(index=(HASH/unique)); + %end; + %else %let index_statement=; + + data &stageds &index_statement ; + length HASH $32 + jobname sourcetablename sourcecolname sourcecoluri + map_type map_transform targettablename targetcolname targetcoluri + uri targettableuri tfmuri sourcetableuri scuri tpuri tmpuri mturi $256 + Derived_Rule $500 Marker_ID Name_ID N_Name LibRef engine sourcePublicType + targetPublicType $64; + keep HASH jobname sourcetablename sourcecolname sourcecoluri + map_type map_transform + targettablename targetcolname targetcoluri Derived_Rule level; + + /* proc transpose logic only */ + length sourceshorttablename sourcemembertype sourcelocation + assoc assocuri name sturi foundrefuri foundfinishuri + targetshorttablename targetlocation targetmembertype trafoName $256 + sourceshorttableuri sourceshortcoluri checkrdm targetshorttableuri + targetshortcoluri selected_direction $17 + lturi _location $200; + + call missing (of _all_); + &start.coluri="&METAID"; + level=&level; + /* first get table associated with the column */ + if metadata_getnasn(&start.coluri,'Table',1,&start.tableuri)=0 then do; + putlog "ERR" "OR: Table not found"; + stop; + end; + rc=metadata_getattr(&start.tableuri,"Name",&start.tablename); + rc=metadata_getattr(&start.coluri,"Name",&start.colname); + rc=metadata_getattr(&start.tableuri,'PublicType',&start.PublicType); + + if (metadata_getnasn(&start.tableuri, "TablePackage",1, tpuri)>0) then + do; + rc=metadata_getattr(tpuri,"Libref",LibRef); + rc=metadata_getattr(tpuri,"Engine",engine); + if missing(libref) then do; + rc=metadata_getnasn(tpuri, "UsedByPackages",1, tmpuri); + rc=metadata_getattr(tmpuri,"Libref",LibRef); + rc=metadata_getattr(tmpuri,"Engine",engine); + end; + &start.tablename=cats( + upcase(LibRef),'-',upcase(engine),'.',&start.tablename + ); + end; + else if (&start.PublicType="ExternalFile") then do; + rc=metadata_getnasn(&start.tableuri, "OwningFile",1, tmpuri); + rc=metadata_getnasn(tmpuri, "FileRefs",1, tmpuri); + rc=metadata_getnasn(tmpuri, "FileRefLocations",1, tmpuri); + rc=metadata_getattr(tmpuri,'FileName',&start.tablename); + end; + else &start.tablename = 'work. '||trim(lowcase(&start.tablename)); + /* now loop the Source / TargetFeatureMaps */ + tfm=1; + do while(metadata_getnasn(&start.coluri,"&start.FeatureMaps",tfm,tfmuri)>0); + call missing(derived_rule); + rc=metadata_getattr(tfmuri,'TransformRole',map_type); + + /* get job and step name */ + if (metadata_getnasn(tfmuri,'AssociatedClassifierMap',1,tmpuri)<1) then + do; + rc=metadata_getnasn(tfmuri,"&finish.Transformations",1,tmpuri); + rc=metadata_getnasn(tmpuri,'AssociatedClassifierMap',1,tmpuri); + end ; + rc=metadata_getnasn(tmpuri,'Steps',1,tmpuri); + rc=metadata_getattr(tmpuri,'Name',map_transform); + rc=metadata_getnasn(tmpuri,'Activities',1,tmpuri); + rc=metadata_getnasn(tmpuri,'Jobs',1,tmpuri); + rc=metadata_getattr(tmpuri,'Name',jobname); + + if Map_Type = 'DERIVED' then do; + if(metadata_getnasn(tfmuri,"SourceCode",1, scuri)>0) then do; + /* standard */ + mturi=tfmuri; + end; + else do; + /* some SQL joins store transform rules elsewhere */ + rc=metadata_getnasn(tfmuri,"Feature&start.s",1, tmpuri); + if (metadata_getnasn(tmpuri,"Variables",1, tmpuri)>0) + then rc=metadata_getnasn(tmpuri,"OwningTransformation",1, mturi); + else rc=metadata_getnasn(tfmuri,"Transformation&start.s",1, mturi); + rc=metadata_getnasn(mturi,"SourceCode",1, scuri); + end; + + rc=metadata_getattr(scuri,"StoredText",Derived_Rule); + Derived_Rule = compress(Derived_Rule,'0A'x); + + /* loop to generate derived rule (swap ref numbers for col descs) */ + sv=1; + do while(metadata_getnasn(mturi,"SubstitutionVariables",sv,tmpuri)>0); + rc=metadata_getattr(tmpuri,"Marker",Marker_ID); + rc=metadata_getattr(tmpuri,"Name",Name_ID); + N_Name = compress(scan(Name_ID,2,'-')); + Derived_Rule=tranwrd( + Derived_Rule,compress(Marker_ID),compress(N_Name) + ); + sv+1; + end; + end; + /* get source col attributes */ + fs=1; + do while(metadata_getnasn(tfmuri,"Feature&finish.s",fs,&finish.coluri)>0); + rc=metadata_getattr(&finish.coluri,'Name',&finish.colname); + rc=metadata_getnasn(&finish.coluri,'Table',1,&finish.tableuri); + rc=metadata_getattr(&finish.tableuri,'Name',&finish.tablename); + rc=metadata_getattr(&finish.tableuri,'PublicType',&finish.PublicType); + + if (metadata_getnasn(&finish.tableuri,"TablePackage",1,tpuri)>0) then + do; + rc=metadata_getattr(tpuri,"Libref",LibRef); + rc=metadata_getattr(tpuri,"Engine",engine); + if missing(libref) then do; + rc=metadata_getnasn(tpuri, "UsedByPackages",1, tmpuri); + rc=metadata_getattr(tmpuri,"Libref",LibRef); + rc=metadata_getattr(tmpuri,"Engine",engine); + end; + &finish.tablename=cats( + upcase(LibRef),'-',upcase(engine),'.',&finish.tablename + ); + end; + else if (&finish.PublicType="ExternalFile") then do; + rc=metadata_getnasn(&finish.tableuri, "OwningFile",1, tmpuri); + rc=metadata_getnasn(tmpuri, "FileRefs",1, tmpuri); + rc=metadata_getnasn(tmpuri, "FileRefLocations",1, tmpuri); + rc=metadata_getattr(tmpuri,'FileName',&finish.tablename); + end; + else &finish.tablename=compress('work.'||lowcase(&finish.tablename)); + + /* do a lookup to see if this record has been loaded before, + IF base table exists */ + hash=put(md5( + cats(jobname,sourcecoluri,map_type,map_transform,targetcoluri) + ),$hex32.); + %if %sysfunc(exist(&baseds)) %then %do; + set &baseds(keep=hash) key=hash/unique; + if _iorc_ ne 0 then do; + /* hash did not exist, hence this is a new record */ + output; + _error_=0; + end; + %end; + %else %do; + output; + %end; + fs+1; + end; + + tfm+1; + end; + + /* No finish URI found - so proceed to see if this is due to transpose */ + if missing(&finish.coluri) + and (metadata_getnasn(&start.tableuri,"&start.ClassifierMaps",1,tmpuri)>0) + then do; + length trafoname $256; + call missing(trafoName); + rc=metadata_getattr(tmpuri,'Name',trafoName); + + /* get &finsh.tablename and jobname */ + rc=metadata_getnasn(tmpuri,"Classifier&finish.s",1,&finish.tableuri); + rc=metadata_getattr(&finish.tableuri,'Name',&finish.tablename); + &finish.shorttablename=&finish.tablename; + rc=metadata_getnasn(tmpuri,'Steps',1,tmpuri); + rc=metadata_getnasn(tmpuri,'Activities',1,tmpuri); + rc=metadata_getnasn(tmpuri,'Jobs',1,tmpuri); + rc=metadata_getattr(tmpuri,'Name',jobname); + + rc1=1;n1=1; + do while(rc1>0); + rc1=metadata_getnasl(&finish.tableuri,n1,assoc); + if (assoc="Columns") then do; + rc2=1;n2=1; + do while(rc2>0 and missing(foundfinishuri)); + /* Walk through all column associations: SpecSourceTransformations*/ + rc2=metadata_getnasn(&finish.tableuri,trim(assoc),n2,assocuri); + /* REVERSE */ + %if ("&direction." = "REVERSE") %then %do; + if metadata_getnasn(assocuri,"SpecSourceTransformations",1,sturi)>0 + then do; + rc=metadata_getattr(sturi,"Name",name); + /* SAS Transpose: varColumns */ + if (name ="varColumns") then do; + foundfinishuri = "true"; /* do a while exit */ + put "scource colname name=" name; + put "scource colname uri=" assocuri; + &finish.coluri=assocuri; + &finish.shortcoluri=substr( + &finish.coluri,find(&finish.coluri, '\')+1 + ); + rc=metadata_getattr(&finish.coluri,'Name',&finish.colname); + rc=metadata_getnasn(&finish.coluri,'Table',1,&finish.tableuri); + rc=metadata_getattr(&finish.tableuri,'Name',&finish.tablename); + &finish.shorttablename=&finish.tablename; + map_type = "ONETOONE"; + + /* get MemberType */ + rc=metadata_getattr( + &finish.tableuri,"MemberType",&finish.membertype + ); + &finish.shorttableuri = substr( + &finish.tableuri,find(&finish.tableuri, '\')+1 + ); + rc=metadata_getattr( + &finish.shorttableuri,"PublicType",&finish.publictype + ); + + if metadata_getnasn( + &finish.shorttableuri,"TablePackage",1,tpuri + )>0 + then do; + /* init LibRef to overwrite previous for &start!!! */ + call missing (LibRef); + rc=metadata_getattr(tpuri,"Libref",LibRef); + rc=metadata_getattr(tpuri,"Engine",engine); + if missing(libref) then do; + rc=metadata_getnasn(tpuri, "UsedByPackages",1, tmpuri); + rc=metadata_getattr(tmpuri,"Libref",LibRef); + rc=metadata_getattr(tmpuri,"Engine",engine); + end; + &finish.shorttablename=&finish.tablename; + &finish.tablename=cats( + upcase(LibRef),'-',upcase(engine),'.',&finish.tablename + ); + end; + /* get SAS Folder location of the table */ + if &finish.publictype eq "Table" then do; + lturi=&finish.shorttableuri; + rc=metadata_getnasn(lturi,"Trees",1,lturi); + rc=metadata_getattr(lturi,"Name",&finish.location); + tree=1; + do while (tree>0); + tree=metadata_getnasn(lturi,"ParentTree",1,lturi); + if tree > 0 then do; + rc=metadata_getattr(lturi,"Name",_location); + &finish.location=catx('/',_location,&finish.location); + end; + end; + &finish.location = '/'||&finish.location; + end; + map_transform = trafoName; + derived_rule = "Transpose vertical"; + /* do a lookup to see if this record has been loaded before, + IF base table exists */ + hash=put(md5( + cats(jobname,sourcecoluri,map_type,map_transform,targetcoluri) + ),$hex32.); + %if %sysfunc(exist(&baseds)) %then %do; + set &baseds(keep=hash) key=hash/unique; + if _iorc_ ne 0 then do; + /* hash did not exist, hence this is a new record */ + output; + _error_=0; + end; + %end; + %else %do; + output; + %end; + end; /* (name = "_VALUE_COLUMN") */ + end; /* (metadata_getnasn(assocuri2,"Spec&finish.xxx",1,sturi)>0) */ + %end; /* &direction = "REVERSE" */ + /* FORWARDS: if TargetFeatureMaps not available: -> target! */ + %if ("&direction." = "FORWARDS") %then %do; + if (metadata_getnasn(assocuri,"TargetFeatureMaps",1,sfuri)<0) + then do; + rc=metadata_getattr(assocuri,"Name",name); + if not missing(assocuri) then do; + put "target colname name=" name; + put "target colname uri=" assocuri; + &finish.coluri=assocuri; + &finish.shortcoluri=substr( + &finish.coluri,find(&finish.coluri, '\')+1 + ); + rc=metadata_getattr(&finish.coluri,'Name',&finish.colname); + rc=metadata_getnasn(&finish.coluri,'Table',1,&finish.tableuri); + rc=metadata_getattr(&finish.tableuri,'Name',&finish.tablename); + &finish.shorttablename=&finish.tablename; + map_type = "ONETOMANY"; + + /* get MemberType */ + rc=metadata_getattr( + &finish.tableuri,"MemberType",&finish.membertype + ); + &finish.shorttableuri = substr( + &finish.tableuri,find(&finish.tableuri, '\')+1 + ); + rc=metadata_getattr( + &finish.shorttableuri,"PublicType",&finish.publictype + ); + + if metadata_getnasn( + &finish.shorttableuri,"TablePackage",1,tpuri + )>0 + then do; + /* init LibRef to overwrite previous for &start!!! */ + call missing (LibRef); + rc=metadata_getattr(tpuri,"Libref",LibRef); + rc=metadata_getattr(tpuri,"Engine",engine); + if missing(libref) then do; + rc=metadata_getnasn(tpuri, "UsedByPackages",1, tmpuri); + rc=metadata_getattr(tmpuri,"Libref",LibRef); + rc=metadata_getattr(tmpuri,"Engine",engine); + end; + &finish.shorttablename=&finish.tablename; + &finish.tablename=cats( + upcase(LibRef),'-',upcase(engine),'.',&finish.tablename + ); + end; + /* get table's SAS Folder location */ + if &finish.publictype eq "Table" then do; + lturi=&finish.shorttableuri; + rc=metadata_getnasn(lturi,"Trees",1,lturi); + rc=metadata_getattr(lturi,"Name",&finish.location); + tree=1; + do while (tree>0); + tree=metadata_getnasn(lturi,"ParentTree",1,lturi); + if tree > 0 then do; + rc=metadata_getattr(lturi,"Name",_location); + &finish.location=catx('/',_location,&finish.location); + end; + end; + &finish.location = '/'||&finish.location; + end; + map_transform = trafoName; + derived_rule = "Transpose horizontal"; + /* do a lookup to see if this record has been loaded before, + IF base table exists */ + hash=put(md5( + cats(jobname,sourcecoluri,map_type,map_transform,targetcoluri) + ),$hex32.); + %if %sysfunc(exist(&baseds)) %then %do; + set &baseds(keep=hash) key=hash/unique; + if _iorc_ ne 0 then do; + /* hash did not exist, hence this is a new record */ + output; + _error_=0; + end; + %end; + %else %do; + output; + %end; + end; + end; + %end; /* (&direction = "FORWARDS" */ + + call missing(assocuri); + n2+1; + end; /* while(rc1>0) */ + end; /* (assoc="Columns") */ + call missing(assoc); + n1+1; + end; /* while(rc1>0) */ + end; /* missing(&finish.coluri) */ + /* ################# end mapping for Transpose flat ################# */ + + stop; + run; + + proc append base=&baseds data=&stageds; + run; + + data _null_; + set &stageds; + call execute('%meta_mapper(metaid='!!&finish.coluri + !!",baseds=&baseds" + !!",direction=&direction" + !!",level=%eval(&level+1)" + !!",levelcheck=&levelcheck" + !!",job="!!jobname + !!",append=YES)"); + run; + +%mend meta_mapper; diff --git a/sas/sasjs/targets/sas9/services_meta/admin/configurator.sas b/sas/sasjs/targets/sas9/services_meta/admin/configurator.sas new file mode 100644 index 0000000..5f126d6 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/admin/configurator.sas @@ -0,0 +1,226 @@ +/** + @file + @brief provides the web service to create the control tables + @details + +

SAS Macros

+ @li dc_getusergroups.sas + @li mf_getuser.sas + @li mf_getapploc.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%let root=%mf_getapploc(); + +/* create web page */ +data _null_; + file _webout; + infile datalines ; + input; + put _infile_; +datalines4; + + + + + Data Controller + + + + + +
+
+ + Data Controller +
+
+
+
+
+
+ +
+
+Terms and Conditions +
+
+
+

Due to the way the Demo version is compiled (in an easy-to-deploy but + inefficient-to-run format), it should not be deployed to production servers. + Before proceeding with configuration, please confirm that you have read, + understood, and agreed to the + Data Controller for SAS© Evaluation Agreement. +

+
+
+ > + +
+
+
+ + +
+
+
+ + +;;;; +run; diff --git a/sas/sasjs/targets/sas9/services_meta/admin/makedata.sas b/sas/sasjs/targets/sas9/services_meta/admin/makedata.sas new file mode 100644 index 0000000..77eafda --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/admin/makedata.sas @@ -0,0 +1,248 @@ +/** + @file + @brief service for creating the configuration tables in DEMO mode. + @details + STP for creating the configuration tables in DEMO mode. + It also adds the STAGING directory as subdirectory to the BASE + library location. + Note - the CURLIB var is added during the build process. + + @warning This STP self destructs! It will delete itself after a successful run + to avoid being executed twice (and overwriting actual data) + + +

SAS Macros

+ @li mf_getapploc.sas + @li mf_getuser.sas + @li mf_mkdir.sas + @li mm_createdocument.sas + @li mm_createlibrary.sas + @li mm_createstp.sas + @li mm_deletedocument.sas + @li mm_deletestp.sas + @li mm_getstpcode.sas + @li mm_getstpinfo.sas + @li mp_abort.sas + @li mp_init.sas + @li mpe_makedata.sas + @li mpe_makedatamodel.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mp_init() + +%global admin repo path; /* URL params from configurator */ +%let repo=%sysfunc(coalescec(&repo,Foundation)); +%let admin=%sysfunc(coalescec(&admin,dc-admin)); +%let dcpath=%sysfunc(coalescec(&path,NOTFOUND)); + +%mp_abort(iftrue= ("&dcpath" = "NOTFOUND") + ,mac=&_program + ,msg=%str(PATH variable was not provided) +) + +%let root=%mf_getapploc(); +%let work=%sysfunc(pathname(work)); +%let dc_libref=%upcase(DC%substr(%sysevalf(%sysfunc(datetime())/60),3,6)); +%let DC_LIBNAME=Data Controller(&dc_libref); +%let dcpath=&dcpath/&dc_libref; +%put _all_; + +%mf_mkdir(&dcpath/dc_staging) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Unable to create &dcpath using &sysuserid) +) + + +/* check we have the admin rights to update the items in the Admin folder */ +%mm_createdocument(tree=&root/services/admin,name=permTest) +%mm_deletedocument(target=&root/services/admin/permTest) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(User &_metaperson does not have WriteMetadata on metadata folder: + &root ) +) + +/* check we have physical permissions to the DCLIB folder */ +data _null_; + putlog "dcpath=&dcpath/permTest.txt"; + putlog "sysuserid=&sysuserid"; +data _null_; + file "&dcpath/permTest.txt"; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(User &sysuserid does not have WRITE permissions on physical + directory: &dcpath ) +) +filename delfile "&dcpath/permTest.txt"; +data _null_; + rc=fdelete('delfile'); +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt ) +) + +/* get the server context from the current STP */ +%mm_getstpinfo(&_program,outds=work.stpinfo) +data _null_; + set work.stpinfo; + call symputx('serverContext',serverContext); +run; + +/* create the library */ +%mm_createlibrary( + libname=&DC_LIBNAME + ,libref=&dc_libref + ,libdesc=Data Controller for SAS configuration tables + ,engine=BASE + ,tree=&root/data + ,servercontext=&serverContext + ,directory=&dcpath + ,mDebug=1 +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Unable to create &dc_libref library) +) + +/* assign the library */ +libname &dc_libref "&dcpath"; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Unable to assign the &dc_libref library) +) + +/* make the tables */ + +/* SASAdministrators */ +%mpe_makedatamodel(lib=&dc_libref) +%mpe_makedata(lib=&DC_LIBREF,mpeadmins=&admin,path=%str(&dcpath)) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem creating tables in &DC_LIBREF library\n + SYSERRORTEXT=&SYSERRORTEXT \n + SYSWARNINGTEXT=&SYSWARNINGTEXT) +) + +/* register tables in metadata */ +proc metalib; + omr (library="&DC_LIBNAME"); + folder="&root/data"; + update_rule=(delete); +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem registering metadata for tables in &DC_LIBREF library \n + os user=&sysuserid \n + metaperson=%mf_getuser() \n + SYSERRORTEXT=&SYSERRORTEXT \n + SYSWARNINGTEXT=&SYSWARNINGTEXT + ) +) + + +/* finally, update the app component. The user will need WM perms for this. */ +data _null_; + file "&work/settings.sas" mod ; + put ' '; + put '%global DC_LIBREF DC_LIBNAME DC_LIBLOC DC_STAGING_AREA DC_ADMIN_GROUP'; + put ' DC_REPO_USERS DC_DTTMTFMT DC_MACROS;'; + put ' '; + put '/* This metadata library (libref) contains control datasets for DC */'; + put '/* If a different libref must be used, configure it below */'; + put '%let DC_LIBREF=' "&DC_LIBREF;"; + put '%let DC_LIBNAME=' "&DC_LIBNAME;"; + put '%let DC_LIBLOC=' "&dcpath;"; + put ' '; + put 'libname &DC_LIBREF "&dc_libloc";'; + put ' '; + put '/* This metadata group has unrestricted access to Data Controller */'; + put '%let dc_admin_group=' "&admin;"; + put ' '; + put '/* This repository is used to query for users and groups */'; + put '%let dc_repo_users=' "&repo;"; + put ' '; + put '/* This physical location is used for staging data and audit history */'; + put '%let dc_staging_area=&dc_libloc/dc_staging;'; + put ' '; + put 'data _null_;'; + put ' set &DC_LIBREF..mpe_config(where=('; + put ' var_scope="DC" '; + put ' and &dc_dttmtfmt. lt tx_to'; + put ' and var_active=1'; + put " ));"; + put " call symputx(var_name,var_value,'G');"; + put ' putlog var_name "=" var_value;'; + put "run;"; + put ' '; + put '/* to override any DC macros with client versions, place them below */'; + put 'options insert=(sasautos=("&dc_macros"));'; +run; +/* + put 'data _null_;'; + put ' length lib_uri up_uri path $256;'; + put ' call missing (of _all_);'; + put ' rc=metadata_getnobj("omsobj:SASLibrary?@Libref =''&dc_libref''",1,lib_uri);'; + put ' rc=metadata_getnasn(lib_uri,"UsingPackages",1,up_uri);'; + put ' rc=metadata_getattr(up_uri,"DirectoryName",path);'; + put ' call symputx("dc_libloc",path);'; + put 'run;'; +*/ +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=syscc=&syscc when preparing data_controller_settings) +) + +%mm_createstp(stpname=Data_Controller_Settings + ,filename=settings.sas + ,directory=&work + ,tree=&root/services/public + ,Server=&serverContext + ,stptype=2 +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str( + Problem updating the dc_staging area in + &root/services/public/DataController Settings \n + SYSERRORTEXT=&SYSERRORTEXT \n + SYSWARNINGTEXT=&SYSWARNINGTEXT + ) +) + +data _null_; + file _webout; + put '

Data Controller Config

'; + put '

The following items have been successfully configured:

'; + put "
  • Library Location (&dcpath)
  • "; + put "
  • Table Creation (&DC_LIBREF library) using the &sysuserid identity
  • "; + put "
  • Logs Location (%trim(&dcpath)/logs)
  • "; + put "
  • Repo for users & groups (&repo)
  • "; + put "
  • Data Controller Admin Group (&admin)
  • "; + put "
"; + put "

Next Steps:

"; + put "
  1. Populate "; + put "Table Lineage
  2. "; + put "
  3. Populate"; + put "Data Catalog
  4. "; + put "
  5. Now, "; + put "hereLaunch!
"; +run; + +/* We ran successfully, now remove configurator and makedata STPs */ +%mm_deletestp(target=&root/services/admin/configurator) +%mm_deletestp(target=&_program) diff --git a/sas/sasjs/targets/sas9/services_meta/admin/makelib.sas b/sas/sasjs/targets/sas9/services_meta/admin/makelib.sas new file mode 100644 index 0000000..612dde8 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/admin/makelib.sas @@ -0,0 +1,165 @@ +/** + @file + @brief Create a demo (base engine) library + @details + Creates the library + + @warning This STP self destructs! It will delete itself after a successful run + to avoid being executed twice (and overwriting actual data) + + +

SAS Macros

+ @li mm_createlibrary.sas + @li mm_createdocument.sas + @li mm_deletedocument.sas + @li mp_abort.sas + @li dc_assignlib.sas + @li mm_deletestp.sas + @li mm_createstp.sas + @li mf_mkdir.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%global dcpath; + +%let dclib=%upcase(DC%substr(%sysevalf(%sysfunc(datetime())/60),3,6)); +%let dclibname=Data Controller(&dclib); +%let work=%sysfunc(pathname(work)); +%let dcpath=&dcpath/&dclib; + +%mf_mkdir(&dcpath) +%mf_mkdir(&work) +%put &=dcpath; + +/* check we have physical permissions to the DCLIB folder */ +data _null_; + file "&dcpath/permTest.txt"; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(User &sysuserid does not have WRITE permissions on physical + directory: &dcpath ) +) +filename delfile "&dcpath/permTest.txt"; +data _null_; + rc=fdelete('delfile'); +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt ) +) + + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Unable to write to &dcpath) +) + + +data _null_; + pgm="&_program"; + rootlen=length(trim(pgm))-length("/services/admin/makelib"); + root=substr(pgm,1,rootlen); + putlog root=; + call symputx('deploy_dir',root); +run; + +options noquotelenmax ps=max; + +/* check we have the admin rights to update the items in the Admin folder */ +%mm_createdocument(tree=&deploy_dir/services/admin,name=permTest) +%mm_deletedocument(target=&deploy_dir/services/admin/permTest) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(User &_metaperson does not have WriteMetadata on SAS folder: + &deploy_dir ) +) + +/** + * Create library and load data + */ +%let mpelibname=Data Controller (&dclib); +%mm_createlibrary( + libname=&mpelibname + ,libref=&dclib + ,libdesc=Configuration tables for the MacroPeople Data Controller application + ,engine=BASE + ,tree=&deploy_dir/data + ,servercontext=SASApp + ,directory=&dcpath + ,mDebug=1) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Unable to create &dclib library) +) + +/* get direct libref */ +%dc_assignlib(READ,&dclib) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Unable to assign &dclib library) +) + + +/* create an initial settings service (this will be overwritten in the + data update step) +*/ + +%let temploc=&work/temp.txt; +data _null_; + file "&temploc" ; + put '/* Data Controller Precode */' / / ; + put ' '; + put 'options noquotelenmax ps=max;'; + put '%global DC_LIBREF DC_LIBNAME;'; + put ' '; + put '/* This metadata library (libref) contains control datasets for DC */'; + put '/* If a different libref must be used, configure it below */'; + put '%let DC_LIBREF=' "&dclib;"; + put '%let DC_LIBNAME=' "&mpelibname;"; + put ' '; + put '/* get physical path for direct libname - needed to track requests */'; + put 'data _null_;'; + put ' length lib_uri up_uri path $256;'; + put ' call missing (of _all_);'; + put ' rc=metadata_getnobj("omsobj:SASLibrary?@Libref=''&dc_libref''",1,lib_uri);'; + put ' rc=metadata_getnasn(lib_uri,"UsingPackages",1,up_uri);'; + put ' rc=metadata_getattr(up_uri,"DirectoryName",path);'; + put ' call symputx("dc_libloc",path);'; + put 'run;'; + put 'libname &DC_LIBREF "&dc_libloc";'; + put ' '; +run; + +%mm_deletestp(target=&deploy_dir/services/public/Data_Controller_Settings) + +%mm_createstp(stpname=Data_Controller_Settings + ,filename=temp.txt + ,directory=&work + ,tree=&deploy_dir/services/public + ,Server=SASApp + ,stptype=2 + ,mdebug=1 + ,stpdesc=Data Controller Configuration + ,minify=NO) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Issue creating settings stp) +) + +data _null_; + file _webout; + put "

Library &dclib successfully assigned

"; +run; diff --git a/sas/sasjs/targets/sas9/services_meta/admin/refreshtablelineage.sas b/sas/sasjs/targets/sas9/services_meta/admin/refreshtablelineage.sas new file mode 100644 index 0000000..3a78176 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/admin/refreshtablelineage.sas @@ -0,0 +1,203 @@ +/** + @file refreshtablelineage.sas + @brief updates the table level lineage + @details extracts all sources/targets from every job + +

SAS Macros

+ @li mpeinit.sas + @li bitemporal_dataloader.sas + @li mp_binarycopy.sas + @li mf_getuniquefileref.sas + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +/* get list of libraries */ +%let fileref1=%mf_getuniquefileref(); +filename &fileref1 temp; +proc metadata in= +"$METAREPOSITORY + JobSAS + + 8452 + + + + + + + + + + + + + + " + out=&fileref1 + ; +run; + +/* create an XML map and extract dependencies from response */ +%macro getTables(type=); +%local x; +%do x=1 %to 2; + %local dir; + %if &x=1 %then %let dir=Source; + %else %let dir=Target; + %local y; + %do y=1 %to 3; + %local maptype; + %if &y=1 %then %let maptype=ClassifierMap; + %else %if &y=2 %then %let maptype=Select; + %else %if &y=3 %then %let maptype=Join; + + filename sxlemap temp; + data _null_; + file sxlemap; + put ''; + put ""; + put ""; + put "/GetMetadataObjects/Objects/Job/JobActivities/TransformationActivi"@; + put "ty/Steps/TransformationStep/Transformations/&maptype/Classifier"@; + put "&dir.s/&type"; + put ''; + put "/GetMetadataObjects/Objects/Job/@Id"; + put "characterstring17"; + put ''; + put ''; + put "/GetMetadataObjects/Objects/Job/@Name"; + put "characterstring128"; + put ''; + put ''; + put "/GetMetadataObjects/Objects/Job/JobActivities"@; + put "/TransformationActivity/@Id"; + put "characterstring17"; + put ''; + put ''; + put "/GetMetadataObjects/Objects/Job/JobActivities"@; + put "/TransformationActivity/Steps/TransformationStep/@Id"; + put "characterstring17"; + put ''; + put ''; + put "/GetMetadataObjects/Objects/Job/JobActivities"@; + put "/TransformationActivity/Steps/TransformationStep/Transformations"@; + put "/&maptype/@Id"; + put "characterstring17"; + put ''; + put ""; + put "/GetMetadataObjects/Objects/Job/JobActivities"@; + put "/TransformationActivity/Steps/TransformationStep/Transformations/"@; + put "&maptype/Classifier&dir.s/&type/@Id"; + put "characterstring17"; + put ''; + put '
'; + + run; + libname _XML_ xml xmlfileref=&fileref1 xmlmap=sxlemap; + + data work.&dir.&type/view=work.&dir.&type; + set _xml_.&dir.&type; + length tabletype maptype $16 tabledirection $1; + jobname=upcase(jobname); + tabletype="&type"; + maptype="&maptype"; + if "&dir"="Source" then tabledirection="R"; + else tabledirection='F'; + run; + proc append base=work.alldata data=work.&dir.&type; + run; + + libname _XML_ clear; + %end; +%end; +%mend getTables; + +/* list of types: +https://support.sas.com/documentation/cdl/en/omamodref/63903/HTML/default/viewer.htm#classifiermap.htm +*/ +%getTables(type=PhysicalTable) +%getTables(type=ExternalTable) +%getTables(type=QueryTable) +%getTables(type=RelationalTable) +%getTables(type=Report) +%getTables(type=Cube) +%getTables(type=DataTable) + +/* remove dups and get tables */ +proc sort data=work.alldata(keep=jobid jobname tableid tabletype tabledirection) + out=work.sorted nodupkey; + by _all_; +run; +proc sort data=work.sorted(keep=tableid) out=work.tables nodupkey; + by tableid; +run; + +/* this bit is slow due to lookups but given the different table types + it was the easiest approach */ +data work.tables2; + length tablename liburi puri $64 libref schemaname $8 ; + if _n_=1 then call missing(tablename, liburi, puri, libref, schemaname); + set work.tables; + drop rc liburi; + if metadata_getnasn(tableid,"TablePackage",1,liburi)>0 then do; + rc= metadata_getattr(liburi, "SchemaName", SchemaName); + if ^missing(SchemaName) then do; + if metadata_getnasn(liburi,"UsedByPackages",1,puri)>0 then do; + rc=metadata_getattr(puri,"Libref",libref); + end; + end; + else rc=metadata_getattr(liburi,"Libref",libref); + libref=upcase(libref); + end; + rc=metadata_getattr(tableid,"Name",tablename); + tablename=upcase(tablename); +run; +proc sql; +create table work.augmented as + select a.* + ,b.tablename + ,b.libref + from work.sorted a + left join work.tables2 b + on a.tableid=b.tableid; + +create table work.mpe_lineage_tabs as + select distinct + coalesce(a.jobid,b.jobid) as jobid, + coalesce(a.jobname,b.jobname) as jobname, + coalesce(a.tableid,"N/A") as srctableid, + a.tabletype as srctabletype, + a.tablename as srctablename, + coalesce(a.libref,'nolib') as srclibref, + coalesce(b.tableid,"N/A") as tgttableid, + b.tabletype as tgttabletype, + b.tablename as tgttablename, + coalesce(b.libref,'nolib') as tgtlibref + from work.augmented(where=(tabledirection='R')) a + full join work.augmented(where=(tabledirection='F')) b + on a.jobid=b.jobid + ; + + +%bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=MPE_LINEAGE_TABS + ,append_dsn=MPE_LINEAGE_TABS + ,PK=jobid srctableid tgttableid + ,etlsource=&_program + ,loadtype=TXTEMPORAL + ,tech_from=TX_FROM + ,tech_to=TX_TO + ,dclib=&mpelib +) + +%mp_binarycopy(inref=&fileref1, outref=_webout) diff --git a/sas/sasjs/targets/sas9/services_meta/lineage/fetchcollineage.sas b/sas/sasjs/targets/sas9/services_meta/lineage/fetchcollineage.sas new file mode 100644 index 0000000..6c5e062 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/lineage/fetchcollineage.sas @@ -0,0 +1,349 @@ +/** + @file + @brief fetch the metadata and server as dotlang + + Some nice ideas for formatting are available here: + https://renenyffenegger.ch/notes/tools/Graphviz/examples/index + +

SAS Macros

+ @li mp_abort.sas + @li mf_getuser.sas + @li bitemporal_dataloader.sas + @li meta_mapper.sas + + @version 9.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%global column_id direction refresh; + +/* enable col id and direction to be passed as url params */ +%let exist=%sysfunc(exist(work.SASControlTable)); +%let inds=%sysfunc(ifc(&exist=1,SASControlTable,_null_)); +%let max_depth=50; +%put &=inds; +data _null_; + length max_depth $ 8; + set &inds; + call symputx('column_id',coluri); + call symputx('direction',direction); + call symputx('refresh',refresh); + if input(max_depth,8.)>0 then call symputx('max_depth',max_depth); + putlog (_all_)(=); +run; +%put &=max_depth &=refresh; + +data info; + length coluri colname taburi tabname liburi libref $256; + call missing(of _all_); + if metadata_getattr("&column_id","Name",colname)<0 then do; + putlog "Col &column_id not found"; + call symputx('syscc','1234'); + stop; + end; + rc=metadata_getnasn("&column_id","Table",1,taburi); + rc=metadata_getattr(taburi,"Name",tabname); + rc=metadata_getnasn(taburi,"TablePackage",1,liburi); + rc=metadata_getattr(liburi,"Libref",libref); + call symputx('lib',libref); + call symputx('tab',tabname); + call symputx('col',colname); +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + + +%macro launcher(); +/* check whether a lineage run already taken place */ +proc sql noprint; +create table existing_data as + select * from &mpelib..mpe_lineage_cols + where col_id="&column_id" + and direction="%substr(&direction,1,1)"; + +/* no data, so make some, and append it */ +%if &sqlobs=0 or &refresh=1 %then %do; + %meta_mapper(metaid=&column_id + , direction=&direction /* either REVERSE or FORWARDS */ + , baseds=work.allmap + , levelcheck=%eval(&max_depth-1) + ) + data append; + length col_id $32 direction $1 modified_by $64; + retain col_id "&column_id"; + retain direction "%substr(&direction,1,1)"; + %global modified_by modified_dttm; + %let modified_dttm=%sysfunc(datetime()); + retain modified_dttm &modified_dttm; + retain modified_by "%mf_getuser()"; + %let modified_by=%mf_getuser(); + set allmap; + drop hash; + run; + proc sort data=append out=appendme nodupkey; + by col_id direction sourcecoluri targetcoluri map_type map_transform; + run; + + %bitemporal_dataloader(base_lib=&mpelib + ,base_dsn=mpe_lineage_cols + ,append_dsn=appendme + ,PK=col_id direction sourcecoluri targetcoluri map_type map_transform + ,etlsource=&_program + ,loadtype=UPDATE + ,close_vars=col_id direction + ,dclib=&mpelib + ) +%end; +%else %do; + /* data exists, so use it */ + data work.allmap(drop=modified_by modified_dttm); + set existing_data(drop=col_id direction ); + if _n_=1 then do; + call symputx('modified_by',modified_by,'g'); + call symputx('modified_dttm',modified_dttm,'g'); + end; + where level < &max_depth; + run; +%end; +%mend launcher; + +%launcher() + +/* generate graphviz */ +filename tmp "%sysfunc(pathname(work))\GraphViz%sysfunc(datetime()).txt" + lrecl=10000 encoding='utf-8'; +options noquotelenmax; + +%macro fcmpconditional(); +%if &sysver=9.3 and &sysscp=WIN %then %do; + /* nothing - as the FCMP function causes an exception err in this case */ +%end; +%else %do; + /* prepare quick func to enable word wrapping of transformations */ + options cmplib=work.funcs; + proc fcmp outlib=work.funcs.macrocore; + function wordwrap(str $,cols,splitchar $) $; + length outstr $32767 curstr $5000; + base=0; + put str=; + do i=1 to countw(str,' ',' '); + curstr=scan(str,i,' '); + outstr=trim(outstr)!!' '!!curstr; + base=base+length(curstr)+1; + if base>cols then do; + outstr=cats(outstr,splitchar); + base=0; + end; + end; + return (outstr); + endsub; + run; +%end; +%mend fcmpconditional; +%fcmpconditional() + +/* prepare label with metadata */ +proc sql; +create table jobs as select distinct jobname as job from work.allmap ; +create table cols as select distinct upcase(scan(cat,1,'.-')) as tmplib + ,cats(calculated tmplib,'.',upcase(scan(cat,2,'.'))) as tmptab + ,cats(calculated tmptab,'.',upcase(col)) as col + from (select sourcetablename as cat, sourcecolname as col from work.allmap + union select targettablename as cat, targetcolname as col from work.allmap ) + having findc(tmplib,'/\')=0 and tmplib ne 'WORK'; +create table files as select distinct file + from (select sourcetablename as file from work.allmap + where findc(sourcetablename,'/\')>0 + union select targettablename as file from work.allmap + where findc(targettablename,'/\')>0 + ) ; +create table libs as select distinct tmplib as lib from cols; +create table tabs as select distinct tmptab as tab from cols; + +data _null_; + file tmp; + put 'digraph G { + concentrate=true; + node [style=filled,shape=plain]; + labelloc = "t"; + '; + label= "label=< + + + + + + +
&direction Lineage for &col
Library:
&libGenerated by:&modified_by
Table:&tabGenerated on: + %sysfunc(round(&modified_dttm,2),datetime19.)
>"; + put label; + if "FORWARD"="&direction" then call symputx('dirdesc','Impacted'); + else call symputx('dirdesc','Source'); + + /* close out if there is no lineage */ + if nobs=0 then put 'x [label="No lineage found" shape=Mdiamond]}'; + set work.allmap nobs=nobs; + stop; +run; + + +data graphviz1; + file tmp mod; + length line arrow $1000 stab ttab slib tlib $100 sbox tbox tooltip $500; + if _n_=1 then call missing(line, sbox, tbox, tooltip); + set work.allmap ; + + sourceid=sourcecoluri; + targetid=targetcoluri; + + if index(sourcetablename,':') then do; + slib=''; + stab=sourcetablename; + end; + else if map_transform='File Reader' then do; + stab=scan(sourcetablename,-1,'/\'); + slib=subpad(sourcetablename,1,length(sourcetablename)-length(stab)); + end; + else do; + slib=scan(sourcetablename,1,'.'); + stab=scan(sourcetablename,2,'.'); + end; + + if index(targettablename,':') then do; + tlib=''; + ttab=targettablename; + end; + else if map_transform='File Reader' then do; + ttab=scan(targettablename,-1,'/\'); + tlib=subpad(targettablename,1,length(targettablename)-length(ttab)); + end; + else do; + tlib=scan(targettablename,1,'.'); + ttab=scan(targettablename,2,'.'); + end; + + if trim(derived_rule) ne '' then do; + derived_rule=tranwrd(derived_rule,'"','\"'); + %macro quick(); + %if "&sysver"="9.3" and "&sysscp"="WIN" %then %do; + arrow=cats('[color=Red, fontcolor=Red, penwidth="3", arrowsize="2",' + ,'label=">>',map_transform,'<<\n',derived_rule,'"]'); + %end; + %else %do; + arrow=cats('[color=Red, fontcolor=Red, penwidth="3", arrowsize="2",' + ,'label=">>',map_transform,'<<\n',wordwrap(derived_rule,24,'\n'),'"]'); + %end; + %mend quick; %quick() + end; + else arrow=cats('[ label="',map_transform,'"]'); + + source=quote(strip(sourceid)); + target=quote(strip(targetid)); + + put ' ' source ' -> ' target arrow; + +run; + +data graphviz2 (keep=id tab lib col tooltip map_transform); + set graphviz1 (rename=(source=id stab=tab slib=lib sourcecolname=col )) + graphviz1 (rename=(target=id ttab=tab tlib=lib targetcolname=col )); + + if upcase(lib)=:'WORK' then tooltip=cats(',tooltip="Job:',jobname,'"'); + else tooltip=''; +run; +proc sort data=graphviz2 out=graphviz3 noduprec; by _all_; run; + +data _null_; + length shape $100 ; + set graphviz3 end=last; + file tmp mod; + tab=tranwrd(tab,'\','\\'); + tab=tranwrd(tab,'&','&'); + lib=tranwrd(lib,'&','&'); + if upcase(lib)=:'WORK' then do; + lib='WORK'; + put id '[label=<
Table' tab + '
Column' col + '
> ,fillcolor=lightgrey, shape=" " ' tooltip ']'; + end; + else if map_transform='File Reader' then do; + put id '[label="Location: ' lib '\nFile:' tab '\nColumn: ' col + '",shape=parallelogram, fillcolor="#00b300"' tooltip ']'; + end; + else do; + engine=scan(lib,2,'-'); + lib=scan(lib,1,'-'); + if engine='BASE' then fillcolour='lightyellow '; + else fillcolour='lightblue'; + shape=' shape=cylinder, fillcolor= '!!fillcolour; + + put id '[label=<
Library' lib + '
Table' tab + '
Column' col + '
> ,' shape tooltip ']'; + end; +run; + +data _null_; + file tmp mod; + /* close out if records exist */ + set work.allmap; + put '}'; + stop; +run; + +data flatdata; + length type $8 item $256; + keep type item; + set cols(in=cols) tabs(in=tabs) files(in=files) libs(in=libs) jobs(in=jobs); + + if cols then do; + type='Column'; + item=col; + end; + else if tabs then do; + type='Table'; + item=tab; + end; + else if files then do; + type='File'; + item=file; + end; + else if libs then do; + type='Library'; + item=lib; + end; + else if jobs then do; + type='Job'; + item=job; + end; +run; + +data fromSAS; + infile tmp end=last; + file tmp; + input ; + string=_infile_; + put string; +run; +filename tmp clear; + +/* get list of IDs so frontend can make a clickable list */ +proc sql; +create table ids as select distinct id from graphviz3; + +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(OBJ,ids,dslabel=clickableIDS) +%webout(OBJ,info) +%webout(OBJ,flatdata) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/lineage/fetchtablelineage.sas b/sas/sasjs/targets/sas9/services_meta/lineage/fetchtablelineage.sas new file mode 100644 index 0000000..66d5879 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/lineage/fetchtablelineage.sas @@ -0,0 +1,261 @@ +/** + @file + @brief fetch Table Lineage for SAS 9 + + Some nice ideas for formatting are available here: + https://renenyffenegger.ch/notes/tools/Graphviz/examples/index + +

SAS Macros

+ @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%global table_id direction graphOrientation; + +/* enable table id and direction to be passed as url params */ +%let exist=%sysfunc(exist(work.SASControlTable)); +%let inds=%sysfunc(ifc(&exist=1,SASControlTable,_null_)); +%put &=inds; +%let max_depth=50; +data _null_; + length max_depth $ 8; + set &inds; + call symputx('table_id',table_id); + call symputx('direction',direction); + call symputx('graphOrientation','LR'); + if max_depth>'0' then call symputx('max_depth',max_depth); + putlog (_all_)(=); +run; +%put &=max_depth; + +%mp_abort(iftrue= (&table_id=undefined) + ,mac=&_program + ,msg=%str(Table_id UNDEFINED provided from frontend) +) + +data work.info; + length tableid tablename liburi $64 libref $8; + drop rc; + tableid="&table_id"; + call missing(liburi); + rc=metadata_getattr(tableid,"Name",tablename); + if metadata_getnasn(tableid,"TablePackage",1,liburi)>0 then do; + rc=metadata_getattr(liburi,"Libref",libref); + libref=upcase(libref); + end; + tablename=upcase(tablename); + if missing(libref) then libref='nolib'; + call symputx('libds',cats(libref,'.',tablename)); +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(syscc=&syscc) +) + +%let src=%sysfunc(ifc(&direction=REVERSE,src,tgt)); +%let tgt=%sysfunc(ifc(&direction=REVERSE,tgt,src)); + +data work.sourcetable/view=work.sourcetable; + set &mpelib..MPE_LINEAGE_TABS; + where &dc_dttmtfmt. lt tx_to ; + drop tx_from tx_to; +run; + +%macro recursivejoin(iter=0 + ,maxiter=&max_depth /* avoid infinite loop */ +); +%if &iter=0 %then %do; + data work.baseds ; + retain level 0; + set work.sourcetable; + where &tgt.tableid="&table_id"; + run; + %let iter=1; + proc sql; +%end; +%else %if &iter>&maxiter %then %return; + +create table work.appendds as + select distinct &iter as level + ,b.* + from work.baseds a + left join work.sourcetable b + on a.&src.tableid=b.&tgt.tableid + where a.level=%eval(&iter.-1) + and b.&src.tableid is not null + and a.&src.tableid is not null + and a.&src.tableid ne 'N/A'; + +%let obs=&sqlobs; +insert into work.baseds select * from work.appendds; + +%if &obs %then %do; + %recursivejoin(iter=%eval(&iter.+1) ) +%end; + +%mend recursivejoin; + +%recursivejoin() + +proc sql; +create table work.final as + select distinct * + from work.baseds(drop=level) + where jobid is not null; + + +/* generate graphviz */ +filename tmp "%sysfunc(pathname(work))\GraphViz%sysfunc(datetime()).txt" + lrecl=10000 encoding='utf-8'; + +/* prepare label with metadata */ +proc sql; +create table work.jobs as + select distinct jobid + , jobname + ,quote(cats(jobid))||' [label='||quote(cats(jobname))||'];' as line + from work.final; +create table work.tables as + select distinct &src.tableid as tableid + ,&src.tablename as tablename + ,&src.libref as libref + from work.final + where &src.tableid ne 'N/A' + union select + &tgt.tableid as tableid + ,&tgt.tablename as tablename + ,&tgt.libref as libref + from work.final + where &tgt.tableid ne 'N/A' + order by libref, tablename; + +create table idlookup as + select tableid as metaid + ,'TABLE' as metatype + ,cats(libref,'.',tablename) as metaname + from work.tables +union + select jobid as metaid + ,'JOB' as metatype + ,jobname as metaname + from work.jobs + order by metaid; + + +data CRAYONS; +length attribute value $8; +infile datalines4 dsd; +input attribute value; +call symput(cats('col',_n_),quote(trim(value))); +datalines; +red,#e6194b +green,#3cb44b +blue,#4363d8 +orange,#f58231 +purple,#911eb4 +cyan,#46f0f0 +magenta,#f032e6 +lime,#bcf60c +pink,#fabebe +teal,#008080 +lavender,#e6beff +brown,#9a6324 +beige,#fffac8 +maroon,#800000 +mint,#aaffc3 +olive,#808000 +apricot,#ffd8b1 +navy,#000075 +gray,#808080 +black,#00000 +yellow,#ffe119 +white,#ffffff +;;;; +run; + +proc sort data=work.tables out=work.libs nodupkey; +by libref; +run; +data work.alllibs; + set work.libs end=last; + length line $1000. ; + crayon=symget(cats('col',_n_)); + call symputx(libref,crayon); + if _n_=1 then do; + line='subgraph cluster_libs { label="Libraries";';output; + end; + line=cats(libref)!!' [label='||quote(cats(libref))||'; style="filled"; color=' + ||cats(crayon)||', shape = Mrecord, fontcolor=white]';output; + if last then do; + line='}';output; + end; +run; + +data alltables; + length line $1000. ; + set work.tables; + crayon=symget(libref); + line=quote(cats(tableid))||' [label="'||cats(tablename) + !!'", color='!!cats(crayon) + !!', shape=cylinder,style=filled,fontcolor=white];'; + output; +run; + +proc sort + data=final(keep=&src.tableid jobid &src.libref) out=&src.relations nodupkey; + by &src.tableid jobid; +proc sort + data=final(keep=&tgt.tableid jobid &tgt.libref) out=&tgt.relations nodupkey; + by jobid &tgt.tableid; +run; + + +data srcrelations; + set srcrelations; + length line $1000; + where srctableid ne 'N/A'; + line=cats( + '"',cats(srctableid),'" -> "',jobid,'" [color=',symget(srclibref),'];' + ); +data tgtrelations; + set tgtrelations; + where tgttableid ne 'N/A'; + length line $1000; + line=cats( + '"',cats(jobid),'" -> "',tgttableid,'" [color=',symget(tgtlibref),'];' + ); +run; + +data finalfinal; +set work.alllibs(keep=line) work.alltables (keep=line) work.jobs(keep=line) + work.&src.relations(keep=line) work.&tgt.relations(keep=line) end=last; +if _N_ = 1 then do; + firstline=line; + line='strict digraph "'!!"&libds"!!'" {'; output; + line="rankdir=&graphOrientation; nodesep=0.5; node [shape = octagon];";output; + line=firstline; +end; +output; +if last then do; + line='}'; + output; +end; +drop firstline; +run; + + +%webout(OPEN) +%webout(OBJ,finalfinal) +%webout(OBJ,info) +%webout(OBJ,final,dslabel=flatdata) +%webout(OBJ,idlookup) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/lineage/getmetacols.sas b/sas/sasjs/targets/sas9/services_meta/lineage/getmetacols.sas new file mode 100644 index 0000000..cfafd00 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/lineage/getmetacols.sas @@ -0,0 +1,43 @@ +/** + @file getmetacols.sas + @brief List the cols as defined in metadata + @details Provide a table uri and get list of columns + +

SAS Macros

+ @li mm_getcols.sas + @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%global tableuri; +%let exist=%sysfunc(exist(work.SASControlTable)); +%let inds=%sysfunc(ifc(&exist=1,SASControlTable,_null_)); + +%put &=inds; + +data _null_; + set &inds; + call symputx('tableuri',scan(tableuri,-1,'\')); +run; +%put &=tableuri; +/* load parameters */ +%mm_getcols(tableuri=&tableuri,outds=metacols) + +data out; + set metacols; + keep col:; +run; + +%webout(OPEN) +%webout(OBJ,out,dslabel=metacols) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/lineage/getmetatables.sas b/sas/sasjs/targets/sas9/services_meta/lineage/getmetatables.sas new file mode 100644 index 0000000..698c550 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/lineage/getmetatables.sas @@ -0,0 +1,43 @@ +/** + @file getmetatables.sas + @brief List the tables as defined in metadata + @details Provide a library uri and get list of tables + +

SAS Macros

+ @li mm_gettables.sas + @li mp_abort.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() + +%global liburi; +%let exist=%sysfunc(exist(work.SASControlTable)); +%let inds=%sysfunc(ifc(&exist=1,SASControlTable,_null_)); + +%put &=inds; + +data _null_; + set &inds; + call symputx('liburi',liburi); +run; + +/* load parameters */ +%mm_gettables(uri=&liburi,outds=metatables,getauth=NO) + +data out; + set metatables; + keep table:; +run; + +%webout(OPEN) +%webout(OBJ,metatables) +%webout(CLOSE) + + +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/metanav/metadetails.sas b/sas/sasjs/targets/sas9/services_meta/metanav/metadetails.sas new file mode 100644 index 0000000..b2163c1 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/metanav/metadetails.sas @@ -0,0 +1,32 @@ +/** + @file metadetails.sas + @brief Retrieves metadata attributes and associations for a particular object + @details + +

SAS Macros

+ @li mm_getdetails.sas + @li mpe_getvars.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%mpe_getvars(SASControlTable, SASControlTable) + +%mm_getdetails(&objecturi + ,outattrs=work.attributes + ,outassocs=work.associations +) + +%webout(OPEN) +%webout(OBJ,attributes) +%webout(OBJ,associations) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/metanav/metaobjects.sas b/sas/sasjs/targets/sas9/services_meta/metanav/metaobjects.sas new file mode 100644 index 0000000..5c3a0b9 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/metanav/metaobjects.sas @@ -0,0 +1,31 @@ +/** + @file metaobjects.sas + @brief Retrieves list of objects for a particular metadata type + @details + +

SAS Macros

+ @li mm_getobjects.sas + @li mpe_getvars.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%mpeinit() + +%mpe_getvars(SASControlTable, SASControlTable) +options metarepository=&repo; +%mm_getobjects( + type=&metatype + ,outds=work.objects +) + +%webout(OPEN) +%webout(OBJ,objects) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/metanav/metarepos.sas b/sas/sasjs/targets/sas9/services_meta/metanav/metarepos.sas new file mode 100644 index 0000000..0bb5241 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/metanav/metarepos.sas @@ -0,0 +1,27 @@ +/** + @file metarepos.sas + @brief Retrieves list of metadata types + @details + +

SAS Macros

+ @li mm_getrepos.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%mpeinit() +%mm_getrepos(outds=work.repos) + +data outrepos; + set repos; + if repositorytype in ('CUSTOM','FOUNDATION'); + keep id name description; +run; +%webout(OPEN) +%webout(OBJ,outrepos) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/metanav/metatypes.sas b/sas/sasjs/targets/sas9/services_meta/metanav/metatypes.sas new file mode 100644 index 0000000..bb30d2d --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/metanav/metatypes.sas @@ -0,0 +1,20 @@ +/** + @file metatypes.sas + @brief Retrieves list of metadata types + @details + +

SAS Macros

+ @li mm_gettypes.sas + + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ +%mpeinit() +%mm_gettypes(outds=work.types) + +%webout(OPEN) +%webout(OBJ,types) +%webout(CLOSE) +%mpeterm() diff --git a/sas/sasjs/targets/sas9/services_meta/usernav/usergroupsbymember.sas b/sas/sasjs/targets/sas9/services_meta/usernav/usergroupsbymember.sas new file mode 100644 index 0000000..ad3b5e6 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/usernav/usergroupsbymember.sas @@ -0,0 +1,107 @@ +/** + @file usergroupsbymember.sas + @brief List the groups a member is in + @details Runs without \%mpeinit() - this enables the dropdown to be populated + during configuration, when the settings service does not yet exist. + +

SAS Macros

+ @li mp_abort.sas + @li mm_getusers.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%macro x(); +%if %sysfunc(exist(work.iwant)) ne 1 %then %do; + /* macro called by configurator - grab the URI of calling user */ + %mm_getusers(user=&_metaperson, outds=work.iwant) +%end; +%mend x; +%x() + +data groups + roles(rename=(groupuri=roleuri groupname=rolename groupdesc=roledesc)) ; + length uri groupuri groupname groupdesc publictype str $256; + call missing(of _all_); + set iwant; + a=1; + grpassn=metadata_getnasn(uri,"IdentityGroups",a,groupuri); + if grpassn in (-3,-4) then do; + putlog "WARNING: No groups found for "; + end; + else do while (grpassn > 0); + rc=metadata_getattr(groupuri, "Name", groupname); + rc=metadata_getattr(groupuri, "Desc", groupdesc); + rc=metadata_getattr(groupuri, "PublicType", PublicType); + a+1; + if PublicType = 'Role' then output roles; + else output groups; + grpassn=metadata_getnasn(uri,"IdentityGroups",a,groupuri); + end; + keep groupuri groupname groupdesc; + if _n_=1 then delete; /* no content so don't send empty row */ +run; + +data emails; + keep email type; + length emailuri email type uri str $256; + call missing(of _all_); + set iwant; + + /* credit + https://seleritysas.com/data-step-view-of-email-addresses-in-sas-metadata + */ + emailrc=1;email_count=1; + do while(emailrc>0); + /* Get Email from Person */ + emailrc=metadata_getnasn(uri,"EmailAddresses",email_count,emailuri); + arc=1; + if (emailrc>0) then do; + arc=metadata_getattr(emailuri,"Address",email); + arc=metadata_getattr(emailuri,"EmailType",type); + end; + if (arc=0) then output emails; + email_count=email_count+1; + end; +run; + +data logins; + length domain userid loginuri domainuri uri $256; + keep domain userid; + call missing(of _all_); + set iwant; + login_count=1; + do while(metadata_getnasn(uri,"Logins",login_count,loginuri)>0); + rc=metadata_getattr(loginuri,"UserID",userid); + rc=metadata_getnasn(loginuri,"Domain",1,domainuri); + rc=metadata_getattr(domainuri,"Name",domain); + output; + login_count+1; + end; +run; + + +data info; + length uri name displayname metadatacreated metadataupdated $256; + keep name displayname metadatacreated metadataupdated; + call missing(of _all_); + set iwant; + rc=metadata_getattr(uri,"Name",name); + rc=metadata_getattr(uri,"DisplayName",displayname); + rc=metadata_getattr(uri,"MetadataCreated",MetadataCreated); + rc=metadata_getattr(uri,"MetadataUpdated",MetadataUpdated); +run; + +%webout(OPEN) +%webout(OBJ,emails) +%webout(OBJ,groups) +%webout(OBJ,roles) +%webout(OBJ,logins) +%webout(OBJ,info) +%webout(CLOSE) + diff --git a/sas/sasjs/targets/sas9/services_meta/usernav/usermembers.sas b/sas/sasjs/targets/sas9/services_meta/usernav/usermembers.sas new file mode 100644 index 0000000..a522dd9 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/usernav/usermembers.sas @@ -0,0 +1,24 @@ +/** + @file usermembers.sas + @brief List all SAS users + @details Gets a list of all SAS users + +

SAS Macros

+ @li dc_getusers.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() +%dc_getusers(outds=users) + +%webout(OPEN) +%webout(OBJ,users) +%webout(CLOSE) + + diff --git a/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbygroup.sas b/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbygroup.sas new file mode 100644 index 0000000..92ce2d1 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbygroup.sas @@ -0,0 +1,56 @@ +/** + @file usermembersbygroup.sas + @brief List the members of a group + +

SAS Macros

+ @li mp_abort.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%mpeinit() +data sasMembers ; + attrib uriGrp uriMem GroupId GroupName Group_or_Role MemberName MemberType + MemberUpdated membercreated emailuri length=$64 + GroupDesc email length=$256 + rcGrp rcMem rc i j length=3; + call missing (of _all_); + drop uriGrp rcGrp rcMem rc i j; + set iwant; + i=1; + * Grab the URI for the first Group ; + rcGrp=metadata_getnobj(groupid,i,uriGrp); + + * If Group found, enter do loop ; + if rcGrp>0 then do; + call missing (rcMem,uriMem,GroupId,GroupName,Group_or_Role + ,MemberName,MemberType); + * get group info ; + rc = metadata_getattr(uriGrp,"Id",GroupId); + rc = metadata_getattr(uriGrp,"Name",GroupName); + rc = metadata_getattr(uriGrp,"PublicType",Group_or_Role); + rc = metadata_getattr(uriGrp,"Desc",GroupDesc); + j=1; + do while (metadata_getnasn(uriGrp,"MemberIdentities",j,uriMem) > 0); + call missing (MemberName,MemberType); + rc = metadata_getattr(uriMem,"Name",MemberName); + rc = metadata_getattr(uriMem,"PublicType",MemberType); + rc=metadata_getattr(uriMem, "MetadataCreated", MemberCreated); + rc=metadata_getattr(uriMem, "MetadataUpdated", MemberUpdated); + emailrc=metadata_getnasn(uriMem,"EmailAddresses",1,emailuri); + if (emailrc>0) then rc=metadata_getattr(emailuri,"Address",email); + output; + j+1; + call missing(email,emailuri); + end; + end; + if _n_=1 then delete; +run; + +%webout(OPEN) +%webout(OBJ,sasMembers) +%webout(CLOSE) diff --git a/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbyrole.sas b/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbyrole.sas new file mode 100644 index 0000000..e2b718b --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/usernav/usermembersbyrole.sas @@ -0,0 +1,60 @@ +/** + @file usermembersbyrole.sas + @brief List the members of a role + +

SAS Macros

+ @li mp_abort.sas + @li mpeinit.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%mpeinit() +data sasMembers sasgroups; + attrib uriGrp uriMem roleId roleName Group_or_Role MemberName MemberType + MemberUpdated membercreated emailuri length=$64 + roleDesc email length=$256 + rcGrp rcMem rc i j length=3; + call missing (of _all_); + set iwant; + i=1; + * Grab the URI for the first Group ; + rcGrp=metadata_getnobj(roleid,i,uriGrp); + + * If Group found, enter do loop ; + if rcGrp>0 then do; + call missing (rcMem,uriMem,roleId,roleName,Group_or_Role + ,MemberName,MemberType,roleDesc); + * get group info ; + rc = metadata_getattr(uriGrp,"Id",roleId); + rc = metadata_getattr(uriGrp,"Name",roleName); + rc = metadata_getattr(uriGrp,"PublicType",Group_or_Role); + rc = metadata_getattr(uriGrp,"Desc",roleDesc); + j=1; + if Group_or_Role='Role' then do while + (metadata_getnasn(uriGrp,"MemberIdentities",j,uriMem) > 0); + call missing (MemberName,MemberType); + call missing(email,emailuri); + rc = metadata_getattr(uriMem,"Name",MemberName); + rc = metadata_getattr(uriMem,"PublicType",MemberType); + rc=metadata_getattr(uriMem, "MetadataCreated", MemberCreated); + rc=metadata_getattr(uriMem, "MetadataUpdated", MemberUpdated); + emailrc=metadata_getnasn(uriMem,"EmailAddresses",1,emailuri); + if (emailrc>0) then rc=metadata_getattr(emailuri,"Address",email); + if membertype='UserGroup' then output sasgroups; + else output sasmembers; + j+1; + end; + end; + + if _n_=1 then delete; /* no roles so don't send empty row */ + keep uriMem membertype membername MemberCreated MemberUpdated email; +run; + +%webout(OPEN) +%webout(OBJ,sasGroups) +%webout(OBJ,sasMembers) +%webout(CLOSE) + diff --git a/sas/sasjs/targets/sas9/services_meta/usernav/userroles.sas b/sas/sasjs/targets/sas9/services_meta/usernav/userroles.sas new file mode 100644 index 0000000..7c4a120 --- /dev/null +++ b/sas/sasjs/targets/sas9/services_meta/usernav/userroles.sas @@ -0,0 +1,20 @@ +/** + @file userroles.sas + @brief List all SAS Roles + @details Gets a list of all SAS Roles + +

SAS Macros

+ @li dc_getroles.sas + @li mpeinit.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%mpeinit() +%dc_getroles(outds=roles) + +%webout(OPEN) +%webout(OBJ,roles) +%webout(CLOSE) diff --git a/sas/sasjs/targets/server/macros_server/dc_assignlib.sas b/sas/sasjs/targets/server/macros_server/dc_assignlib.sas new file mode 100644 index 0000000..15231c7 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_assignlib.sas @@ -0,0 +1,22 @@ +/** + @file + @brief Assigns library and opens pass through + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + This macro will source library definitions from a secure location on the + filesystem. + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_assignlib(type,libref,passthru=); + %if %length(&passthru)>0 %then %do; + proc sql; + connect using &libref as &passthru; + %end; +%mend dc_assignlib; diff --git a/sas/sasjs/targets/server/macros_server/dc_createdataset.sas b/sas/sasjs/targets/server/macros_server/dc_createdataset.sas new file mode 100644 index 0000000..303d028 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_createdataset.sas @@ -0,0 +1,20 @@ +/** + @file dc_createdataset.sas + +

SAS Macros

+ + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_createdataset(libds=mm_getlibs,outds=viewdata); +data viewdata; + var1='Table'; + var2="&libds"; + var3="does not exist!"; +run; + +%mend dc_createdataset; diff --git a/sas/sasjs/targets/server/macros_server/dc_getgroupmembers.sas b/sas/sasjs/targets/server/macros_server/dc_getgroupmembers.sas new file mode 100644 index 0000000..88eebb8 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getgroupmembers.sas @@ -0,0 +1,22 @@ +/** + @file dc_getgroupmembers.sas + @brief Gets all the memers of a group + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroupmembers(group,outds=dc_getgroupmembers); + data &outds ; + length membername $64; + call missing(membername); + stop; + run; +%mend dc_getgroupmembers; diff --git a/sas/sasjs/targets/server/macros_server/dc_getgroups.sas b/sas/sasjs/targets/server/macros_server/dc_getgroups.sas new file mode 100644 index 0000000..383e6bc --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getgroups.sas @@ -0,0 +1,34 @@ +/** + @file dc_getgroups.sas + @brief Gets all groups + +

SAS Macros

+ @li ms_getgroups.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroups(outds=ms_getgroups); + + %ms_getgroups(outds=&outds) + + data &outds; + length groupuri groupname $32 groupdesc $128 ; + if _n_=1 then call missing (of _all_); + if nobs=0 then do; + groupuri='1'; + groupname='DCDEFAULT'; + groupdesc='DC Default'; + output; + end; + set &outds nobs=nobs; + keep groupuri groupname groupdesc; + groupuri=cats(groupid); + groupname=name; + groupdesc=description; + output; + run; +%mend dc_getgroups; diff --git a/sas/sasjs/targets/server/macros_server/dc_getlibs.sas b/sas/sasjs/targets/server/macros_server/dc_getlibs.sas new file mode 100644 index 0000000..04610c7 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getlibs.sas @@ -0,0 +1,26 @@ +/** + @file dc_getlibs.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getlibs(outds=mm_getlibs); +proc sql; +create table &outds as + select distinct libname as LibraryRef + ,libname as LibraryName length=256 + ,engine + ,'' as libraryid length=17 + from dictionary.libnames + where libname not in ('WORK','SASUSER'); +insert into &syslast values ("&DC_LIBREF", "&DC_LIBNAME",'','V9'); + +%mend dc_getlibs; diff --git a/sas/sasjs/targets/server/macros_server/dc_getservicecode.sas b/sas/sasjs/targets/server/macros_server/dc_getservicecode.sas new file mode 100644 index 0000000..3f2b5fe --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getservicecode.sas @@ -0,0 +1,19 @@ +/** + @file + @brief Gets service code + +

SAS Macros

+ @li ms_getfile.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getservicecode(loc=,outref=); + + %ms_getfile(&loc..sas, outref=&outref) + +%mend dc_getservicecode; diff --git a/sas/sasjs/targets/server/macros_server/dc_getsettings.sas b/sas/sasjs/targets/server/macros_server/dc_getsettings.sas new file mode 100644 index 0000000..b5d3281 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getsettings.sas @@ -0,0 +1,35 @@ +/** + @file + @brief Get settings from SASjs Drive + @details gets and runs the code from services/public/settings.sas + +

SAS Macros

+ @li mp_abort.sas + @li mf_getapploc.sas + @li ms_getfile.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getsettings(); +%global DC_LIBNAME DC_LIBREF; + +/* get settings code */ +%ms_getfile(%mf_getapploc()/services/public/settings.sas, outref=settings) + +/* run it */ +%inc settings/source2; + +%let DC_LIBNAME=&dc_libref; +%let mpelib=&DC_LIBREF; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=dc_getsettings + ,msg=%str(syscc=&syscc after dc_getsettings) +) + +%mend dc_getsettings; diff --git a/sas/sasjs/targets/server/macros_server/dc_gettableid.sas b/sas/sasjs/targets/server/macros_server/dc_gettableid.sas new file mode 100644 index 0000000..aeecc2b --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_gettableid.sas @@ -0,0 +1,24 @@ +/** + @file dc_gettableid.sas + @brief Gets the table id + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_gettableid(libref= + ,ds= + ,outds=); + +data &outds; + tableuri=''; + tablename="&ds"; +run; + +%mend dc_gettableid; diff --git a/sas/sasjs/targets/server/macros_server/dc_getusergroups.sas b/sas/sasjs/targets/server/macros_server/dc_getusergroups.sas new file mode 100644 index 0000000..5f334fb --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getusergroups.sas @@ -0,0 +1,29 @@ +/** + @file + @brief Gets all groups + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + Returns the group memberships of a particular user. + +

SAS Macros

+ @li mf_getuser.sas + @li ms_getgroups.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusergroups(user=,outds=ms_getgroups); + + %ms_getgroups(outds=work.groups,user=%mf_getuser()) + + data &outds; + set work.groups; + rename name=groupname + description=groupdesc; + run; +%mend dc_getusergroups; diff --git a/sas/sasjs/targets/server/macros_server/dc_getusers.sas b/sas/sasjs/targets/server/macros_server/dc_getusers.sas new file mode 100644 index 0000000..616d451 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_getusers.sas @@ -0,0 +1,28 @@ +/** + @file dc_getusers.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ @li ms_getusers.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusers(outds=dc_getusers); + + %ms_getusers(outds=work.users) + + data &outds; + length uri name $32; + set work.users; + uri=put(id,best.); + name=username; + drop username id; + run; +%mend dc_getusers; diff --git a/sas/sasjs/targets/server/macros_server/dc_refreshcatalog.sas b/sas/sasjs/targets/server/macros_server/dc_refreshcatalog.sas new file mode 100644 index 0000000..80e70e0 --- /dev/null +++ b/sas/sasjs/targets/server/macros_server/dc_refreshcatalog.sas @@ -0,0 +1,40 @@ +/** + @file dc_refreshcatalog.sas + @brief Refresh catalog + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces are the same. This version is VIYA. + + The MPELIB should be pre-assigned + +

SAS Macros

+ @li mpe_refreshlibs.sas + @li dc_assignlib.sas + @li mpe_refreshtables.sas + + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_refreshcatalog(libref); + +%mpe_refreshlibs() + +filename executor catalog 'work.code.code.source'; +data libraries; + set &mpelib..mpe_datacatalog_libs; + where &dc_dttmtfmt. le TX_TO; +%if %length(&libref)>0 %then %do; + where also libref="&libref"; +%end; + file executor; + str=cats('%mpe_refreshtables(',libref,')'); + put str; + putlog str; +run; +%inc executor/source2; + +%mend dc_refreshcatalog; diff --git a/sas/sasjs/targets/server/services_server/admin/configurator.sas b/sas/sasjs/targets/server/services_server/admin/configurator.sas new file mode 100644 index 0000000..9e6df81 --- /dev/null +++ b/sas/sasjs/targets/server/services_server/admin/configurator.sas @@ -0,0 +1,241 @@ +/** + @file + @brief provides the web service to create the control tables + @details + +

SAS Macros

+ @li dc_getusergroups.sas + @li mf_getuser.sas + @li mf_getapploc.sas + @li mp_base64copy.sas + +

Binary Files

+ @li dcsquare.png dcsq + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%let root=%mf_getapploc(); + +/* create web page */ +data _null_; + file _webout; + infile datalines ; + input; + put _infile_; +datalines4; + + + + + Data Controller + + +;;;; +run; + +/* convert favicon to base64 */ +%mp_base64copy(inref=dcsq, outref=b64dcsq, action=ENCODE) +/* send */ +/* +data _null_; + file _webout mod lrecl=32767; + infile b64dcsq end=last lrecl=1 recfm=n; + if _n_=1 then do; + put ''; + end; +run; +*/ + +/* get the folder root (depends where the app was installed) */ +data _null_; + length root $512; + pgm="&_program"; + root="&root"; + putlog root=; + file _webout mod; + root=quote(trim(root)); + put ' + + +
+
+ + Data Controller +
+
+
+
+
+
+ +
+
+Terms and Conditions +
+
+
+

+ Before proceeding with configuration, please confirm that you have read, + understood, and agreed to the + Data Controller for SAS© Evaluation Agreement. +

+
+
+ + +
+
+
+ + +
+
+ + +;;;; +run; diff --git a/sas/sasjs/targets/server/services_server/admin/makedata.sas b/sas/sasjs/targets/server/services_server/admin/makedata.sas new file mode 100644 index 0000000..d535704 --- /dev/null +++ b/sas/sasjs/targets/server/services_server/admin/makedata.sas @@ -0,0 +1,166 @@ +/** + @file + @brief service for creating the configuration tables + @details + STP for creating the configuration tables. + It also adds the STAGING directory as subdirectory to the BASE + library location. + + @warning This STP self destructs! It will delete itself after a successful run + to avoid being executed twice (and overwriting actual data) + +

SAS Macros

+ @li mf_getapploc.sas + @li mf_mkdir.sas + @li mp_abort.sas + @li mpe_makedata.sas + @li mpe_makedatamodel.sas + @li ms_createfile.sas + @li ms_deletefile.sas + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%global path ADMIN ; + +%webout(FETCH) + +/* enable vars to be passed as url params */ +%let exist=%sysfunc(exist(work.fromjs)); +%let inds=%sysfunc(ifc(&exist=1,fromjs,_null_)); +data _null_; + set &inds; + call symputx('path',dcpath); + call symputx('ADMIN',ADMIN); +run; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Issue on makedata entry) +) + +%let root=%mf_getapploc(); +%let dc_libref=%upcase(DC%substr(%sysevalf(%sysfunc(datetime())/60),3,6)); +%let dcpath=%trim(&path)/&dc_libref; +%put _all_; + +%mf_mkdir(&dcpath) + +libname &dc_libref "&dcpath"; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Libref (&dc_libref) could not be assigned to (&dcpath) ) +) + +/* check we have physical permissions to the DCLIB folder */ +data _null_; + putlog "testing write to: &dcpath/permTest.txt"; + putlog "sysuserid=&sysuserid"; +data _null_; + file "&dcpath/permTest.txt"; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(User &sysuserid does not have WRITE permissions on physical + directory: &dcpath ) +) + +filename delfile "&dcpath/permTest.txt"; +data _null_; + rc=fdelete('delfile'); +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt ) +) + + +/* SASAdministrators */ +%let admin=%sysfunc(coalescec(&admin,SASAdministrators)); +%mpe_makedatamodel(lib=&dc_libref) +%mpe_makedata(lib=&DC_LIBREF,mpeadmins=&admin,path=%str(&dcpath)) + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem creating tables in &DC_LIBREF library) +) + +/* finally, update the app component. The user will need WM perms for this. */ +filename stngs temp; +data _null_; + file stngs ; + put ' '; + put '%global dc_repo_users dc_macros dc_libref dc_staging_area dc_admin_group mpelib dc_dttmtfmt;'; + put ' '; + put '%let dc_libref=' "&dc_libref;"; + put ' '; + put '/* This metadata group has unrestricted access to Data Controller */'; + put '%let dc_admin_group=' "&admin;"; + put ' '; + put "libname &dc_libref '&dcpath' ;"; + put ' '; + put '/* This physical location is used for staging data and audit history */'; + put '%let dc_staging_area=' "&dcpath/dc_staging;"; + put ' '; + put 'data _null_;'; + put ' set &DC_LIBREF..mpe_config(where=('; + put ' var_scope="DC" '; + put ' and &dc_dttmtfmt. lt tx_to'; + put ' and var_active=1'; + put " ));"; + put " call symputx(var_name,var_value,'G');"; + put ' putlog var_name "=" var_value;'; + put "run;"; + put ' '; + put '/* to override any DC macros with client versions, place them below */'; + put 'options insert=(sasautos=("&dc_macros"));'; + put '%let mpelib=&DC_LIBREF;'; +run; + + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(syscc=syscc=&syscc when preparing data_controller_settings) +) + +%ms_deletefile(&root/services/public/settings.sas) +%ms_createfile(&root/services/public/settings.sas, inref=stngs) + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program..sas + ,msg=%str(Problem updating &root/services/public/settings) +) + + +data _null_; + file _webout; + put '

Data Controller Config

'; + put '

The following items have been successfully configured:

'; + put "
  • Library Location (&dcpath)
  • "; + put "
  • Table Creation (&DC_LIBREF library) using the &sysuserid identity
  • "; + put "
  • Logs Location (%trim(&dcpath)/logs)
  • "; + put "
  • Data Controller Admin Group (&admin)
  • "; + put "
"; + put 'Future configuration changes can be made here

'; + put "

Next Steps:

"; + put "
  1. Populate"; + put "Data Catalog
  2. "; + put "
  3. Launch!"; + put "
"; +run; + +/* We ran successfully, now remove configurator and makedata STPs */ +%ms_deletefile(&root/services/admin/configurator.sas) +%ms_deletefile(&_program..sas) + diff --git a/sas/sasjs/targets/server/services_server/usernav/usergroupsbymember.sas b/sas/sasjs/targets/server/services_server/usernav/usergroupsbymember.sas new file mode 100644 index 0000000..c93be15 --- /dev/null +++ b/sas/sasjs/targets/server/services_server/usernav/usergroupsbymember.sas @@ -0,0 +1,51 @@ +/** + @file usergroupsbymember.sas + @brief List the groups a member is in + @details Runs without \%mpeinit() - this enables the dropdown to be populated + during configuration, when the settings service does not yet exist. + +

SAS Macros

+ @li mp_abort.sas + @li mpeinit.sas + @li ms_getgroups.sas + +

Data Inputs

+
iwant
+ |uri:$| + |---| + |1| + +

Data Outputs

+
groups
+ |NAME:$32.|DESCRIPTION:$64.|GROUPID:best.| + |---|---|---| + |`SomeGroup `|`A group `|`1`| + |`Another Group`|`this is a different group`|`2`| + |`admin`|`Administrators `|`3`| + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +/* enable service to run without an input */ +%let exist=%sysfunc(exist(work.iwant)); +%let inds=%sysfunc(ifc(&exist=1,iwant,_null_)); +%let uid=&_sasjs_userid; +data _null_; + set &inds; + call symputx('uid',uri); +run; + +%ms_getgroups(outds=work.groups,uid=&uid) + +data work.groups; + set work.groups(rename=(groupid=uri name=groupname description=groupdesc)); +run; + +%webout(OPEN) +%webout(OBJ,groups) +%webout(CLOSE) + diff --git a/sas/sasjs/targets/server/services_server/usernav/usermembers.sas b/sas/sasjs/targets/server/services_server/usernav/usermembers.sas new file mode 100644 index 0000000..4ed9b83 --- /dev/null +++ b/sas/sasjs/targets/server/services_server/usernav/usermembers.sas @@ -0,0 +1,34 @@ +/** + @file usermembers.sas + @brief List all SAS users + @details Gets a list of all SAS users + +

SAS Macros

+ @li dc_getusers.sas + @li mpeinit.sas + +

Data Outputs

+
users
+|DISPLAYNAME:$60.|USERNAME:$30.|ID:best.| +|---|---|---| +|`Super Admin `|`secretuser `|`1`| +|`Sabir Hassan`|`sabir`|`2`| +|`Mihajlo Medjedovic `|`mihajlo `|`3`| +|`Ivor Townsend `|`ivor `|`4`| +|`New User `|`newuser `|`5`| + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() +%dc_getusers(outds=users) + +%webout(OPEN) +%webout(OBJ,users) +%webout(CLOSE) + + diff --git a/sas/sasjs/targets/server/services_server/usernav/usermembersbygroup.sas b/sas/sasjs/targets/server/services_server/usernav/usermembersbygroup.sas new file mode 100644 index 0000000..86249ed --- /dev/null +++ b/sas/sasjs/targets/server/services_server/usernav/usermembersbygroup.sas @@ -0,0 +1,43 @@ +/** + @file usermembersbygroup.sas + @brief List the members of a group + +

SAS Macros

+ @li mp_abort.sas + @li mpeinit.sas + @li ms_getusers.sas + +

Data Inputs

+
iwant
+ |groupid:$| + |---| + |1| + +

Data Outputs

+
sasmembers
+|DISPLAYNAME:$60.|USERNAME:$30.|ID:best.| +|---|---|---| +|`Super Admin `|`secretuser `|`1`| +|`Sabir Hassan`|`sabir`|`2`| +|`Mihajlo Medjedovic `|`mihajlo `|`3`| +|`Ivor Townsend `|`ivor `|`4`| +|`New User `|`newuser `|`5`| + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%mpeinit() + +data _null_; + set work.iwant; + call symputx('gid',groupid); +run; + +%ms_getusers(outds=sasMembers, gid=&gid) + +%webout(OPEN) +%webout(OBJ,sasMembers) +%webout(CLOSE) diff --git a/sas/sasjs/targets/viya/macros_viya/dc_assignlib.sas b/sas/sasjs/targets/viya/macros_viya/dc_assignlib.sas new file mode 100644 index 0000000..15231c7 --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_assignlib.sas @@ -0,0 +1,22 @@ +/** + @file + @brief Assigns library and opens pass through + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + This macro will source library definitions from a secure location on the + filesystem. + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_assignlib(type,libref,passthru=); + %if %length(&passthru)>0 %then %do; + proc sql; + connect using &libref as &passthru; + %end; +%mend dc_assignlib; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_createdataset.sas b/sas/sasjs/targets/viya/macros_viya/dc_createdataset.sas new file mode 100644 index 0000000..f359c52 --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_createdataset.sas @@ -0,0 +1,20 @@ +/** + @file dc_createdataset.sas + +

SAS Macros

+ + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_createdataset(libds=mm_getlibs); +data viewdata; + var1='Table'; + var2="&libds"; + var3="does not exist!"; +run; + +%mend dc_createdataset; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getgroupmembers.sas b/sas/sasjs/targets/viya/macros_viya/dc_getgroupmembers.sas new file mode 100644 index 0000000..f3c9ca7 --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getgroupmembers.sas @@ -0,0 +1,23 @@ +/** + @file dc_getgroupmembers.sas + @brief Gets all the memers of a group + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ @li mv_getgroupmembers.sas + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroupmembers(group,outds=dc_getgroupmembers); + %mv_getgroupmembers(%str(&group),outds=&outds) + data &outds ; + length membername $64; + set &outds(rename=(name=MemberName)); + run; +%mend dc_getgroupmembers; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getgroups.sas b/sas/sasjs/targets/viya/macros_viya/dc_getgroups.sas new file mode 100644 index 0000000..4aa576d --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getgroups.sas @@ -0,0 +1,24 @@ +/** + @file dc_getgroups.sas + @brief Gets all groups + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is META. + +

SAS Macros

+ @li mv_getgroups.sas + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getgroups(outds=mm_getgroups); + %mv_getgroups(outds=&outds) + proc sort + data=&outds(rename=(id=groupuri name=groupname description=groupdesc)) + out=&outds (keep=groupuri groupname groupdesc); + by groupname; + run; +%mend dc_getgroups; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getlibs.sas b/sas/sasjs/targets/viya/macros_viya/dc_getlibs.sas new file mode 100644 index 0000000..cfac4e6 --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getlibs.sas @@ -0,0 +1,27 @@ +/** + @file dc_getlibs.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getlibs(outds=mm_getlibs); +proc sql; +create table &outds as + select distinct libname as LibraryRef + ,libname as LibraryName length=256 + ,engine + ,'' as libraryid length=17 + from dictionary.libnames + where libname not in ('WORK','SASUSER'); +insert into &syslast values ("&DC_LIBREF", "&DC_LIBNAME",'','V9'); + +%mend dc_getlibs; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getservicecode.sas b/sas/sasjs/targets/viya/macros_viya/dc_getservicecode.sas new file mode 100644 index 0000000..e9bc2be --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getservicecode.sas @@ -0,0 +1,24 @@ +/** + @file + @brief Gets service code + +

SAS Macros

+ @li mv_getjobcode.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getservicecode(loc=,outref=); + +%local name; +%let name=%scan(&loc,-1,/); +%mv_getjobcode(path=%substr(&loc,1,%length(&loc)-%length(&name)-1) + ,name=&name + ,outref=&outref +) + +%mend dc_getservicecode; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getsettings.sas b/sas/sasjs/targets/viya/macros_viya/dc_getsettings.sas new file mode 100644 index 0000000..e95ee3e --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getsettings.sas @@ -0,0 +1,55 @@ +/** + @file dc_getsettings.sas + @brief Get settings + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ @li mp_abort.sas + @li mf_getapploc.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getsettings(); +%global DC_LIBNAME DC_LIBREF; + +%if %symexist(_PROGRAM) %then %let root=&_program; +%else %do; + %global _metauser; + %let _metauser=&sysuserid; + /* to mimic a "real" _program we need to give a dummy role and stp name */ + %let root=/dummyRole/dummyName; +%end; + + +/* the DC precode is stored in the Admin folder in the root of + the project. Lets find that root. */ +%put &=root; +%let root=%mf_getapploc(); +%put &=root; + +/* Now we know the root location we can retrieve the params */ +/* only do this if the lib is not assigned - this is an expensive Viya call */ + +%if x&dc_libref.x=xx %then %do; + %put fetching settings from API - this is an expensive call; + %put it is recommended to put these values in the autoexec; + filename __dc filesrvc folderpath="&root/services"; + %inc __dc(settings)/source2; +%end; + + +%let DC_LIBNAME=&dc_libref; +%let mpelib=&DC_LIBREF; + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=&_program + ,msg=%str(Problem running &sysmacroname (&syswarningtext &syserrortext)) +) + +%mend dc_getsettings; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_gettableid.sas b/sas/sasjs/targets/viya/macros_viya/dc_gettableid.sas new file mode 100644 index 0000000..aeecc2b --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_gettableid.sas @@ -0,0 +1,24 @@ +/** + @file dc_gettableid.sas + @brief Gets the table id + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_gettableid(libref= + ,ds= + ,outds=); + +data &outds; + tableuri=''; + tablename="&ds"; +run; + +%mend dc_gettableid; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getusergroups.sas b/sas/sasjs/targets/viya/macros_viya/dc_getusergroups.sas new file mode 100644 index 0000000..47f6c3c --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getusergroups.sas @@ -0,0 +1,25 @@ +/** + @file + @brief Gets all groups + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + + Returns the group memberships of a particular user. + +

SAS Macros

+ @li mv_getusergroups.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusergroups(user=,outds=mm_getgroups); + %mv_getusergroups(&user,outds=&outds) + data &outds; + length groupname groupdesc $256; + set &outds(rename=(id=groupname name=groupdesc)); + run; +%mend dc_getusergroups; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_getusers.sas b/sas/sasjs/targets/viya/macros_viya/dc_getusers.sas new file mode 100644 index 0000000..0c2487a --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_getusers.sas @@ -0,0 +1,22 @@ +/** + @file dc_getusers.sas + @brief Gets all available libraries + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces is the same. This version is VIYA. + +

SAS Macros

+ @li mv_getusers.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_getusers(outds=mm_getlibs); + %mv_getusers(outds=&outds) + proc sort data=&outds(rename=(id=uri)) out=&outds(keep=uri name); + by name; + run; +%mend dc_getusers; diff --git a/sas/sasjs/targets/viya/macros_viya/dc_refreshcatalog.sas b/sas/sasjs/targets/viya/macros_viya/dc_refreshcatalog.sas new file mode 100644 index 0000000..196a092 --- /dev/null +++ b/sas/sasjs/targets/viya/macros_viya/dc_refreshcatalog.sas @@ -0,0 +1,37 @@ +/** + @file dc_refreshcatalog.sas + @brief Refresh catalog + @details There are two versions of this macro - a META and a VIYA version (in + different folders). The interfaces are the same. This version is VIYA. + + The MPELIB should be pre-assigned + +

SAS Macros

+ @li mpe_refreshlibs.sas + @li dc_assignlib.sas + @li mpe_refreshtables.sas + + + @version 3.4 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%macro dc_refreshcatalog(); + +%mpe_refreshlibs() + +filename executor catalog 'work.code.code.source'; +data libraries; + set &mpelib..mpe_datacatalog_libs; + where &dc_dttmtfmt. le TX_TO; + file executor; + str=cats('%mpe_refreshtables(',libref,')'); + put str; + putlog str; +run; +%inc executor; + +%mend dc_refreshcatalog; diff --git a/sas/sasjs/targets/viya/services_viya/admin/makedata.sas b/sas/sasjs/targets/viya/services_viya/admin/makedata.sas new file mode 100644 index 0000000..440ca2b --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/admin/makedata.sas @@ -0,0 +1,183 @@ +/** + @file + @brief self destructing setup service + @details Will create the database and perform config activities + +

SAS Macros

+ @li mf_getapploc.sas + @li mf_mkdir.sas + @li mf_trimstr.sas + @li mpe_getvars.sas + @li mpe_makedata.sas + @li mpe_makedatamodel.sas + @li mpe_makesampledata.sas + @li mv_deletejes.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + + +%global dcpath ADMIN ; + +%webout(FETCH) + +/* enable vars to be passed as url params */ +%let exist=%sysfunc(exist(work.fromjs)); +%let inds=%sysfunc(ifc(&exist=1,fromjs,_null_)); +data _null_; + set &inds; + call symputx('dcpath',dcpath); + call symputx('ADMIN',ADMIN); +run; + + +options noquotelenmax; + +%let dclib=%upcase(VIYA%substr(%sysevalf(%sysfunc(datetime())/60),3,4)); +%let dclibname=Data Controller (&dclib); +%let DC_LIBREF=&dclib; +%let work=%sysfunc(pathname(work)); + + +%let dcpath=%mf_trimstr(&dcpath,/)/&dclib; +%put &=sysuserid; +%put &=dcpath; +%put &=admin; + +%mf_mkdir(&dcpath) +%mf_mkdir(&dcpath/secret) +%mf_mkdir(&dcpath/dc_staging) + + +libname &dclib "&dcpath"; +%global admin; +%let admin=%sysfunc(coalescec(&admin,All Users)); +%mpe_makedatamodel(lib=&dclib) +%mpe_makedata(lib=&dclib,mpeadmins=&admin,path=%str(&dcpath)) + +/* sample data library */ +%mf_mkdir(&dcpath/dc_demo) +libname dcdemo "&dcpath/dc_demo"; +%mpe_makesampledata(outlib=DCDEMO) + +/* the DC precode is stored in the root of the project */ +%let root=%mf_getapploc(&_program)/services; +%put &=root; + +filename jobout filesrvc folderpath="&root"; +data _null_; + file jobout('settings.sas'); + put '/* these values are ignored if DC_LIBREF was declared in autoexec */'; + put ' '; + put '%global DC_LIBREF dc_admin_group dc_staging_area ;'; + put '/* This library (libref) contains the control datasets for DC */'; + put '/* If a different libref must be used, configure it below */'; + put '%let DC_LIBREF=' "&dclib;"; + put ' '; + put "libname &dclib '&dcpath' ;"; + put ' '; + put '/* This group has unrestricted access to Data Controller */'; + put '%let dc_admin_group=' "&admin;"; + put ' '; + put '/* This physical location is used for staging data and audit history */'; + put '%let dc_staging_area=' "&dcpath/dc_staging;"; + put ' '; + if &syssite in (70221618,70253615) then do; + put "libname dcdemo '&dcpath/dc_demo';"; + end; +run; + + +/* create demo data + +cas dcsession; +caslib _all_ assign; +caslib casmusic path='/opt/sas/viya/cascache/tracks' libref=casmusic GLOBAL; + +proc casutil; + LOAD DATA=dcdemo.cars + CASOUT="cars" + OUTCASLIB="casmusic" PROMOTE ; +run; +*/ + +/* +cas mysess; +caslib _all_ assign; +data casmusic.artists(promote=yes); + length name varchar(30); + do tracks=1 to 100; + name='Phil Collins'!!cats(tracks); + output; + end; +run; +*/ +/* +%let url=http://millionsongdataset.com/sites/default/files/AdditionalFiles%trim( + )/unique_tracks.txt; +filename test url "&url" lrecl=3000 ; + +proc sql; +drop table casmusic.tunes; + +data tracks; + infile test dlmstr='' dsd end=lastobs; + input track_id:$32. song_id:$32. artist_nm:$128. title:$256.; + output; + if lastobs then do; + track_id='dummyrecords'; + title='none'; + artist_nm='none'; + do x=1 to 4000000; + drop x; + song_id=cats(x); + output; + end; + stop; + end; +run; + +proc casutil; + LOAD DATA=tracks + CASOUT="tunes" + OUTCASLIB="casmusic" PROMOTE ; +run; +/* +data append; + if 0 then set &dclib..MPE_TABLES; + libref="CASMUSIC"; + dsn='TUNES'; + num_of_approvals_required=1; + loadtype='UPDATE'; + buskey='TRACK_ID SONG_ID'; + tx_from=0; + tx_to='31DEC9999:23:59:59'dt; + output; + dsn='ARTISTS'; + buskey='NAME'; + output; +run; +proc append base=&dclib..MPE_tABLES data=append; +run; +*/ +%mp_abort(iftrue=(&syscc ne 0) + ,mac=&sysmacroname + ,msg=%str(Err during DB build) +) + + +%webout(OPEN) +data result; + dclib="&dclib"; + admingroup="&admin"; + dcpath="&dcpath"; +run; +%webout(OBJ,result) +%webout(CLOSE) + +%mv_deletejes(path=&root/admin, name=makedata) diff --git a/sas/sasjs/targets/viya/services_viya/public/tokenauth.sas b/sas/sasjs/targets/viya/services_viya/public/tokenauth.sas new file mode 100644 index 0000000..2db2095 --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/public/tokenauth.sas @@ -0,0 +1,36 @@ +/** + @file tokenauth.sas + @brief Get initial tokens using an auth code - DEPRECATED + +

SAS Macros

+ @li mv_tokenauth.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%webout(FETCH) + +data _null_; + set work.fromjs; + call symputx('viyasettings',viyasettings); + call symputx('client_id',client_id); + call symputx('auth_code',auth_code); +run; + +data authme; + /* get client info from special location */ + infile "&viyasettings" dsd; + input client_secret:$100.; + client_id="&client_id"; + auth_code="&auth_code"; +run; +/* get tokens */ +%mv_tokenauth(inds=authme, outds=fromSAS(keep=access_token refresh_token)) + +/* send back to frontend */ +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(CLOSE) diff --git a/sas/sasjs/targets/viya/services_viya/public/tokenrefresh.sas b/sas/sasjs/targets/viya/services_viya/public/tokenrefresh.sas new file mode 100644 index 0000000..f7bca51 --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/public/tokenrefresh.sas @@ -0,0 +1,37 @@ +/** + @file tokenauth.sas + @brief Get initial tokens using an auth code - DEPRECATED + +

SAS Macros

+ @li mpeinit.sas + @li mv_tokenrefresh.sas + + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%webout(FETCH) + +data _null_; + set work.fromjs; + call symputx('viyasettings',viyasettings); + call symputx('client_id',client_id); + call symputx('refresh_token',refresh_token); +run; + +data authme; + /* get client info from special location */ + infile "&viyasettings" dsd; + input client_secret:$100.; + client_id="&client_id"; + refresh_token="&refresh_token"; +run; +/* get tokens */ +%mv_tokenrefresh(inds=authme, outds=fromSAS(keep=refresh_token access_token)) + +/* send back to frontend */ +%webout(OPEN) +%webout(OBJ,fromSAS) +%webout(CLOSE) diff --git a/sas/sasjs/targets/viya/services_viya/viya_users/usergroupsbymember.sas b/sas/sasjs/targets/viya/services_viya/viya_users/usergroupsbymember.sas new file mode 100644 index 0000000..fd66be6 --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/viya_users/usergroupsbymember.sas @@ -0,0 +1,25 @@ +/** + @file usergroupsbymember.sas + @brief List the groups a member is in + @details Runs without \%mpeinit() - this enables the dropdown to be populated + during configuration, when the settings service does not yet exist. + +

SAS Macros

+ @li mv_getusergroups.sas + @li mf_getuser.sas + + @version 3.4 + @author 4GL Apps Ltd +**/ + +%mv_getusergroups(%mf_getuser(),outds=groups) + +proc sort data=groups(rename=(id=uri name=groupname providerid=groupdesc)) + out=groups; + by groupname; +run; + +%webout(OPEN) +%webout(OBJ,groups) +%webout(CLOSE) + diff --git a/sas/sasjs/targets/viya/services_viya/viya_users/usermembers.sas b/sas/sasjs/targets/viya/services_viya/viya_users/usermembers.sas new file mode 100644 index 0000000..a522dd9 --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/viya_users/usermembers.sas @@ -0,0 +1,24 @@ +/** + @file usermembers.sas + @brief List all SAS users + @details Gets a list of all SAS users + +

SAS Macros

+ @li dc_getusers.sas + @li mpeinit.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ + +%mpeinit() +%dc_getusers(outds=users) + +%webout(OPEN) +%webout(OBJ,users) +%webout(CLOSE) + + diff --git a/sas/sasjs/targets/viya/services_viya/viya_users/usermembersbygroup.sas b/sas/sasjs/targets/viya/services_viya/viya_users/usermembersbygroup.sas new file mode 100644 index 0000000..ffff12f --- /dev/null +++ b/sas/sasjs/targets/viya/services_viya/viya_users/usermembersbygroup.sas @@ -0,0 +1,31 @@ +/** + @file usermembersbygroup.sas + @brief List the members of a group + +

SAS Macros

+ @li mp_abort.sas + @li mpeinit.sas + @li dc_getgroupmembers.sas + + @version 9.3 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. +**/ +%mpeinit() + +data _null_; + set iwant; + call symputx('groupid',groupid); +run; + +%dc_getgroupmembers(%str(&groupid),outds=sasMembers) + +proc sort data=sasMembers; + by membername; +run; + +%webout(OPEN) +%webout(OBJ,sasMembers) +%webout(CLOSE) diff --git a/sas/sasjs/tests/testinit.sas b/sas/sasjs/tests/testinit.sas new file mode 100644 index 0000000..2eb79ad --- /dev/null +++ b/sas/sasjs/tests/testinit.sas @@ -0,0 +1,69 @@ +/** + @file + @brief testinit.sas + + @details for SAS 9 you can run: + +

SAS Macros

+ @li dc_getsettings.sas + @li mf_getplatform.sas + @li mpeinit2.sas + @li mp_abort.sas + @li mp_testservice.sas + + +REMOVE THAT LAST MACRO +**/ + +%let syscc=0; +%global apploc _program dclib defaultcontext _debug sasjs_mdebug dc_dttmtfmt; + +%let defaultcontext=Datacontroller compute context; +%let sasjs_mdebug=0; + +options mprint mprintnest nobomfile lrecl=32767; + +%mpeinit2() + +data _null_; + length _pgm $1000; + _pgm=symget('_program'); + if _pgm='' then do; + if "&SYSPROCESSMODE" = 'SAS Workspace Server' + then apploc= + '/30.SASApps/3030.Projects/303001.DataController/build2/DataController'; + else apploc='/Public/app/viya'; + call symputx('apploc',apploc); + call symputx('_program',cats(apploc,'/tests/services/bottom')); + end; + else do; + cnt=find(_pgm,'/tests/'); + if cnt=0 then cnt=find(_pgm,'/services/'); + if cnt=0 then cnt=find(_pgm,'/jobs/'); + put cnt= apploc= _pgm=; + apploc=substr(_pgm,1,cnt-1); + call symputx('apploc',apploc); + end; +run; + +%macro conditional(); +%if %scan(&_program,-1,/) ne testsetup %then %do; + %dc_getsettings() + /* this should be tidied up */ + %global dclib mpelib dc_libref; + %let dclib=&dc_libref; + %let mpelib=&dc_libref; + %put &=dclib &=mpelib; +%end; + +%if "&_debug"="2477" or "&_debug"="fields,log,trace" or "&_debug"="131" +%then %do; + %let sasjs_mdebug=1; +%end; + +%mend conditional; + +%conditional() + + + diff --git a/sas/sasjs/tests/testsetup.sas b/sas/sasjs/tests/testsetup.sas new file mode 100644 index 0000000..cae8ec9 --- /dev/null +++ b/sas/sasjs/tests/testsetup.sas @@ -0,0 +1,208 @@ +/** + @file + @brief test setup + +

SAS Macros

+ @li dc_getsettings.sas + @li mf_getapploc.sas + @li mf_getplatform.sas + @li mf_getuniquefileref.sas + @li mf_mkdir.sas + @li mm_createstp.sas + @li mm_createlibrary.sas + @li mm_deletelibrary.sas + @li mm_deletestp.sas + @li mm_getstpcode.sas + @li mp_assert.sas + @li mp_coretable.sas + @li mp_init.sas + @li mp_testservice.sas + @li ms_createfile.sas + @li ms_deletefile.sas + @li mx_getcode.sas + + +**/ + +%mp_init() + +%global apploc _program; + +%let defaultcontext=Datacontroller compute context; + +data _null_; + length _pgm $1000; + _pgm=symget('_program'); + if _pgm='' then do; + if "&SYSPROCESSMODE" = 'SAS Workspace Server' + then apploc= + '/30.SASApps/3030.Projects/303001.DataController/build2/DataController'; + else apploc='/Public/app/viya'; + call symputx('apploc',apploc); + call symputx('_program',cats(apploc,'/tests/services/bottom')); + end; + else do; + cnt=find(_pgm,'/tests/'); + if cnt=0 then cnt=find(_pgm,'/services/'); + if cnt=0 then cnt=find(_pgm,'/jobs/'); + apploc=substr(_pgm,1,cnt-1); + put cnt= apploc=; + call symputx('apploc',apploc); + end; +run; + +%dc_getsettings() + + +/** + * Set up Test library + */ +%let testloc=%sysfunc(pathname(&DC_LIBREF))/fmt%mf_getuniquefileref(); +%mf_mkdir(&testloc) +libname dctest "&testloc"; + +/* add formats */ +PROC FORMAT library=dctest.dcfmts; + picture MyMSdt other='%0Y-%0m-%0dT%0H:%0M:%0S' (datatype=datetime); +RUN; +data work.fmts; + length fmtname $32; + do fmtname='SMAUG','MORDOR','GOLLUM'; + do start=1 to 10; + label= cats('Dragon ',start); + output; + end; + end; +run; +proc sort data=work.fmts nodupkey; + by type fmtname fmtrow; +run; +proc format cntlin=work.fmts library=dctest.dcfmts; +run; +proc format library=dctest.dcfmts; + invalue indays (default=13) other=42; +run; +proc sql; +delete from &DC_LIBREF..mpe_tables + where libref="DCTEST" and dsn='DCFMTS-FC'; +data work.append; + if 0 then set &DC_LIBREF..mpe_tables; + tx_from=0; + tx_to='31DEC9999:23:59:59'dt; + libref="DCTEST"; + dsn='DCFMTS-FC'; + buskey='TYPE FMTNAME FMTROW'; + loadtype='FORMAT_CAT'; + num_of_approvals_required=1; + output; +run; +proc append base=&dc_libref..mpe_tables data=work.append; +run; + +/* add some other tables */ +%mp_coretable(LOCKTABLE,libds=dctest.locktable) +%mp_coretable(DIFFTABLE,libds=dctest.difftable) + + +/** + * Update settings service + */ +%let root=%mf_getapploc(&_program); +%put &=root; +filename setngs temp; +options mprint; + +%macro update_settings(); + +%if "&_debug"="2477" or "&_debug"="fields,log,trace" %then %do; + %put debug mode activated; + options mprint; + %put _global_; +%end; + +%let pf=%mf_getplatform(); +%if &pf=SASVIYA %then %do; + filename jobout filesrvc folderpath="&root/services"; + data _null_; + file setngs; + infile jobout('settings.sas') end=last; + input; + put _infile_; + if last then do; + put "libname dctest '&testloc';"; + end; + run; + data _null_; + file jobout('settings.sas'); + infile setngs; + input; + put _infile_; + putlog _infile_; + run; +%end; +%else %if &pf=SASJS %then %do; + %mx_getcode(&root/services/public/settings,outref=stngs) + + filename sendback "&sasjswork/settings2.txt" lrecl=1000; + data _null_; + file sendback; + infile stngs end=last lrecl=1000; + input; + put _infile_; + if last then do; + put "libname dctest '&testloc';"; + end; + run; + %ms_deletefile(&root/services/public/settings.sas) + + %ms_createfile(&root/services/public/settings.sas, inref=sendback,mdebug=1) +%end; +%else %do; + %let libname=DC Test; + %mm_deletelibrary(name=&libname) + %mm_createlibrary( + libname=&libname + ,libref=dctest + ,libdesc=Testing the DC + ,engine=BASE + ,tree=/30.SASApps/3030.Projects/303001.DataController + ,servercontext=SASApp + ,directory=&testloc + ,mDebug=1 + ) + + %mm_getstpcode(tree=&root/services/public + ,name=Data_Controller_Settings + ,outloc=&sasjswork/settings.txt + ) + data _null_; + file "&sasjswork/settings2.txt"; + infile "&sasjswork/settings.txt" end=last; + input; + put _infile_; + if last then do; + put "libname dctest '&testloc';"; + end; + run; + %mm_deletestp(target=&root/services/public/Data_Controller_Settings) + %mm_createstp(stpname=Data_Controller_Settings + ,filename=settings2.txt + ,directory=&sasjswork + ,tree=&root/services/public + ,Server=SASApp + ,stptype=2 + ,mdebug=1 + ,stpdesc=Data Controller Configuration + ,minify=NO + ) +%end; +%mend update_settings; + +%update_settings() + +%mp_assert( + iftrue=(&syscc=0), + desc=Makedata ran without errors, + outds=work.test_results +) + diff --git a/sas/sasjs/tests/testterm.sas b/sas/sasjs/tests/testterm.sas new file mode 100644 index 0000000..ecdabfb --- /dev/null +++ b/sas/sasjs/tests/testterm.sas @@ -0,0 +1,11 @@ +/** + @file + @brief testterm.sas + +**/ + + +%webout(OPEN) +%webout(OBJ, TEST_RESULTS) +%webout(CLOSE) + diff --git a/sas/sasjs/utils/buildinitsas9.sas b/sas/sasjs/utils/buildinitsas9.sas new file mode 100644 index 0000000..43e9a24 --- /dev/null +++ b/sas/sasjs/utils/buildinitsas9.sas @@ -0,0 +1,16 @@ +/** + @file + @brief Initialise build program for SAS 9 DC + +

SAS Macros

+**/ +options nomprint; + +%global _metaperson _url dcpath; + +/* set webout if not running in STP mode */ +data _null_; + if "&sysprocessmode" ne "SAS Stored Process Server" then do; + call execute('filename _webout temp;'); + end; +run; \ No newline at end of file diff --git a/sas/sasjs/utils/buildinitviya.sas b/sas/sasjs/utils/buildinitviya.sas new file mode 100644 index 0000000..2707003 --- /dev/null +++ b/sas/sasjs/utils/buildinitviya.sas @@ -0,0 +1,7 @@ +/** + @file buildinitviya.sas + @brief initialisation for viya build program + +**/ + +options nonotes nomprint; \ No newline at end of file diff --git a/sas/sasjs/utils/buildtermsas9.sas b/sas/sasjs/utils/buildtermsas9.sas new file mode 100644 index 0000000..8693625 --- /dev/null +++ b/sas/sasjs/utils/buildtermsas9.sas @@ -0,0 +1,190 @@ +/** + @file buildtermsas9.sas + @brief Creates the library and staging area etc + @details Creates a unique library, staging area, initial settings stp etc. + + The DCPATH should be configured in the tgtBuildVars attribute. + + +

SAS Macros

+ @li dc_assignlib.sas + @li mf_deletefile.sas + @li mf_getapploc.sas + @li mf_mkdir.sas + @li mm_createdocument.sas + @li mm_createlibrary.sas + @li mm_createstp.sas + @li mm_deletedocument.sas + @li mm_deletestp.sas + @li mm_spkexport.sas + @li mp_abort.sas + + + @version 9.2 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +%global dcpath; + +%let dclib=%upcase(DC%substr(%sysevalf(%sysfunc(datetime())/60),3,6)); +%let dclibname=Data Controller(&dclib); +%let work=%sysfunc(pathname(work)); +%let dcpath=/tmp/dcsas9/&dclib; +%let apploc=%mf_getapploc(); + +%mf_mkdir(&dcpath) +%mf_mkdir(&work) +%put &=dcpath; + +/* check we have physical permissions to the DCLIB folder */ +data _null_; + file "&dcpath/permTest.txt"; + put "something"; +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str( + User &sysuserid needs WRITE permissions on physical directory: &dcpath + ) +) +%mp_abort(iftrue= (%sysfunc(fileexist(&dcpath/permTest.txt)) ne 1) + ,mac=buildtermsas9 + ,msg=%str( + User &sysuserid could not create &dcpath/permTest.txt + ) +) +filename delfile "&dcpath/permTest.txt"; +data _null_; + rc=fdelete('delfile'); +run; +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt ) +) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Unable to write to &dcpath) +) + +/* check we have the admin rights to update the items in the Admin folder */ +%mm_createdocument(tree=&appLoc/services/admin,name=permTest) +%mm_deletedocument(target=&appLoc/services/admin/permTest) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str( + User &_metaperson does not have WriteMetadata on SAS folder: &appLoc + ) +) + +/** + * Create library and load data + */ +%let mpelibname=Data Controller (&dclib); +%mm_createlibrary( + libname=&mpelibname + ,libref=&dclib + ,libdesc=Configuration tables for the MacroPeople Data Controller application + ,engine=BASE + ,tree=&appLoc/data + ,servercontext=SASApp + ,directory=&dcpath + ,mDebug=1 +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Unable to create &dclib library) +) + +/* get direct libref */ +%dc_assignlib(READ,&dclib) + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Unable to assign &dclib library) +) + +/* create an initial settings service (this will be overwritten in the + data update step) +*/ +%let temploc=&work/temp.txt; +data _null_; + file "&temploc" ; + put '/* Data Controller Precode */' / / ; + put ' '; + put 'options noquotelenmax ps=max;'; + put '%global DC_LIBREF DC_LIBNAME DC_LIBLOC DC_STAGING_AREA DC_ADMIN_GROUP;'; + put ' '; + put '/* This metadata library (libref) contains control datasets for DC */'; + put '/* If a different libref must be used, configure it below */'; + put '%let DC_LIBREF=' "&dclib;"; + put '%let DC_LIBNAME=' "&mpelibname;"; + put ' '; + put '/* get physical path for direct libname - needed to track requests */'; + put 'data _null_;'; + put ' length lib_uri up_uri path $256;'; + put ' call missing (of _all_);'; + put ' rc=metadata_getnobj("omsobj:SASLibrary?@Libref =''&dc_libref''",1,lib_uri);'; + put ' rc=metadata_getnasn(lib_uri,"UsingPackages",1,up_uri);'; + put ' rc=metadata_getattr(up_uri,"DirectoryName",path);'; + put ' call symputx("dc_libloc",path);'; + put 'run;'; + put 'libname &DC_LIBREF "&dc_libloc";'; + put ' '; +run; + +%mm_deletestp(target=&appLoc/services/public/Data_Controller_Settings) + +%mm_createstp(stpname=Data_Controller_Settings + ,filename=temp.txt + ,directory=&work + ,tree=&appLoc/services/public + ,Server=SASApp + ,stptype=2 + ,mdebug=1 + ,stpdesc=Data Controller Configuration + ,minify=NO +) +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Issue creating settings stp) +) + +/* create script for exporting SPK */ +%let spkfile=/tmp/dcspk.sh; + +%mf_deletefile(&spkfile) + +filename myref "&spkfile" permission='A::u::rwx,A::g::r-x,A::o::---'; +%let ignore1=tests; +%let ignore2=%scan(&_program,-1,/); +%mm_spkexport(metaloc=%str(&apploc) + ,outref=myref + ,excludevars=ignore1 ignore2 + ,cmdoutloc=%str(/tmp) + ,cmdoutname=dc +) + +data _null_; + file _webout; + put "

Library &dclib successfully assigned to &dcpath on "; + put "%sysfunc(datetime(),datetime19.)

"; + put "

Now Configurate!

"; + put "Or skip it and make tables

"; +run; + + +%mp_abort(iftrue= (&syscc ne 0) + ,mac=buildtermsas9 + ,msg=%str(Some final error in &_program ) +) +/* delete if successful */ +%mm_deletestp(target=&_program) diff --git a/sas/sasjs/utils/buildtermviya.sas b/sas/sasjs/utils/buildtermviya.sas new file mode 100644 index 0000000..1312d71 --- /dev/null +++ b/sas/sasjs/utils/buildtermviya.sas @@ -0,0 +1,51 @@ +/** + @file buildviyaterm.sas + @brief build term script - prepare to call service + @details services have been built, now to build the DB. + +

SAS Macros

+ @li mx_testservice.sas + + @version 3.5 + @author 4GL Apps Ltd + @copyright 4GL Apps Ltd. This code may only be used within Data Controller + and may not be re-distributed or re-sold without the express permission of + 4GL Apps Ltd. + +**/ + +/* launch makedata with provided params */ +%global dcpath adminGroup; +data work.params; + length name $6; + name='ADMIN'; + value=coalescec("&adminGroup","SASAdministrators"); + output; + name='DCPATH'; + value=coalescec("&dcpath","/tmp/dc"); + output; +run; + +%mx_testservice(&appLoc/services/admin/makedata, + inputparams=work.params, + outlib=webout, + debug=log +) + +data _null_; + if symexist('_baseurl') then do; + url=symget('_baseurl'); + if subpad(url,length(url)-9,9)='SASStudio' + then url=substr(url,1,length(url)-11); + else url="&systcpiphostname"; + end; + else url="&systcpiphostname"; + call symputx('url',url); +run; + +%put now call configurator:; +%put x; +%put x; +%put x http://&url/SASJobExecution?_program=&appLoc/services/clickme; +%put x; +%put x; diff --git a/sas/sasjs/utils/delete_metafolder.sh b/sas/sasjs/utils/delete_metafolder.sh new file mode 100755 index 0000000..4bb90e0 --- /dev/null +++ b/sas/sasjs/utils/delete_metafolder.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Creates the file locally using arguments, then pushes the file to the remote +# SAS 9 server using SSH for execution. Finally, deletes the file. +echo remove and recreate sasjsbuild folder +rm -rf sasjsbuild +mkdir sasjsbuild + +echo "reading .env.sas9 file (from sasjs auth -t sas9)" +source .env.sas9 + +# extract password from sasjs encoding +echo $SAS_PASSWORD | cut -c 16- | base64 --decode | cut -c 201- >/tmp/tempfile.sh >.env.sas9.deleteFolder.sh +read PW < .env.sas9.deleteFolder.sh + +# create the script to be executed on the server +echo creating script +cat > .env.sas9.deleteFolder.sh <<- EOM +#!/usr/bin/env bash +cd "/opt/sas/sas9/SASHome/SASPlatformObjectFramework/9.4/tools" +./sas-delete-objects \\ + "/30.SASApps/3030.Projects/303001.DataController/build2" \\ + -host sas.4gl.io -port 8561 \\ + -user '$SAS_USERNAME' -password "$PW" \\ + -deleteContents 2>&1 +EOM + +echo copy to server: allbow@sas.4gl.io +scp .env.sas9.deleteFolder.sh allbow@sas.4gl.io:~/deleteTheFolder.sh + +echo update permissions +ssh allbow@sas.4gl.io <<'ENDSSH' + chmod 777 deleteTheFolder.sh +ENDSSH + +echo execute the script +ssh allbow@sas.4gl.io <<'ENDSSH' + ./deleteTheFolder.sh > deleteTheFolder.log +ENDSSH + +echo fetching the log +scp allbow@sas.4gl.io:~/deleteTheFolder.log ./sasjsbuild/deleteTheFolder.log + +echo printing the log +cat ./sasjsbuild/deleteTheFolder.log + diff --git a/sas/sasjs/utils/deploysas9sh.sh b/sas/sasjs/utils/deploysas9sh.sh new file mode 100755 index 0000000..bcb9bed --- /dev/null +++ b/sas/sasjs/utils/deploysas9sh.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +#################################################################### +# PROJECT: Data Controller # +# The SAS project should be checked out from +# git@gitlab.com:macropeople/dcfrontend.git +#################################################################### +cd ~/git/datacontroller/sas/sasjs/utils +# appref should also be manully updated in the delete step below +APPREF="build2" +ADMINGROUP="sec-sas9-prd-ext-sasplatform-300114sasjs" +ADMINGROUP="dc-admin" + + +BUILDSERVER="http://sas.4gl.io:7980" +BUILDSERVER="https://sas.4gl.io:8343" # without trailing slash + +STPSVR="$BUILDSERVER/SASStoredProcess/do" +BUILDSTP="/User%20Folders/allbow/My%20Folder/testJob" +APPROOT="/30.SASApps/3030.Projects/303001.DataController" + +# GET CREDENTIALS +#read -s -p "enter creds? " -i "N" -e answer +#echo "you answered: $answer" +if [ "0" != "0" ] # [ "$answer" != "N" ] +then + # get SAS creds for running the build STP + echo -n What is your SAS username? : + read USER + echo -n What is your SAS password? : + stty -echo + read PASS + stty echo + echo "username=$USER&password=$PASS">~/.ssh/sascred + echo "_username=$USER&_password=$PASS">~/.ssh/sascredurl +fi +CREDS=$(cat ~/.ssh/sascredurl) +STPURI="&STPSVR?_program=$BUILDSTP" + +mkdir -p /tmp/dc +cd ../.. + +echo current directory: $(pwd) + + +echo "copying deploy script up" +scp sasjsbuild/mysas9deploy.sas allbow@sas.4gl.io:/tmp/mysas9deploy.sas + +# pass the folder to be DELETED here (will come from the root below) +# /30.Projects/3001.Internal/300115.DataController/dc +echo "SASJS: deleting old metadata folder" +ssh allbow@sas.4gl.io <<'ENDSSH' + ./delfolder.sh build2 > ~/delfolder.txt +ENDSSH +scp allbow@sas.4gl.io:delfolder.txt /tmp/dc/delfolder.txt +cat /tmp/dc/delfolder.txt + + +##!/usr/bin/env bash +#: ${1?Need a value} +#cd "/opt/sas/sas9/SASHome/SASPlatformObjectFramework/9.4/tools" +#./sas-delete-objects -host sas.4gl.io -port 8561 -user 'allbow' -password 'xxx!' \ +# "/30.Projects/3001.Internal/300115.DataController/$1/DataController" -deleteContents 2>&1 + +# Create all the SAS services and the SPK shell script +echo "SASJS: now running $STPSVR?_program=$BUILDSTP" + +curl -v -L -k -b cookiefile -c cookiefile "$STPSVR&$CREDS" # dummy request to populate cookies +curl -v -L -k -c cookiefile -b cookiefile "$STPSVR?_program=$BUILDSTP&$CREDS" + +# Run the spkexport shell script + +#cd /tmp/dc +#./dcspk.sh USER PASS +#cp /tmp/dc/dc.spk /var/www/html/dc +echo "SASJS: executing dcspk.log" +ssh allbow@sas.4gl.io <<'ENDSSH' + ./spkexport.sh > /tmp/dcspk.log +ENDSSH +scp allbow@sas.4gl.io:/tmp/dc.spk /tmp/dc.spk +scp allbow@sas.4gl.io:/tmp/dc.log /tmp/dc.log +cat /tmp/dc/dc.log + + +# Make the tables and configurate with Admin group +BASEURL="$STPSVR?_program=$APPROOT/$APPREF/DataController" +URL="$BASEURL/services/admin/makedata&admin=$ADMINGROUP&repo=foundation&_debug=2477" + +echo "SASJS: now running $URL" + +curl -v -L -k -b cookiefile -c cookiefile "$URL&$CREDS" + +URL2="$BASEURL/services/admin/refreshcatalog" +curl -v -L -k -b cookiefile -c cookiefile "$URL2&$CREDS" + +URL3="$BASEURL/services/admin/refreshtablelineage" +curl -v -L -k -b cookiefile -c cookiefile "$URL3&$CREDS" + +echo "SASJS: Make Catalog: $URL2"; +echo "SASJS: Refresh Table Lineage: $URL3"; +echo "SASJS: DC is ready: $STPSVR?_program=$APPROOT/$APPREF/DataController/services/clickme" diff --git a/sas/sasjs/utils/export_spk.sh b/sas/sasjs/utils/export_spk.sh new file mode 100755 index 0000000..b0322f6 --- /dev/null +++ b/sas/sasjs/utils/export_spk.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Creates the file locally using arguments, then pushes the file to the remote +# SAS 9 server using SSH for execution. Finally, deletes the file. + +echo "reading .env.sas9 file (from sasjs auth -t sas9)" +source .env.sas9 + +# extract password from sasjs encoding +echo $SAS_PASSWORD | cut -c 16- | base64 --decode | cut -c 201- >/tmp/tempfile.sh >.env.sas9.exportspk.sh +read PW < .env.sas9.exportspk.sh + +# create the script to be executed on the server +echo creating export script locally +cat > .env.sas9.exportspk.sh <<- EOM + #!/usr/bin/env bash + rm /tmp/dc.spk + /tmp/dcspk.sh $SAS_USERNAME $PW +EOM + +echo copy to server: allbow@sas.4gl.io +scp .env.sas9.exportspk.sh allbow@sas.4gl.io:~/exportspk.sh + +echo update permissions +ssh allbow@sas.4gl.io <<'ENDSSH' + chmod 777 exportspk.sh +ENDSSH + +echo execute the script +ssh allbow@sas.4gl.io <<'ENDSSH' + ./exportspk.sh > exportspk.log +ENDSSH + +echo fetching the spk +scp allbow@sas.4gl.io:/tmp/dc.spk ./sasjsbuild/dc.spk + +echo fetching the script +scp allbow@sas.4gl.io:/tmp/dcspk.sh ./sasjsbuild/dcspk.sh + +echo fetching the log +scp allbow@sas.4gl.io:~/exportspk.log ./sasjsbuild/exportspk.log + +echo printing the log +cat ./sasjsbuild/exportspk.log diff --git a/sas/sasjs/utils/favicon.ico b/sas/sasjs/utils/favicon.ico new file mode 100644 index 0000000..b888dfb Binary files /dev/null and b/sas/sasjs/utils/favicon.ico differ diff --git a/sas/sasjs/utils/serviceinitsas9.sas b/sas/sasjs/utils/serviceinitsas9.sas new file mode 100644 index 0000000..1ddfa5e --- /dev/null +++ b/sas/sasjs/utils/serviceinitsas9.sas @@ -0,0 +1,23 @@ +/** + @file serviceinit.sas + @brief this file is called with every service + @details This file is included in *every* service, *after* the macros and + *before* the service code. + +

SAS Macros

+ @li mpeinit.sas + @li mpeterm.sas + +**/ + +options noquotelenmax ps=max; + +/* create dummy macros to prevent stpbegin / stpend from corrupting sessions */ + +%macro stpbegin(); +%put NOTE: the STPBEGIN macro should not be used for web apps!; +%mend stpbegin; + +%macro stpend(); +%put NOTE: the STPEND macro should not be used for web apps!; +%mend stpend; \ No newline at end of file diff --git a/sas/sasjs/utils/serviceinitserver.sas b/sas/sasjs/utils/serviceinitserver.sas new file mode 100644 index 0000000..ff48372 --- /dev/null +++ b/sas/sasjs/utils/serviceinitserver.sas @@ -0,0 +1,14 @@ +/** + @file + @brief this file is called with every service + @details This file is included in *every* service, *after* the macros and + *before* the service code. + +

SAS Macros

+ @li mpeinit.sas + @li mpeterm.sas + +**/ + +options noquotelenmax ps=max nobomfile; + diff --git a/sas/sasjs/utils/serviceinitviya.sas b/sas/sasjs/utils/serviceinitviya.sas new file mode 100644 index 0000000..fc8bd83 --- /dev/null +++ b/sas/sasjs/utils/serviceinitviya.sas @@ -0,0 +1,25 @@ +/** + @file serviceinit.sas + @brief this file is called with every service + @details This file is included in *every* service, *after* the macros and + *before* the service code. + +

SAS Macros

+ @li mpeinit.sas + @li mpeterm.sas + +**/ + +options noquotelenmax ps=max; + +cas dcsession sessopts=(caslib=casuser); +caslib _all_ assign; + +libname casuser cas caslib=casuser; + + +/*caslib casmusic path='/opt/sas/viya/cascache/tracks' libref=casmusic ;*/ + +%let syscc=0; + +%put _global_; \ No newline at end of file diff --git a/sas/sasjs/utils/serviceterm.sas b/sas/sasjs/utils/serviceterm.sas new file mode 100644 index 0000000..759ec20 --- /dev/null +++ b/sas/sasjs/utils/serviceterm.sas @@ -0,0 +1,12 @@ +/** + @file serviceterm.sas + @brief this file is called at the end of every service + @details This file is included at the *end* of every service. + +

SAS Macros

+ @li mpeterm.sas + + +**/ + + diff --git a/sas/sasjs/utils/viyadeploy.sh b/sas/sasjs/utils/viyadeploy.sh new file mode 100755 index 0000000..dbff065 --- /dev/null +++ b/sas/sasjs/utils/viyadeploy.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +#################################################################### +# PROJECT: Data Controller # +# The SAS project should be checked out from +# git@gitlab.com:macropeople/dcfrontend.git +#################################################################### + +cd ~/git/data-controller/sas +echo "copying viya deploy script up to sas.4gl.io:/tmp/dcviya/buildviya.sas" +scp sasjsbuild/myviyadeploy.sas allbow@sas.4gl.io:/tmp/dcviya/buildviya.sas + +mkdir ../client/dist/sasbuild +cp sasjsbuild/viya.json ../client/dist/sasbuild + +rsync -avhe ssh ../client/dist/* --delete allbow@sas.4gl.io:/var/www/html/dc + +echo "Now open: https://sas.4gl.io/dc"