diff --git a/.gitignore b/.gitignore index b9eda26d..302a4864 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ ezunpaywall.local.env.sh +ezunpaywall.env.local.sh config/kibana/certificates/ config/elastic/certificates/ certs/instances.yml diff --git a/README.md b/README.md index cf35ed44..d7a5324d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # ezunpaywall -Ezunpaywall is an API and database that queries the Unpaywall database containing free scholarly articles. +ezunpaywall is a Unpaywall mirror hosted in France by Inist-CNRS of data from Unpaywall since 2020 and updated daily. Unpaywall is a metadata repository of free and open access electronic resources. +This app is available at https://unpaywall.inist.fr/. **Table of content** -- [Structure](#Structure) +- [Description](#Description) +- [Network-flow](#Network-flow) - [Installation](#Installation) - [Development](#Development) - [Prerequisites](#Prerequisites) @@ -11,23 +13,42 @@ Ezunpaywall is an API and database that queries the Unpaywall database containin - [Tests](#Tests) - [Deployment](#Deployment) - [Prerequisites](#Prerequisites) - - [Environment variables](#Environment-variables) - - [apikey](/src/apikey/README.md#ezunpaywall-apikey) - - [enrich](/src/enrich/README.md#ezunpaywall-enrich) - - [frontend](/src/frontend/README.md#ezunpaywall-frontend) - - [graphql](/src/graphql/README.md#ezunpaywall-graphql) - - [health](/src/health/README.md#ezunpaywall-health) - - [mail](/src/mail/README.md#ezunpaywall-mail) - - [update](/src/update/README.md#ezunpaywall-update) - [Data update](#Data-update) - [API Graphql](#API-graphql) -## Structure +## Description -Unpaywall is made up of several services which are distributed in several docker containers. -![Structure](/doc/structure.png) +ezunpaywall operates as a service. It is updated daily with its own update service. Data is stored in an elastic index. To access this data, ezunpaywall offers 2 types of access: +- A graphql API for querying unpaywall data via one or more DOIs +- A file enrichment service that allows you to enrich a csv or jsonl file containing a column or a doi key. -for `apikey`, `enrich`, `graphql`, `health`, `mail` and `update` service, a **open api** is available on frontend +These services are accessible via API keys, which can be managed by the API key service. The keys are stored in a redis database and can be accessed by the graphql service and enrich. +A web interface is also available as a demonstrator. It allows you to : +- Show data metrics +- Examples of how to use the graphql API and enrichment service +- openAPI documentation +- A contact form +- A server administration section +- A history of data update reports. +- A healthcare service makes sure that all its services work and communicate well together. + +On the front, a nginx acts as a reverse proxy, redirecting all these services to a single entry point. + +Each service : +* [graphql](./services/graphql#ezunpaywall-graphql) +* [enrich](./services/enrich#ezunpaywall-enrich) +* [update](./services/update#ezunpaywall-update) +* [apikey](./services/apikey#ezunpaywall-apikey) +* [frontend](./services/frontend#ezunpaywall-frontend) +* [health](./services/health#ezunpaywall-health) +* [nginx](./services/nginx#ezunpaywall-nginx) +* [mail](./services/mail#ezunpaywall-mail) +* [fakeUnpaywall](./services/fakeUnpaywall#ezunpaywall-fakeUnpaywall) (only for dev) + +## Network-flow + +ezunpaywall is made up of several services which are distributed in several docker containers. +![Network-flow](./doc/network-flow.png) ## Installation @@ -69,40 +90,30 @@ To run tests, you need ezunpaywall to be launched in dev mode with fakeUnpaywall ```bash # there are alias on root folder -$ ~/ezunpaywall npm run test -$ ~/ezunpaywall npm run test:apikey -$ ~/ezunpaywall npm run test:enrich -$ ~/ezunpaywall npm run test:graphql -$ ~/ezunpaywall npm run test:update +npm run test +npm run test:apikey +npm run test:enrich +npm run test:graphql +npm run test:update # you can run test for each service -$ ~/ezunpaywall/src/apikey npm run test -$ ~/ezunpaywall/src/enrich npm run test -$ ~/ezunpaywall/src/graphql npm run test -$ ~/ezunpaywall/src/update npm run test +ezunpaywall/src/apikey npm run test +ezunpaywall/src/enrich npm run test +ezunpaywall/src/graphql npm run test +ezunpaywall/src/update npm run test ``` ### Deployment #### Prerequisites -The tools you need to let ezunpaywall run are : * docker -* unpaywall data measured about 130Gb it is necessary to provide the necessary place on the hard drive +* docker compose +* Unpaywall data in elastic with single node in index with 3 shards measured about 130Gb, it is necessary to provide the necessary place on the hard drive (storage for index + unpaywall file if you want to keep them). #### Environment variables -Create an environment file named `ezunpaywall.local.env.sh` and export the following environment variables. You can then source `ezunpaywall.env.sh`, which contains a set of predefined variables and is overriden by `ezunpaywall.local.env.sh`. +Create an environment file named `ezunpaywall.local.env.sh` and export the following environment variables. You can then source `ezunpaywall.env.sh`, which contains a set of predefined variables and is overridden by `ezunpaywall.local.env.sh`. -Details : -* [apikey](/src/apikey#ezunpaywall-apikey) -* [enrich](/src/enrich#ezunpaywall-enrich) -* [fakeUnpaywall](/src/fakeUnpaywall#ezunpaywall-fakeUnpaywall) -* [frontend](/src/frontend#ezunpaywall-frontend) -* [graphql](/src/graphql#ezunpaywall-graphql) -* [health](/src/health#ezunpaywall-health) -* [mail](/src/mail#ezunpaywall-mail) -* [nginx](/src/nginx#ezunpaywall-nginx) -* [update](/src/update#ezunpaywall-update) ### Adjust system configuration for Elasticsearch @@ -136,67 +147,3 @@ docker-compose ps You can update your data via update snapshots provided by unpaywall on a weekly or daily basis (if you have API key). in the update service, there is a cron that allows to automatically update the data from unpaywall, weekly or daily. - -## API Graphql -### unpaywall - -get unpaywall data with [parameters](#Object-structure). -### Examples -#### GET - -```js -headers: { - "x-api-key": "" -} -``` - -`GET "/api/graphql?query={unpaywall(dois:["10.1038/2211089b0","10.1038/nature12373"]){doi, is_oa, best_oa_location{ url }}}"` - -#### POST - -`POST "/api/graphql"` - -```js -headers: { - "x-api-key": "" -}, -body: { - "query": "{unpaywall(dois:[\"10.1038/2211089b0\",\"10.1038/nature12373\"]){doi, is_oa, best_oa_location{ url }}}" -} -``` - -`POST "/api/graphql"` - -```js -headers: { - "x-api-key": "" -}, -body: { - "query": "query ($dois: [ID!]!){ unpaywall(dois: $dois){is_oa} }", - "variables": { - "dois": ["10.1038/2211089b0","10.1038/nature12373"], - } -} -``` - -Response -Status: 200 - -```json -{ - "data": { - "unpaywall": [ - { - "doi": "10.1038/2211089b0", - "is_oa": true, - "best_oa_location": { - "url": "http://www.nature.com/articles/2211089b0.pdf" - } - } - ] - } -} -``` -### Object structure - -[data-format](https://unpaywall.org/data-format) \ No newline at end of file diff --git a/doc/network-flow.png b/doc/network-flow.png new file mode 100644 index 00000000..04491774 Binary files /dev/null and b/doc/network-flow.png differ diff --git a/doc/structure.png b/doc/structure.png deleted file mode 100644 index d56cb364..00000000 Binary files a/doc/structure.png and /dev/null differ diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index dc2fc50b..bf118562 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -2,10 +2,10 @@ version: "3.3" services: graphql: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-graphql-dev environment: - - NODE_ENV=development + - NODE_ENV # elastic - ELASTICSEARCH_HOSTS - ELASTICSEARCH_PORT @@ -18,7 +18,7 @@ services: - REDIS_PASSWORD working_dir: /usr/src/app volumes: - - ./src/graphql:/usr/src/app + - ./services/graphql:/usr/src/app command: "npm run dev" ports: - ${GRAPHQL_PORT:-59701}:3000 @@ -30,17 +30,18 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 200" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000/healthcheck || exit 1" ] interval: 10s timeout: 10s retries: 5 update: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-update-dev environment: - - NODE_ENV=development + - NODE_ENV + - LOG_LEVEL=debug # unpaywall - UNPAYWALL_APIKEY - UNPAYWALL_HOST @@ -64,7 +65,7 @@ services: - UPDATE_APIKEY working_dir: /usr/src/app volumes: - - ./src/update:/usr/src/app + - ./services/update:/usr/src/app command: "npm run dev" ports: - ${UPDATE_PORT:-59702}:3000 @@ -73,17 +74,17 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000/healthcheck || exit 1" ] interval: 10s timeout: 10s retries: 5 enrich: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-enrich-dev environment: - - NODE_ENV=development + - NODE_ENV # redis - REDIS_HOST - REDIS_PORT @@ -92,7 +93,7 @@ services: - GRAPHQL_HOST=http://graphql:3000 working_dir: /usr/src/app volumes: - - ./src/enrich:/usr/src/app + - ./services/enrich:/usr/src/app command: "npm run dev" ports: - ${ENRICH_PORT:-59703}:3000 @@ -106,24 +107,24 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000/healthcheck || exit 1" ] interval: 10s timeout: 10s retries: 5 apikey: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-apikey-dev environment: - - NODE_ENV=development + - NODE_ENV # redis - REDIS_HOST - REDIS_PORT - REDIS_PASSWORD working_dir: /usr/src/app volumes: - - ./src/apikey:/usr/src/app + - ./services/apikey:/usr/src/app command: "npm run dev" ports: - ${APIKEY_PORT:-59704}:3000 @@ -135,14 +136,14 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000/healthcheck || exit 1" ] interval: 10s timeout: 10s retries: 5 mail: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-mail-dev environment: - NODE_CONFIG @@ -155,7 +156,7 @@ services: - MAIL_APIKEY working_dir: /usr/src/app volumes: - - ./src/mail:/usr/src/app + - ./services/mail:/usr/src/app command: "npm run dev" ports: - ${MAIL_PORT:-59705}:3000 @@ -164,24 +165,24 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000/healthcheck || exit 1" ] interval: 10s timeout: 10s retries: 5 frontend: - image: node:18.17.1 + image: node:18.19.1 container_name: ezunpaywall-frontend-dev working_dir: /usr/src/app volumes: - - ./src/frontend:/usr/src/app + - ./services/frontend:/usr/src/app command: "npm run dev" ports: - ${FRONTEND_PORT:-59706}:3000 - 24678:24678 environment: - - NODE_ENV=development + - NODE_ENV - NUXT_PUBLIC_ENVIRONMENT=development - NUXT_PUBLIC_ELASTIC_ENV=development - NUXT_PUBLIC_VERSION=development @@ -192,20 +193,21 @@ services: - NUXT_PUBLIC_UPDATE_HOST - NUXT_PUBLIC_ENRICH_HOST - NUXT_PUBLIC_APIKEY_HOST + - NUXT_PUBLIC_MAIL_HOST + - NUXT_MAIL_HOST - NUXT_MAIL_APIKEY - - NUXT_MAIL_HOST="http://mail:3000" healthcheck: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1" ] interval: 10s timeout: 10s retries: 5 redis: - image: redis:7.2.1 + image: redis:7.2.4 container_name: ezunpaywall-redis-dev command: redis-server --requirepass "${REDIS_PASSWORD:-changeme}" volumes: @@ -223,43 +225,6 @@ services: timeout: 3s retries: 5 - health: - image: node:18.17-alpine3.18 - container_name: ezunpaywall-health-dev - working_dir: /usr/src/app - volumes: - - ./src/health:/usr/src/app - environment: - - NODE_CONFIG - command: "npm run dev" - ports: - - ${HEALTH_PORT:-59707}:3000 - restart: unless-stopped - depends_on: - enrich: - condition: service_healthy - update: - condition: service_healthy - graphql: - condition: service_healthy - apikey: - condition: service_healthy - frontend: - condition: service_healthy - redis: - condition: service_healthy - elastic: - condition: service_healthy - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 - nginx: image: nginx:1.25.2 container_name: ezunpaywall-nginx-dev @@ -276,7 +241,7 @@ services: ports: - ${NGINX_PORT:-80}:80 volumes: - - ./src/nginx/templates/http.conf.template:/etc/nginx/templates/default.conf.template:ro + - ./services/nginx/templates/dev.conf.template:/etc/nginx/templates/default.conf.template:ro restart: unless-stopped depends_on: enrich: @@ -289,22 +254,23 @@ services: condition: service_healthy mail: condition: service_healthy - health: - condition: service_healthy frontend: condition: service_healthy healthcheck: - test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80 || exit 1" ] + test: [ + "CMD-SHELL", + "service nginx status || exit 1" + ] interval: 10s timeout: 10s retries: 5 fakeunpaywall: container_name: ezunpaywall-fakeunpaywall-dev - image: node:18.17.1 + image: node:18.19.1 working_dir: /usr/src/app volumes: - - ./src/fakeUnpaywall:/usr/src/app + - ./services/fakeUnpaywall:/usr/src/app command: "npm run dev" ports: - 59799:3000 @@ -313,7 +279,7 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1" ] interval: 10s timeout: 10s @@ -326,7 +292,7 @@ services: - discovery.type=single-node - bootstrap.memory_lock=true - xpack.security.enabled=true - - ES_JAVA_OPTS=-Xms512m -Xmx512m + - ES_JAVA_OPTS=-Xms4g -Xmx4g - ELASTIC_USERNAME={ELASTICSEARCH_USERNAME:-elastic} - ELASTIC_PASSWORD=${ELASTICSEARCH_PASSWORD:-changeme} volumes: @@ -377,7 +343,7 @@ services: test: [ "CMD-SHELL", - "wget -q -S -O - http://localhost:80 2>&1 | grep 'HTTP/1.1 200 OK'" + "wget -Y off --no-verbose --tries=1 --spider http://localhost:80 || exit 1" ] interval: 10s timeout: 10s diff --git a/docker-compose.yml b/docker-compose.yml index 54a9f8f8..c6790e86 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.3" services: graphql: build: - context: ./src/graphql + context: ./services/graphql container_name: ezunpaywall-graphql-prod environment: - NODE_ENV=production @@ -27,19 +27,10 @@ services: redis: condition: service_healthy restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 update: build: - context: ./src/update + context: ./services/update args: - http_proxy - https_proxy @@ -73,19 +64,10 @@ services: - ${ELASTIC_CERT_CA_PATH-./src/update/certs/ca.crt}:/usr/src/app/certs command: "npm start" restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 enrich: build: - context: ./src/enrich + context: ./services/enrich container_name: ezunpaywall-enrich-prod environment: - NODE_ENV=production @@ -108,19 +90,10 @@ services: elastic: condition: service_healthy restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 apikey: build: - context: ./src/apikey + context: ./services/apikey container_name: ezunpaywall-apikey-prod environment: - NODE_ENV=production @@ -137,19 +110,10 @@ services: redis: condition: service_healthy restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 mail: build: - context: ./src/mail + context: ./services/mail container_name: ezunpaywall-mail-prod environment: - NODE_ENV=production @@ -168,19 +132,10 @@ services: - ${MAIL_ACCESS_LOG_PATH:-./src/mail/log/access}:/usr/src/app/log/access command: "npm start" restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 frontend: build: - context: ./src/frontend + context: ./services/frontend container_name: ezunpaywall-frontend-prod environment: - NODE_ENV=development @@ -196,67 +151,18 @@ services: - NUXT_PUBLIC_APIKEY_HOST=http://localhost/api/apikey - NUXT_MAIL_APIKEY - NUXT_MAIL_HOST="http://mail:3000" - healthcheck: - test: - [ - "CMD-SHELL", - "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" - ] - interval: 10s - timeout: 10s - retries: 5 redis: - image: redis:7.2.1-alpine3.18 + image: redis:7.2.4-alpine3.19 container_name: ezunpaywall-redis-prod command: redis-server --requirepass "${REDIS_PASSWORD}" volumes: - ${REDIS_DATA_PATH:-./data/redis}:/data restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "redis-cli --pass changeme ping | grep PONG" - ] - interval: 10s - timeout: 3s - retries: 5 - - health: - build: - context: ./src/health - container_name: ezunpaywall-health-prod - volumes: - - ${HEALTH_APPLICATION_LOG_PATH:-./src/health/log/application}:/usr/src/app/log/application - command: "npm run start" - ports: - - ${HEALTH_PORT:-59707}:3000 - restart: unless-stopped - depends_on: - enrich: - condition: service_healthy - update: - condition: service_healthy - graphql: - condition: service_healthy - apikey: - condition: service_healthy - frontend: - condition: service_healthy - redis: - condition: service_healthy - elastic: - condition: service_healthy - healthcheck: - test: [ "CMD-SHELL", "wget -q -S -O - http://localhost:3000 2>&1 | grep 'HTTP/1.1 200 OK'" ] - interval: 10s - timeout: 10s - retries: 5 nginx: build: - context: ./src/nginx + context: ./services/nginx container_name: ezunpaywall-nginx-prod environment: # host of service @@ -282,15 +188,8 @@ services: condition: service_healthy mail: condition: service_healthy - health: - condition: service_healthy frontend: condition: service_healthy - healthcheck: - test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80 || exit 1" ] - interval: 10s - timeout: 10s - retries: 5 elastic: image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2 @@ -302,11 +201,6 @@ services: - ES_JAVA_OPTS=-Xms512m -Xmx512m - ELASTIC_USERNAME={ELASTICSEARCH_USERNAME:-elastic} - ELASTIC_PASSWORD=${ELASTICSEARCH_PASSWORD:-changeme} - healthcheck: - test: curl --cacert $CERTS_DIR_ES/ca.crt -s https://localhost:9200 >/dev/null; if [[ $$? == 52 ]]; then echo 0; else echo 1; fi - interval: 10s - timeout: 10s - retries: 5 ulimits: memlock: soft: -1 @@ -314,6 +208,15 @@ services: volumes: - "./data/elastic:/usr/share/elasticsearch/data" restart: unless-stopped + healthcheck: + test: + [ + "CMD-SHELL", + "curl -s --fail http://elastic:changeme@localhost:9200" + ] + interval: 10s + timeout: 10s + retries: 5 kibana: image: docker.elastic.co/kibana/kibana:7.10.2 @@ -330,7 +233,11 @@ services: - 5601:5601 restart: unless-stopped healthcheck: - test: [ "CMD-SHELL", "curl -s --fail http://elastic:changeme@localhost:5601/api/status" ] + test: + [ + "CMD-SHELL", + "curl -s --fail http://elastic:changeme@localhost:5601/api/status" + ] interval: 10s timeout: 10s retries: 5 diff --git a/package-lock.json b/package-lock.json index 970627c8..61f0a1d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ezunpaywall", - "version": "1.2.2", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ezunpaywall", - "version": "1.2.2", + "version": "1.3.5", "hasInstallScript": true, "license": "CeCILL", "dependencies": { @@ -1123,8 +1123,7 @@ "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "ajv": { "version": "6.12.6", diff --git a/package.json b/package.json index 5a817339..3346d397 100644 --- a/package.json +++ b/package.json @@ -6,29 +6,27 @@ "license": "CeCILL", "scripts": { "prepare": "husky install", - "install:apikey": "cd src/apikey; npm install", - "install:enrich": "cd src/enrich; npm install", - "install:fakeUnpaywall": "cd src/fakeUnpaywall; npm install", - "install:frontend": "cd src/frontend; npm install", - "install:graphql": "cd src/graphql; npm install", - "install:health": "cd src/health; npm install", - "install:mail": "cd src/mail; npm install", - "install:update": "cd src/update; npm install", - "postinstall": "npm run install:apikey; npm run install:enrich; npm run install:fakeUnpaywall; npm run install:frontend; npm run install:graphql; npm run install:health; npm run install:mail; npm run install:update", - "test:apikey": "cd src/apikey; npm run test", - "test:enrich": "cd src/enrich; npm run test", - "test:graphql": "cd src/graphql; npm run test", - "test:update": "cd src/update; npm run test", + "install:apikey": "npm --prefix services/apikey install", + "install:enrich": "npm --prefix services/enrich install", + "install:fakeUnpaywall": "npm --prefix services/fakeUnpaywall install", + "install:frontend": "npm --prefix services/frontend install", + "install:graphql": "npm --prefix services/graphql install", + "install:mail": "npm --prefix services/mail install", + "install:update": "npm --prefix services/update install", + "postinstall": "npm run install:apikey; npm run install:enrich; npm run install:fakeUnpaywall; npm run install:frontend; npm run install:graphql; npm run install:mail; npm run install:update", + "test:apikey": "npm --prefix services/apikey run test", + "test:enrich": "npm --prefix services/enrich run test", + "test:graphql": "npm --prefix services/graphql run test", + "test:update": "npm --prefix services/update run test", "test": "npm run test:apikey; npm run test:enrich; npm run test:graphql; npm run test:update;", - "audit:apikey": "cd src/apikey; npm audit", - "audit:enrich": "cd src/enrich; npm audit", - "audit:fakeUnpaywall": "cd src/fakeUnpaywall; npm audit", - "audit:frontend": "cd src/frontend; npm audit", - "audit:graphql": "cd src/graphql; npm audit", - "audit:health": "cd src/health; npm audit", - "audit:mail": "cd src/mail; npm audit", - "audit:update": "cd src/update; npm audit", - "audit": "npm run audit:apikey; npm run audit:enrich; npm run audit:fakeUnpaywall; npm run audit:frontend; npm run audit:graphql; npm run audit:health; npm run audit:mail; npm run audit:update" + "audit:apikey": "npm --prefix services/apikey audit", + "audit:enrich": "npm --prefix services/enrich audit", + "audit:fakeUnpaywall": "npm --prefix services/fakeUnpaywall audit", + "audit:frontend": "npm --prefix services/frontend audit", + "audit:graphql": "npm --prefix services/graphql audit", + "audit:mail": "npm --prefix services/mail audit", + "audit:update": "npm --prefix services/update audit", + "audit": "npm run audit:apikey; npm run audit:enrich; npm run audit:fakeUnpaywall; npm run audit:frontend; npm run audit:graphql; npm run audit:mail; npm run audit:update" }, "devDependencies": { "husky": "^8.0.3" diff --git a/src/apikey/.dockerignore b/services/apikey/.dockerignore similarity index 79% rename from src/apikey/.dockerignore rename to services/apikey/.dockerignore index 520e7d7a..8f0045a7 100644 --- a/src/apikey/.dockerignore +++ b/services/apikey/.dockerignore @@ -4,4 +4,4 @@ test/ .eslintrc.json .gitignore README.md -apikey-dev.json \ No newline at end of file +apikey-dev.json diff --git a/src/apikey/.eslintrc.json b/services/apikey/.eslintrc.json similarity index 100% rename from src/apikey/.eslintrc.json rename to services/apikey/.eslintrc.json diff --git a/src/health/.gitignore b/services/apikey/.gitignore similarity index 100% rename from src/health/.gitignore rename to services/apikey/.gitignore diff --git a/services/apikey/Dockerfile b/services/apikey/Dockerfile new file mode 100644 index 00000000..09eac7fe --- /dev/null +++ b/services/apikey/Dockerfile @@ -0,0 +1,25 @@ +FROM node:18.19.1-alpine3.19 +LABEL maintainer="ezTeam " + +EXPOSE 3000 + +ENV NODE_ENV production + +ARG ACCESS_LOG_ROTATE +ARG TIMEZONE +ARG REDIS_HOST +ARG REDIS_PORT +ARG REDIS_PASSWORD +ARG ADMIN_APIKEY +ARG HEALTH_TIMEOUT + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm ci --omit=dev +COPY . . + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/services/apikey/README.md b/services/apikey/README.md new file mode 100644 index 00000000..58d85985 --- /dev/null +++ b/services/apikey/README.md @@ -0,0 +1,63 @@ +# ezunpaywall-apikey + +API key management service for access to graphql and enrich service. +This service is for administrators. + +## Config + +To set up this service, you can use environment variables. The config is displayed at startup. Sensitive data are not displayed. + +``` +# if sensitive data are not updated +warn: [config]: Apikey has the default value +warn: [config]: Redis password has the default value + +info: { + "nodeEnv": "development", + "accessLogRotate": false, + "timezone": "Europe/Paris" + "redis": { + "host": "redis", + "port": "6379", + "password": "********" + }, + "apikey": "********", + "healthTimeout": 3000 +} +``` + +## Environment variables + +| name | default | description | +| --- | --- | --- | +| NODE_ENV | development | environment of node | +| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | +| TIMEZONE | Europe/Paris | timezone of app used in cron | +| REDIS_HOST | redis | redis host | +| REDIS_PORT | 6379 | redis port | +| REDIS_PASSWORD | changeme | redis password | +| ADMIN_APIKEY | changeme | admin API key | +| HEALTH_TIMEOUT | 3000 | timeout to query the health route | + +## Cron + +One cron automatically reset the counter at 100 000 of demo API key. + +## Log format + +``` +:ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" +``` + +## Open API + +[open-api documentation](https://unpaywall.inist.fr/open-api?doc=apikey) + +## Test + +``` +# Functional tests +npm run test +# Unit test +# it's your turn to play +``` \ No newline at end of file diff --git a/src/apikey/apikey-dev.json b/services/apikey/apikey-dev.json similarity index 100% rename from src/apikey/apikey-dev.json rename to services/apikey/apikey-dev.json diff --git a/services/apikey/app.js b/services/apikey/app.js new file mode 100644 index 00000000..5a7b6e0e --- /dev/null +++ b/services/apikey/app.js @@ -0,0 +1,57 @@ +const express = require('express'); +const cors = require('cors'); +const fs = require('fs-extra'); +const path = require('path'); +const { paths } = require('config'); + +const accessLogger = require('./src/logger/access'); +const appLogger = require('./src/logger/appLogger'); + +const getConfig = require('./src/config'); + +const { pingRedis, startConnectionRedis, loadDemoAPIKey } = require('./src/services/redis'); + +const cronDemo = require('./src/cron'); + +const routerHealthCheck = require('./src/routers/healthcheck'); +const routerPing = require('./src/routers/ping'); +const routerAdmin = require('./src/routers/admin'); +const routerManage = require('./src/routers/manage'); +const routerOpenapi = require('./src/routers/openapi'); + +// create log directory +fs.ensureDir(path.resolve(paths.log.applicationDir)); +fs.ensureDir(path.resolve(paths.log.accessDir)); +fs.ensureDir(path.resolve(paths.log.healthCheckDir)); + +const app = express(); + +app.use(express.json()); +app.use(cors()); + +// initiate healthcheck router with his logger +app.use(routerHealthCheck); + +// initiate access logger +app.use(accessLogger); + +// initiate all other routes +app.use(routerAdmin); +app.use(routerPing); +app.use(routerManage); +app.use(routerOpenapi); +app.use(routerPing); + +// Errors and unknown routes +app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}: this route does not exist.` })); + +app.use((error, req, res, next) => res.status(500).json({ message: error.message })); + +app.listen(3000, async () => { + appLogger.info('[express]: ezunpaywall apikey service listening on 3000'); + getConfig(); + await startConnectionRedis(); + pingRedis(); + loadDemoAPIKey(); + cronDemo.start(); +}); diff --git a/src/apikey/config/custom-environment-variables.json b/services/apikey/config/custom-environment-variables.json similarity index 79% rename from src/apikey/config/custom-environment-variables.json rename to services/apikey/config/custom-environment-variables.json index eff9689a..507f0059 100644 --- a/src/apikey/config/custom-environment-variables.json +++ b/services/apikey/config/custom-environment-variables.json @@ -1,11 +1,12 @@ { "nodeEnv": "NODE_ENV", "accessLogRotate": "ACCESS_LOG_ROTATE", + "timezone": "TIMEZONE", "redis": { "host": "REDIS_HOST", "port": "REDIS_PORT", "password": "REDIS_PASSWORD" }, - "apikey": "APIKEY_APIKEY", + "apikey": "ADMIN_APIKEY", "healthTimeout": "HEALTH_TIMEOUT" } \ No newline at end of file diff --git a/services/apikey/config/default.json b/services/apikey/config/default.json new file mode 100644 index 00000000..2c0c84cf --- /dev/null +++ b/services/apikey/config/default.json @@ -0,0 +1,20 @@ +{ + "nodeEnv": "development", + "accessLogRotate": false, + "healthcheckLogRotate": false, + "timezone": "Europe/Paris", + "redis": { + "host": "redis", + "port": "6379", + "password": "changeme" + }, + "paths": { + "log": { + "applicationDir": "./log/application", + "accessDir": "./log/access", + "healthCheckDir": "./log/healthcheck" + } + }, + "apikey": "changeme", + "healthTimeout": 3000 +} \ No newline at end of file diff --git a/services/apikey/openapi.yml b/services/apikey/openapi.yml new file mode 100644 index 00000000..afa1d893 --- /dev/null +++ b/services/apikey/openapi.yml @@ -0,0 +1,477 @@ +openapi: 3.0.0 +info: + description: The Apikey service is reserved for the administrators, it allows to manage the API keys + version: 1.0.0 + title: Apikey service + contact: + email: ezteam@couperin.org + name: ezTeam + license: + name: CeCILL 2.1 + url: http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html +servers: + - url: https://unpaywall.inist.fr/api +tags: + - name: apikey + - name: ping +paths: + /apikey: + get: + tags: + - ping + summary: Name of service + operationId: get-apikey + description: Name of service + parameters: [] + responses: + '200': + description: OK + content: + Success: + examples: + response: + value: apikey service + schema: + type: string + x-examples: + example-1: apikey service + /apikey/ping: + get: + tags: + - ping + summary: Ping apikey service + operationId: get-apikey-ping + description: Ping apikey service + responses: + '204': + description: No Content + + /apikey/health: + get: + tags: + - ping + summary: Health + operationId: get-apikey-health + description: Health on all service connected to apikey service + parameters: [] + responses: + '200': + description: OK + content: + application/json: + examples: + Success: + value: + redis: + elapsedTime: 0 + status: true + elapsedTime: 0 + status: true + Error redis: + value: + redis: + elapsedTime: 3000 + status: false + error: time out + elapsedTime: 3001 + status: false + schema: + type: object + properties: + redis: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elapsedTime: + type: integer + status: + type: boolean + x-examples: + Example 1: + redis: + elapsedTime: 0 + status: true + elapsedTime: 0 + status: true + + /apikey/health/redis: + get: + summary: Health on redis service + operationId: get-apikey-health-redis + description: Health on redis + tags: + - ping + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + parameters: [] + /apikey/keys/${apikey}: + get: + tags: + - apikey + summary: Get config of apikey + operationId: get-apikey-keys-$-apikey + description: Get config of apikey + parameters: + - in: path + name: apikey + description: apikey + required: true + schema: + type: string + responses: + '200': + description: config of apikey + content: + application/json: + schema: + type: object + properties: + apikey: + type: string + default: azerty + name: + type: string + default: john doe + attributes: + type: array + items: + type: string + default: '*' + access: + type: array + items: + type: string + default: graphql + allowed: + type: boolean + put: + tags: + - apikey + summary: Update apikey + operationId: put-apikeys-keys-$-apikey + description: Update apikey + security: + - x-api-key: [] + parameters: + - in: path + name: apikey + description: apikey + required: true + schema: + type: string + responses: + '200': + description: update apikey + content: + application/json: + schema: + type: object + properties: + apikey: + type: string + default: azerty + name: + type: string + default: john doe + attributes: + type: array + items: + type: string + default: '*' + access: + type: array + items: + type: string + default: graphql + allowed: + type: boolean + examples: + John Doe apikey: + value: + apikey: azerty + name: john doe + attributes: + - '*' + access: + - graphql + allowed: true + '400': + description: Bad Request + content: + application/json: + schema: + type: object + properties: + message: + type: string + x-examples: + example-1: + message: '"name" is required' + examples: + Name is required: + value: + message: '"name" is required' + '401': + $ref: '#/components/responses/Not-authorized' + delete: + tags: + - apikey + summary: Delete apikey + operationId: delete-apikey-keys-$-apikey + description: Delete apikey + security: + - x-api-key: [] + parameters: + - in: path + name: apikey + description: apikey + required: true + schema: + type: string + responses: + '204': + description: apikey deleted + '401': + $ref: '#/components/responses/Not-authorized' + /apikey/keys: + get: + tags: + - apikey + summary: Get all config of all apikey + operationId: get-apikey-keys + description: Get all config of all apikey + security: + - x-api-key: [] + responses: + '200': + description: update apikey + content: + application/json: + schema: + type: array + items: + type: object + properties: + apikey: + type: string + default: azerty + name: + type: string + default: john doe + attributes: + type: array + items: + type: string + default: '*' + access: + type: array + items: + type: string + default: graphql + allowed: + type: boolean + examples: + John doe apikey: + value: + - apikey: azerty + name: john doe + attributes: + - '*' + access: + - graphql + allowed: true + apikey of John Doe: + examples: + response: + value: + - apikey: azerty123456 + name: John Doe + attributes: + - '*' + access: + - graphql + allowed: true + '401': + $ref: '#/components/responses/Not-authorized' + delete: + tags: + - apikey + summary: Delete all apikey + operationId: delete-apikey-keys + description: Delete all apikey + security: + - x-api-key: [] + responses: + '204': + description: all apikey are deleted + '401': + $ref: '#/components/responses/Not-authorized' + post: + tags: + - apikey + summary: Create apikey + operationId: post-apikey-keys + description: Create new apikey + security: + - x-api-key: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + attributes: + type: array + items: + type: string + access: + type: array + items: + type: string + allowed: + type: boolean + description: config for apikey + required: true + responses: + '200': + description: update apikey + content: + application/json: + schema: + type: object + properties: + apikey: + type: string + default: azerty + name: + type: string + default: john doe + attributes: + type: array + items: + type: string + default: '*' + access: + type: array + items: + type: string + default: graphql + allowed: + type: boolean + '401': + $ref: '#/components/responses/Not-authorized' + /apikey/keys/load: + post: + tags: + - apikey + summary: Load apikey + operationId: post-apikeys-keys-load + description: Load apikey + security: + - x-api-key: [] + requestBody: + content: + application/json: + schema: + type: array + items: + type: object + properties: + apikey: + type: string + name: + type: string + attributes: + type: array + items: + type: string + access: + type: array + items: + type: string + allowed: + type: boolean + x-examples: + example-1: + - apikey: string + name: string + attributes: + - string + access: + - string + allowed: true + examples: + example-1: + value: + - apikey: string + name: string + attributes: + - string + access: + - string + allowed: true + description: apikeys + required: true + responses: + '204': + description: all apikey are loaded + '401': + $ref: '#/components/responses/Not-authorized' +components: + responses: + Not-authorized: + description: Not authorized + headers: + x-api-key: + schema: + type: string + description: redis password + content: + application/json: + examples: + response: + value: + message: Not authorized + + Health: + description: Example response + content: + application/json: + schema: + type: object + properties: + name: + type: string + status: + type: boolean + elapsedTime: + type: integer + x-examples: + Example 1: + name: redis + status: true + elapsedTime: 1 + examples: + Success: + value: + name: name of service + status: true + elapsedTime: 1 + Error redis: + value: + name: redis + elapsedTime: 3002 + error: time out + status: false + securitySchemes: + x-api-key: + name: API Key + type: apiKey + in: header diff --git a/src/apikey/package-lock.json b/services/apikey/package-lock.json similarity index 99% rename from src/apikey/package-lock.json rename to services/apikey/package-lock.json index a49381f4..f37e3c26 100644 --- a/src/apikey/package-lock.json +++ b/services/apikey/package-lock.json @@ -1,12 +1,12 @@ { "name": "ezunpaywall-apikey", - "version": "1.3.0", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ezunpaywall-apikey", - "version": "1.3.0", + "version": "1.3.5", "license": "CeCILL", "dependencies": { "config": "^3.3.9", @@ -14,6 +14,7 @@ "cron": "^2.4.3", "date-fns": "^2.30.0", "express": "^4.18.2", + "express-rate-limit": "^7.2.0", "fs-extra": "^11.1.1", "joi": "^17.10.1", "lodash.isequal": "^4.5.0", @@ -1676,6 +1677,20 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz", + "integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/express/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4603,8 +4618,7 @@ "@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "requires": {} + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==" }, "@redis/client": { "version": "1.5.9", @@ -4619,26 +4633,22 @@ "@redis/graph": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "requires": {} + "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==" }, "@redis/json": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", - "requires": {} + "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==" }, "@redis/search": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "requires": {} + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==" }, "@redis/time-series": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==" }, "@sideway/address": { "version": "4.1.3", @@ -4719,8 +4729,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", @@ -5667,6 +5676,11 @@ } } }, + "express-rate-limit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz", + "integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", diff --git a/src/apikey/package.json b/services/apikey/package.json similarity index 96% rename from src/apikey/package.json rename to services/apikey/package.json index a069f0e1..1997ebb8 100644 --- a/src/apikey/package.json +++ b/services/apikey/package.json @@ -17,6 +17,7 @@ "cron": "^2.4.3", "date-fns": "^2.30.0", "express": "^4.18.2", + "express-rate-limit": "^7.2.0", "fs-extra": "^11.1.1", "joi": "^17.10.1", "lodash.isequal": "^4.5.0", diff --git a/src/apikey/lib/attributes.js b/services/apikey/src/attributes.js similarity index 100% rename from src/apikey/lib/attributes.js rename to services/apikey/src/attributes.js diff --git a/src/apikey/lib/config.js b/services/apikey/src/config.js similarity index 93% rename from src/apikey/lib/config.js rename to services/apikey/src/config.js index da8fb3ea..abdc7b9c 100644 --- a/src/apikey/lib/config.js +++ b/services/apikey/src/config.js @@ -1,6 +1,6 @@ const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const defaultConfig = require('../config/default.json'); const copyConfig = JSON.parse(JSON.stringify(config)); diff --git a/src/apikey/lib/controllers/health.js b/services/apikey/src/controllers/health.js similarity index 100% rename from src/apikey/lib/controllers/health.js rename to services/apikey/src/controllers/health.js diff --git a/src/apikey/lib/controllers/manage.js b/services/apikey/src/controllers/manage.js similarity index 99% rename from src/apikey/lib/controllers/manage.js rename to services/apikey/src/controllers/manage.js index 6d31f2c0..d2b762d3 100644 --- a/src/apikey/lib/controllers/manage.js +++ b/services/apikey/src/controllers/manage.js @@ -1,7 +1,7 @@ const apikeyService = require('../services/apikeys'); const { redisClient, load } = require('../services/redis'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Controller to get config of apikey. diff --git a/src/apikey/lib/cron.js b/services/apikey/src/cron.js similarity index 60% rename from src/apikey/lib/cron.js rename to services/apikey/src/cron.js index 7b00a199..9ce2f0ad 100644 --- a/src/apikey/lib/cron.js +++ b/services/apikey/src/cron.js @@ -1,5 +1,7 @@ const { CronJob } = require('cron'); -const logger = require('./logger'); +const { timezone } = require('config'); + +const logger = require('./logger/appLogger'); const { redisClient } = require('./services/redis'); @@ -11,14 +13,14 @@ const cronDemo = new CronJob('0 0 0 * * *', async () => { try { apikeyConfig = await redisClient.get('demo'); } catch (err) { - logger.error('[cron demo] Cannot get [demo]', err); + logger.error('[cron][demo]: Cannot get [demo]', err); return; } try { apikeyConfig = JSON.parse(apikeyConfig); } catch (err) { - logger.error(`[cron demo] Cannot parse [${apikeyConfig}]`, err); + logger.error(`[cron][demo]: Cannot parse [${apikeyConfig}]`, err); return; } @@ -27,10 +29,10 @@ const cronDemo = new CronJob('0 0 0 * * *', async () => { try { await redisClient.set('demo', `${JSON.stringify(apikeyConfig)}`); } catch (err) { - logger.error(`[cron demo] Cannot update apikey [demo] with config [${JSON.stringify(apikeyConfig)}]`, err); + logger.error(`[cron][demo]: Cannot update apikey [demo] with config [${JSON.stringify(apikeyConfig)}]`, err); return Promise.reject(err); } - logger.info('[cron demo] Demo apikey is reseted'); -}, null, true, 'Europe/Paris'); + logger.info('[cron][demo]: Demo apikey has been reset'); +}, null, true, timezone); module.exports = cronDemo; diff --git a/src/update/lib/morgan.js b/services/apikey/src/logger/access.js similarity index 70% rename from src/update/lib/morgan.js rename to services/apikey/src/logger/access.js index 9e16d039..fda3b593 100644 --- a/src/update/lib/morgan.js +++ b/services/apikey/src/logger/access.js @@ -3,14 +3,14 @@ const fs = require('fs-extra'); const rfs = require('rotating-file-stream'); const path = require('path'); const { format } = require('date-fns'); -const { accessLogRotate } = require('config'); +const { nodeEnv, paths, accessLogRotate } = require('config'); -const accessLogDir = path.resolve(__dirname, '..', 'log', 'access'); +const isProd = (nodeEnv === 'production'); /** * Get the name of access file. * - * @param {number} date - Date in minisecond + * @param {number} date - Date in milliseconds * * @returns {string} Name of access file. */ @@ -24,10 +24,10 @@ let accessLogStream; if (accessLogRotate) { accessLogStream = rfs.createStream(logFilename, { interval: '1d', // rotate daily - path: accessLogDir, + path: paths.log.accessDir, }); } else { - accessLogStream = fs.createWriteStream(path.resolve(accessLogDir, 'access.log'), { flags: 'a+' }); + accessLogStream = fs.createWriteStream(path.resolve(paths.log.accessDir, 'access.log'), { flags: 'a+' }); } morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); @@ -37,4 +37,4 @@ morgan.token('user', (req) => { return '-'; }); -module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: accessLogStream }); +module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: isProd ? accessLogStream : process.stdout }); diff --git a/src/enrich/lib/logger.js b/services/apikey/src/logger/appLogger.js similarity index 91% rename from src/enrich/lib/logger.js rename to services/apikey/src/logger/appLogger.js index d2d91902..e83d3544 100644 --- a/src/enrich/lib/logger.js +++ b/services/apikey/src/logger/appLogger.js @@ -1,5 +1,5 @@ const path = require('path'); -const { nodeEnv } = require('config'); +const { nodeEnv, paths } = require('config'); const isProd = (nodeEnv === 'production'); @@ -22,7 +22,7 @@ const { const processConfiguration = [ new transports.DailyRotateFile({ name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), + filename: path.resolve(paths.log.applicationDir, '%DATE%.log'), datePattern: 'yyyy-MM-DD', level: 'info', }), diff --git a/services/apikey/src/logger/healthcheck.js b/services/apikey/src/logger/healthcheck.js new file mode 100644 index 00000000..f56e9d9f --- /dev/null +++ b/services/apikey/src/logger/healthcheck.js @@ -0,0 +1,41 @@ +const morgan = require('morgan'); +const fs = require('fs-extra'); +const rfs = require('rotating-file-stream'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths, healthcheckLogRotate } = require('config'); + +/** + * Get the name of healthcheck log file. + * + * @param {number} date - Date in milliseconds + * + * @returns {string} Name of healthcheck log file. + */ +function logFilename(date) { + if (!date) return 'healthcheck.log'; + return `${format(new Date(date) - 1000 * 60 * 60 * 24, 'yyyy-MM-dd')}-healthcheck.log`; +} + +let healthCheckLogStream; + +if (healthcheckLogRotate) { + healthCheckLogStream = rfs.createStream(logFilename, { + interval: '1d', // rotate daily + path: paths.log.healthCheckDir, + }); +} else { + healthCheckLogStream = fs.createWriteStream(path.resolve(paths.log.healthCheckDir, 'healthcheck.log'), { flags: 'a+' }); +} + +morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); + +morgan.token('user', (req) => { + if (req.user) return req.user; + return '-'; +}); + +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: healthCheckLogStream }, +); diff --git a/src/apikey/lib/middlewares/apikey.js b/services/apikey/src/middlewares/apikey.js similarity index 100% rename from src/apikey/lib/middlewares/apikey.js rename to services/apikey/src/middlewares/apikey.js diff --git a/src/apikey/lib/middlewares/auth.js b/services/apikey/src/middlewares/auth.js similarity index 100% rename from src/apikey/lib/middlewares/auth.js rename to services/apikey/src/middlewares/auth.js diff --git a/src/update/lib/middlewares/dev.js b/services/apikey/src/middlewares/dev.js similarity index 87% rename from src/update/lib/middlewares/dev.js rename to services/apikey/src/middlewares/dev.js index 70cf93af..f3d153fc 100644 --- a/src/update/lib/middlewares/dev.js +++ b/services/apikey/src/middlewares/dev.js @@ -1,4 +1,4 @@ -const config = require('config'); +const { nodeEnv } = require('config'); /** * dev middleware that checks if NODE_ENV is equal to development @@ -10,7 +10,7 @@ const config = require('config'); * This middleware need a header that contains the apikey. */ async function dev(req, res, next) { - const env = config.get('nodeEnv'); + const env = nodeEnv; if (env !== 'development') { return res.status(404).json({ message: 'Not found' }); diff --git a/services/apikey/src/middlewares/rateLimit.js b/services/apikey/src/middlewares/rateLimit.js new file mode 100644 index 00000000..976ad58e --- /dev/null +++ b/services/apikey/src/middlewares/rateLimit.js @@ -0,0 +1,8 @@ +const rateLimit = require('express-rate-limit'); + +const rateLimiter = rateLimit({ + windowMs: 1000, + max: 2, +}); + +module.exports = rateLimiter; diff --git a/src/apikey/lib/ping.js b/services/apikey/src/ping.js similarity index 100% rename from src/apikey/lib/ping.js rename to services/apikey/src/ping.js diff --git a/src/apikey/lib/routers/admin.js b/services/apikey/src/routers/admin.js similarity index 62% rename from src/apikey/lib/routers/admin.js rename to services/apikey/src/routers/admin.js index cb68ce38..fbab22a6 100644 --- a/src/apikey/lib/routers/admin.js +++ b/services/apikey/src/routers/admin.js @@ -1,11 +1,12 @@ const router = require('express').Router(); const checkAuth = require('../middlewares/auth'); +const rateLimiter = require('../middlewares/rateLimit'); /** * Route that checks if the content of the x-api-key header * matches the environment variable used as password. */ -router.post('/login', checkAuth, async (req, res) => res.status(204).json()); +router.post('/login', checkAuth, rateLimiter, async (req, res) => res.status(204).json()); module.exports = router; diff --git a/services/apikey/src/routers/healthcheck.js b/services/apikey/src/routers/healthcheck.js new file mode 100644 index 00000000..5eb10fe8 --- /dev/null +++ b/services/apikey/src/routers/healthcheck.js @@ -0,0 +1,10 @@ +const router = require('express').Router(); + +const healthCheckLogger = require('../logger/healthcheck'); + +/** + * Route use for healthcheck. + */ +router.get('/healthcheck', healthCheckLogger, (req, res, next) => res.status(204).end()); + +module.exports = router; diff --git a/src/apikey/lib/routers/manage.js b/services/apikey/src/routers/manage.js similarity index 100% rename from src/apikey/lib/routers/manage.js rename to services/apikey/src/routers/manage.js diff --git a/services/apikey/src/routers/openapi.js b/services/apikey/src/routers/openapi.js new file mode 100644 index 00000000..6faa2bcc --- /dev/null +++ b/services/apikey/src/routers/openapi.js @@ -0,0 +1,9 @@ +const router = require('express').Router(); +const path = require('path'); + +/** + * Route that give the openapi.yml file. + */ +router.get('/openapi.yml', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'openapi.yml'))); + +module.exports = router; diff --git a/src/apikey/lib/routers/ping.js b/services/apikey/src/routers/ping.js similarity index 100% rename from src/apikey/lib/routers/ping.js rename to services/apikey/src/routers/ping.js diff --git a/src/apikey/lib/services/apikeys.js b/services/apikey/src/services/apikeys.js similarity index 98% rename from src/apikey/lib/services/apikeys.js rename to services/apikey/src/services/apikeys.js index a1a76141..345698ff 100644 --- a/src/apikey/lib/services/apikeys.js +++ b/services/apikey/src/services/apikeys.js @@ -2,7 +2,7 @@ const crypto = require('crypto'); const { format } = require('date-fns'); const { redisClient } = require('./redis'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Get config of apikey diff --git a/src/apikey/lib/services/redis.js b/services/apikey/src/services/redis.js similarity index 75% rename from src/apikey/lib/services/redis.js rename to services/apikey/src/services/redis.js index a29626a8..54e38d0b 100644 --- a/src/apikey/lib/services/redis.js +++ b/services/apikey/src/services/redis.js @@ -1,20 +1,20 @@ const path = require('path'); -const redis = require('redis'); +const { createClient } = require('redis'); const util = require('util'); -const config = require('config'); +const { redis } = require('config'); const fs = require('fs-extra'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); let apiKeys; -const redisClient = redis.createClient({ +const redisClient = createClient({ legacyMode: true, socket: { - host: config.get('redis.host'), - port: config.get('redis.port'), + host: redis.host, + port: redis.port, }, - password: config.get('redis.password'), + password: redis.password, }); redisClient.get = util.promisify(redisClient.get); @@ -29,7 +29,7 @@ redisClient.on('error', (err) => { }); /** - * Load the dev apikeys on redis from apikey-dev.json. + * Load the dev apiKeys on redis from apikey-dev.json. * Using for test. * * @returns {Promise} @@ -46,13 +46,13 @@ async function load() { await redisClient.set(apikey, JSON.stringify(configApikey)); logger.info(`[redis] ${configApikey.name} is loaded`); } catch (err) { - logger.error(`[redis] Cannot load [${apikey}] with config [${JSON.stringify(config)}]`, err); + logger.error(`[redis] Cannot load [${apikey}] with config [${JSON.stringify(configApikey)}]`, err); } } } /** - * Load the dev apikeys on redis from apikey-dev.json. + * Load the dev apiKeys on redis from apikey-dev.json. * Using for test. * * @returns {Promise} ping @@ -61,7 +61,7 @@ async function pingRedis() { try { await redisClient.ping(); } catch (err) { - logger.error(`[redis] Cannot ping ${config.get('redis.host')}:${config.get('redis.port')}`, err); + logger.error(`[redis] Cannot ping ${redis.host}:${redis.port}`, err); return false; } return true; @@ -71,10 +71,10 @@ async function startConnectionRedis() { try { await redisClient.connect(); } catch (err) { - logger.error(`[redis] Cannot start connection ${config.get('redis.host')}:${config.get('redis.port')}`, err); + logger.error(`[redis] Cannot start connection ${redis.host}:${redis.port}`, err); return false; } - logger.info(`[redis] connect success ${config.get('redis.host')}:${config.get('redis.port')}`); + logger.info(`[redis] connect success ${redis.host}:${redis.port}`); return true; } diff --git a/src/apikey/test/auth.js b/services/apikey/test/auth.js similarity index 100% rename from src/apikey/test/auth.js rename to services/apikey/test/auth.js diff --git a/src/apikey/test/create.js b/services/apikey/test/create.js similarity index 100% rename from src/apikey/test/create.js rename to services/apikey/test/create.js diff --git a/src/apikey/test/delete.js b/services/apikey/test/delete.js similarity index 100% rename from src/apikey/test/delete.js rename to services/apikey/test/delete.js diff --git a/src/apikey/test/get.js b/services/apikey/test/get.js similarity index 100% rename from src/apikey/test/get.js rename to services/apikey/test/get.js diff --git a/src/apikey/test/update.js b/services/apikey/test/update.js similarity index 100% rename from src/apikey/test/update.js rename to services/apikey/test/update.js diff --git a/src/apikey/test/utils/apikey.js b/services/apikey/test/utils/apikey.js similarity index 100% rename from src/apikey/test/utils/apikey.js rename to services/apikey/test/utils/apikey.js diff --git a/src/apikey/test/utils/ping.js b/services/apikey/test/utils/ping.js similarity index 100% rename from src/apikey/test/utils/ping.js rename to services/apikey/test/utils/ping.js diff --git a/src/enrich/.dockerignore b/services/enrich/.dockerignore similarity index 100% rename from src/enrich/.dockerignore rename to services/enrich/.dockerignore diff --git a/src/enrich/.eslintrc.json b/services/enrich/.eslintrc.json similarity index 100% rename from src/enrich/.eslintrc.json rename to services/enrich/.eslintrc.json diff --git a/services/enrich/.gitignore b/services/enrich/.gitignore new file mode 100644 index 00000000..07f16694 --- /dev/null +++ b/services/enrich/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +log/ +data/ \ No newline at end of file diff --git a/services/enrich/Dockerfile b/services/enrich/Dockerfile new file mode 100644 index 00000000..1023a41e --- /dev/null +++ b/services/enrich/Dockerfile @@ -0,0 +1,25 @@ +FROM node:18.19.1-alpine3.19 +LABEL maintainer="ezTeam " + +EXPOSE 3000 + +ENV NODE_ENV production + +ARG ACCESS_LOG_ROTATE +ARG TIMEZONE +ARG REDIS_HOST +ARG REDIS_PORT +ARG REDIS_PASSWORD +ARG GRAPHQL_HOST +ARG HEALTH_TIMEOUT + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm ci --omit=dev +COPY . . + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/services/enrich/README.md b/services/enrich/README.md new file mode 100644 index 00000000..7c91baa3 --- /dev/null +++ b/services/enrich/README.md @@ -0,0 +1,114 @@ +# ezunpaywall-enrich + +Service that enrich csv and jsonl file with unpaywall data. + +## Config + +To set up this service, you can use environment variables. The config is displayed at startup. Sensitive data are not displayed. + +``` +# if sensitive data are not updated +warn: [config]: Redis password has the default value + +info: { + "nodeEnv": "development", + "accessLogRotate": false, + "timezone": "Europe/Paris", + "redis": { + "host": "redis", + "port": 6379, + "password": "********" + }, + "graphql": { + "host": "http://graphql:3000" + }, + "healthTimeout": 3000 +} +``` + +## Service environment variables + +| name | default | description | +| --- | --- | --- | +| NODE_ENV | development | environment of node | +| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | +| TIMEZONE | Europe/Paris | timezone of app used in cron | +| REDIS_HOST | redis | redis host | +| REDIS_PORT | 6379 | redis port | +| REDIS_PASSWORD | changeme | redis password | +| GRAPHQL_HOST | http://graphql:3000 | graphql host | +| HEALTH_TIMEOUT | 3000 | timeout to query the health route | + +## Activity diagram + +Enrich process + +![Activity-diagram](./doc/activity-diagram-enrich.png) + +### Data + +2 types of file is generated by enrich job : +- uploaded file +- enriched file +- states of enrich process + +They are structured like this +``` +data +├── enriched +│ ├── user01 +| ├── 00000000-0000-0000-0000-000000000001.csv +│ ├── 00000000-0000-0000-0000-000000000001.jsonl +│ ├── ... +│ └── 00000000-0000-0000-0000-000000000010.csv +│ └── user02 +│ ├── 00000000-0000-0000-0000-000000000001.csv +│ ├── 00000000-0000-0000-0000-000000000001.jsonl +│ ├── ... +│ └── 00000000-0000-0000-0000-000000000010.csv +├── states +│ ├── user01 +| ├── 00000000-0000-0000-0000-000000000001.csv +│ ├── 00000000-0000-0000-0000-000000000001.jsonl +│ ├── ... +│ └── 00000000-0000-0000-0000-000000000010.csv +│ └── user02 +│ ├── 00000000-0000-0000-0000-000000000001.csv +│ ├── 00000000-0000-0000-0000-000000000001.jsonl +│ ├── ... +│ └── 00000000-0000-0000-0000-000000000010.csv +└── upload + ├── user01 + ├── 00000000-0000-0000-0000-000000000001.csv + ├── 00000000-0000-0000-0000-000000000001.jsonl + ├── ... + └── 00000000-0000-0000-0000-000000000010.csv + └── user02 + ├── 00000000-0000-0000-0000-000000000001.csv + ├── 00000000-0000-0000-0000-000000000001.jsonl + ├── ... + └── 00000000-0000-0000-0000-000000000010.csv +``` + +### Cron + +One cron automatically deletes files generated by updates that are more than 30 days old. + +## Log format + +``` +:ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" +``` + +## Open API + +[open-api documentation](https://unpaywall.inist.fr/open-api?doc=enrich) + +## Test + +``` +# Functional tests +npm run test +# Unit test +# it's your turn to play +``` \ No newline at end of file diff --git a/services/enrich/app.js b/services/enrich/app.js new file mode 100644 index 00000000..cf8018c2 --- /dev/null +++ b/services/enrich/app.js @@ -0,0 +1,63 @@ +const express = require('express'); +const fs = require('fs-extra'); +const cors = require('cors'); +const { paths } = require('config'); + +const accessLogger = require('./src/logger/access'); +const appLogger = require('./src/logger/appLogger'); + +const getConfig = require('./src/config'); + +const { startConnectionRedis, pingRedis } = require('./src/services/redis'); + +require('./src/cron'); + +const routerHealthCheck = require('./src/routers/healthcheck'); +const routerPing = require('./src/routers/ping'); +const routerJob = require('./src/routers/job'); +const routerFile = require('./src/routers/file'); +const routerState = require('./src/routers/state'); +const routerOpenapi = require('./src/routers/openapi'); + +// create data directory +fs.ensureDir(paths.data.enrichedDir); +fs.ensureDir(paths.data.statesDir); +fs.ensureDir(paths.data.uploadDir); + +// create log directory +fs.ensureDir(paths.log.healthCheckDir); +fs.ensureDir(paths.log.applicationDir); +fs.ensureDir(paths.log.accessDir); + +const app = express(); + +app.use(cors({ + origin: '*', + allowedHeaders: ['Content-Type', 'x-api-key'], + method: ['GET', 'POST'], +})); + +app.use(express.urlencoded({ extended: true })); +app.use(express.json()); + +app.use(routerHealthCheck); + +app.use(accessLogger); + +app.use(routerJob); +app.use(routerFile); +app.use(routerState); +app.use(routerOpenapi); +app.use(routerPing); + +// Errors and unknown routes +app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}: this route does not exist.` })); + +app.use((error, req, res, next) => res.status(500).json({ message: error.message })); + +app.listen(3000, async () => { + appLogger.info('[express]: ezunpaywall enrich service listening on 3000'); + getConfig(); + await startConnectionRedis(); + pingRedis(); +}); diff --git a/src/enrich/config/custom-environment-variables.json b/services/enrich/config/custom-environment-variables.json similarity index 90% rename from src/enrich/config/custom-environment-variables.json rename to services/enrich/config/custom-environment-variables.json index 67be8c61..7b50e8a3 100644 --- a/src/enrich/config/custom-environment-variables.json +++ b/services/enrich/config/custom-environment-variables.json @@ -1,6 +1,7 @@ { "nodeEnv": "NODE_ENV", "accessLogRotate": "ACCESS_LOG_ROTATE", + "timezone": "TIMEZONE", "redis": { "host": "REDIS_HOST", "port": "REDIS_PORT", diff --git a/services/enrich/config/default.json b/services/enrich/config/default.json new file mode 100644 index 00000000..6621203c --- /dev/null +++ b/services/enrich/config/default.json @@ -0,0 +1,27 @@ +{ + "nodeEnv": "development", + "accessLogRotate": false, + "healthcheckLogRotate": false, + "timezone": "Europe/Paris", + "redis": { + "host": "redis", + "port": 6379, + "password": "changeme" + }, + "graphql": { + "host": "http://graphql:3000" + }, + "paths": { + "log": { + "applicationDir": "./log/application", + "accessDir": "./log/access", + "healthCheckDir": "./log/healthcheck" + }, + "data": { + "enrichedDir": "./data/enriched", + "statesDir": "./data/states", + "uploadDir": "./data/upload" + } + }, + "healthTimeout": 3000 +} \ No newline at end of file diff --git a/services/enrich/doc/activity-diagram-enrich.png b/services/enrich/doc/activity-diagram-enrich.png new file mode 100644 index 00000000..d813d4ac Binary files /dev/null and b/services/enrich/doc/activity-diagram-enrich.png differ diff --git a/services/enrich/openapi.yml b/services/enrich/openapi.yml new file mode 100644 index 00000000..ceb2215d --- /dev/null +++ b/services/enrich/openapi.yml @@ -0,0 +1,409 @@ +openapi: 3.0.0 +info: + description: The enrichment service allows to enrich a csv or jsonl file which contains a "doi" field with the metadata of the ezunpaywall mirror + version: 1.0.0 + title: Enrich service + contact: + email: ezteam@couperin.org + name: ezTeam + license: + name: CeCILL 2.1 + url: http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html +servers: + - url: https://unpaywall.inist.fr/api +tags: + - name: job + - name: ping +paths: + /enrich: + get: + tags: + - ping + summary: Name of service + operationId: get-enrich + description: Get name of enrich service + parameters: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: string + x-examples: + Example 1: enrich service + examples: + response: + value: enrich service + + /enrich/ping: + get: + tags: + - ping + summary: Ping enrich service + operationId: get-enrich-ping + description: Ping enrich service + responses: + '204': + description: No Content + + /enrich/health: + get: + summary: Health + operationId: get-enrich-health + description: Health on all service connected to enrich service + parameters: [] + tags: + - ping + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + redis: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + graphql: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elapsedTime: + type: integer + status: + type: boolean + x-examples: + Example 1: + redis: + elapsedTime: 1 + status: true + graphql: + elapsedTime: 2 + status: true + elapsedTime: 2 + status: true + examples: + Success: + value: + redis: + elapsedTime: 4 + status: true + graphql: + elapsedTime: 3 + status: true + elapsedTime: 6 + status: true + Error redis: + value: + redis: + elapsedTime: 3003 + status: false + error: time out + graphql: + elapsedTime: 1 + status: true + elapsedTime: 3003 + status: false + /enrich/health/redis: + get: + tags: + - ping + operationId: get-enrich-health-redis + description: Health on redis + summary: Health on redis service + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + /enrich/health/elastic: + get: + tags: + - ping + summary: Health on graphql service + operationId: get-enrich-health-elastic + description: Health on elastic + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + /enrich/upload: + post: + tags: + - job + summary: Upload a file + operationId: post-enrich-upload + description: Upload a file to be enriched + security: + - x-api-key: [] + parameters: [] + responses: + '200': + description: filename of uploaded file + content: + application/json: + schema: + type: string + default: id + '401': + $ref: '#/components/responses/Not-authorized' + + /enrich/job/{filename}: + post: + tags: + - job + summary: Enrich job + operationId: post-enrich-job-$-filename + description: Start a enrich job with uploaded file + security: + - x-api-key: [] + parameters: + - in: path + name: filename + description: filename + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + type: object + properties: + keys: + type: array + items: + type: object + properties: + id: + type: string + type: + type: string + args: + type: string + index: + type: string + separator: + type: string + description: apikeys + required: true + responses: + '200': + description: filename of process + content: + application/json: + schema: + type: string + default: id + '401': + $ref: '#/components/responses/Not-authorized' + + /enrich/enriched: + get: + tags: + - job + summary: Get enriched files + operationId: get-enrich-enriched + description: Get the list of enriched files + security: + - x-api-key: [] + responses: + '200': + description: list of enriched file + content: + application/json: + schema: + type: array + items: + type: string + default: file.csv + '401': + $ref: '#/components/responses/Not-authorized' + + /enrich/enriched/${filename}: + get: + tags: + - job + summary: Get enriched file + operationId: get-enrich-enriched-$-filename + description: Get the enriched file, generated at the end of the enrichment process + security: + - x-api-key: [] + parameters: + - in: path + name: filename + description: filename + required: true + schema: + type: string + responses: + '200': + description: enriched file + content: + application/json: + schema: + type: string + format: binary + '401': + $ref: '#/components/responses/Not-authorized' + + /enrich/states: + get: + tags: + - job + summary: Get list of states of enrich job + operationId: get-enrich-states + description: Get list of filenames state of enrich process + parameters: + - in: query + name: latest + description: latest + required: false + schema: + type: boolean + responses: + '200': + description: list of states file + content: + application/json: + schema: + type: array + items: + type: string + default: file.json + '401': + $ref: '#/components/responses/Not-authorized' + + /enrich/states/${filename}: + get: + tags: + - job + summary: Get State + operationId: get-enrich-states-$-filename + description: Get state of enrich process with his filename + parameters: + - in: path + name: filename + description: filename + required: true + schema: + type: string + responses: + '200': + description: list of uploaded file + content: + application/json: + schema: + type: object + properties: + done: + type: boolean + default: true + loaded: + type: integer + default: 150 + linesRead: + type: integer + default: 3 + enrichedLines: + type: integer + default: 3 + createdAt: + type: string + default: '2021-11-30T10:00:00.000Z' + endAt: + type: string + default: '2021-11-30T10:01:00.000Z' + error: + type: boolean + default: false + '401': + $ref: '#/components/responses/Not-authorized' + '404': + description: File not found + content: + File not found: + examples: + response: + value: + message: File not found + + /enrich/uploaded: + get: + tags: + - job + summary: Get uploaded files + operationId: get-enriched-uploaded + description: Get the lists of uploaded files + security: + - x-api-key: [] + parameters: [] + responses: + '200': + description: list of uploaded file + content: + application/json: + schema: + type: array + items: + type: string + default: file.csv + '401': + $ref: '#/components/responses/Not-authorized' + +components: + responses: + Not-authorized: + description: Not authorized + headers: {} + content: + application/json: + examples: + response: + value: + message: Not authorized + Health: + description: Example response + content: + Success: + schema: + type: object + properties: + name: + type: string + status: + type: boolean + elapsedTime: + type: integer + x-examples: + Example 1: + name: redis + status: true + elapsedTime: 1 + examples: + Success: + value: + name: name of service + status: true + elapsedTime: 1 + Error redis: + value: + name: redis + elapsedTime: 3002 + error: time out + status: false + securitySchemes: + x-api-key: + name: API Key + type: apiKey + in: header diff --git a/src/enrich/package-lock.json b/services/enrich/package-lock.json similarity index 99% rename from src/enrich/package-lock.json rename to services/enrich/package-lock.json index 42deef19..a649a63b 100644 --- a/src/enrich/package-lock.json +++ b/services/enrich/package-lock.json @@ -1,12 +1,12 @@ { "name": "ezunpaywall-enrich", - "version": "1.3.0", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ezunpaywall-enrich", - "version": "1.3.0", + "version": "1.3.5", "license": "CeCILL", "dependencies": { "@elastic/elasticsearch": "^7.13.0", @@ -5020,8 +5020,7 @@ "@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "requires": {} + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==" }, "@redis/client": { "version": "1.5.9", @@ -5036,26 +5035,22 @@ "@redis/graph": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "requires": {} + "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==" }, "@redis/json": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", - "requires": {} + "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==" }, "@redis/search": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "requires": {} + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==" }, "@redis/time-series": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==" }, "@sideway/address": { "version": "4.1.3", @@ -5144,8 +5139,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", diff --git a/src/enrich/package.json b/services/enrich/package.json similarity index 100% rename from src/enrich/package.json rename to services/enrich/package.json diff --git a/src/enrich/lib/config.js b/services/enrich/src/config.js similarity index 92% rename from src/enrich/lib/config.js rename to services/enrich/src/config.js index 479805d1..3de19bcd 100644 --- a/src/enrich/lib/config.js +++ b/services/enrich/src/config.js @@ -1,6 +1,6 @@ const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const defaultConfig = require('../config/default.json'); const copyConfig = JSON.parse(JSON.stringify(config)); diff --git a/src/enrich/lib/controllers/file.js b/services/enrich/src/controllers/file.js similarity index 93% rename from src/enrich/lib/controllers/file.js rename to services/enrich/src/controllers/file.js index c5e14d22..fa575d0d 100644 --- a/src/enrich/lib/controllers/file.js +++ b/services/enrich/src/controllers/file.js @@ -1,9 +1,9 @@ +const config = require('config'); const fs = require('fs-extra'); const path = require('path'); const joi = require('joi'); -const uploadDir = path.resolve(__dirname, '..', '..', 'data', 'upload'); -const enrichedDir = path.resolve(__dirname, '..', '..', 'data', 'enriched'); +const { uploadDir, enrichedDir } = config.paths.data; /** * Controller to get list of enriched files of user. @@ -80,7 +80,7 @@ async function getEnrichedFileByFilename(req, res, next) { */ async function uploadFile(req, res, next) { if (!req?.file) return next({ message: 'File not sent' }); - const { filename } = req?.file; + const { filename } = req.file; return res.status(200).json(path.parse(filename).name); } diff --git a/src/enrich/lib/controllers/health.js b/services/enrich/src/controllers/health.js similarity index 100% rename from src/enrich/lib/controllers/health.js rename to services/enrich/src/controllers/health.js diff --git a/src/enrich/lib/controllers/job.js b/services/enrich/src/controllers/job.js similarity index 78% rename from src/enrich/lib/controllers/job.js rename to services/enrich/src/controllers/job.js index 917903e2..5a7a58f4 100644 --- a/src/enrich/lib/controllers/job.js +++ b/services/enrich/src/controllers/job.js @@ -1,12 +1,8 @@ const fs = require('fs-extra'); const path = require('path'); +const { paths } = require('config'); -const { - enrichJSON, - enrichCSV, -} = require('../job'); - -const uploadDir = path.resolve(__dirname, '..', '..', 'data', 'upload'); +const { enrichJSON, enrichCSV } = require('../job'); /** * Controller to do enrich job. @@ -24,7 +20,7 @@ async function job(req, res, next) { type, args, index, separator, prefix, } = config; - if (!await fs.pathExists(path.resolve(uploadDir, apikey, `${id}.${type}`))) { + if (!await fs.pathExists(path.resolve(paths.data.uploadDir, apikey, `${id}.${type}`))) { return res.status(404).json({ message: `[file] ${id}.${type} not found` }); } diff --git a/src/enrich/lib/controllers/state.js b/services/enrich/src/controllers/state.js similarity index 86% rename from src/enrich/lib/controllers/state.js rename to services/enrich/src/controllers/state.js index 1c64b41e..b3934af3 100644 --- a/src/enrich/lib/controllers/state.js +++ b/services/enrich/src/controllers/state.js @@ -1,3 +1,4 @@ +const { paths } = require('config'); const path = require('path'); const fs = require('fs-extra'); @@ -5,8 +6,6 @@ const { getMostRecentFile } = require('../file'); const { getState } = require('../models/state'); -const statesDir = path.resolve(__dirname, '..', '..', 'data', 'states'); - /** * Controller to get list of states of enrich job of user. * @@ -22,7 +21,7 @@ async function getStates(req, res, next) { if (latest) { let latestFile; try { - latestFile = await getMostRecentFile(path.resolve(statesDir, apikey)); + latestFile = await getMostRecentFile(path.resolve(paths.data.statesDir, apikey)); } catch (err) { return next({ message: err.message }); } @@ -37,7 +36,7 @@ async function getStates(req, res, next) { let states; try { - states = await fs.readdir(path.resolve(statesDir, apikey)); + states = await fs.readdir(path.resolve(paths.data.statesDir, apikey)); } catch (err) { return next({ message: err.message }); } @@ -59,7 +58,7 @@ async function getStateByFilename(req, res, next) { let fileExist = false; try { - fileExist = await fs.exists(path.resolve(statesDir, apikey, filename)); + fileExist = await fs.exists(path.resolve(paths.data.statesDir, apikey, filename)); } catch (err) { return next({ message: err.message }); } diff --git a/services/enrich/src/cron.js b/services/enrich/src/cron.js new file mode 100644 index 00000000..7bf09c3b --- /dev/null +++ b/services/enrich/src/cron.js @@ -0,0 +1,29 @@ +const { paths } = require('config'); + +const Cron = require('./models/cron'); +const logger = require('./logger/appLogger'); + +const { deleteFilesInDir } = require('./file'); + +/** + * Removes files generated by an enrichment that are older than one day. + * + * @returns {Promise} + */ +async function task() { + const deletedEnrichedFiles = await deleteFilesInDir(paths.data.enrichedDir, 1); + logger.info(`[cron][files]: ${deletedEnrichedFiles?.join(',')} (${deletedEnrichedFiles.length}) enriched files are deleted`); + + const deletedStatesFiles = await deleteFilesInDir(paths.data.statesDir, 1); + logger.info(`[cron][files]: ${deletedStatesFiles?.join(',')} (${deletedStatesFiles.length}) enriched files are deleted`); + + const deletedUploadedFiles = await deleteFilesInDir(paths.data.uploadDir, 1); + logger.info(`[cron][files]: ${deletedUploadedFiles?.join(',')} (${deletedUploadedFiles.length}) enriched files are deleted`); +} + +/** + * Cron that runs every day to delete files generated by an enrichment that are older than one day. + */ +const cron = new Cron('delete out files', '0 0 0 * * *', task, true); + +module.exports = cron; diff --git a/src/enrich/lib/csv.js b/services/enrich/src/csv.js similarity index 91% rename from src/enrich/lib/csv.js rename to services/enrich/src/csv.js index 7255adc8..2941e9c9 100644 --- a/src/enrich/lib/csv.js +++ b/services/enrich/src/csv.js @@ -6,17 +6,13 @@ const Papa = require('papaparse'); const path = require('path'); const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); -const { - updateStateInFile, - fail, -} = require('./models/state'); +const { updateStateInFile, fail } = require('./models/state'); const { requestGraphql } = require('./services/graphql'); -const uploadDir = path.resolve(__dirname, '..', 'data', 'upload'); -const enrichedDir = path.resolve(__dirname, '..', 'data', 'enriched'); +const { uploadDir, enrichedDir } = config.paths.data; /** * get graphql params to get all unpaywall attributes. @@ -144,7 +140,7 @@ async function writeInFileCSV(data, headers, separator, enrichedFile, state) { }); await fs.writeFile(enrichedFile, `${unparse}\r\n`, { flag: 'a' }); } catch (err) { - logger.error(`[job csv] Cannot write [${unparse}] in [${enrichedFile}]`, err); + logger.error(`[job][csv]: Cannot write [${unparse}] in [${enrichedFile}]`, err); await fail(state); } } @@ -210,7 +206,7 @@ async function writeHeaderCSV(headers, separator, filePath) { try { await fs.writeFile(filePath, `${headers.join(separator)}\r\n`, { flag: 'a' }); } catch (err) { - logger.error(`[job csv] Cannot write [${headers.join(separator)}] in [${filePath}]`, err); + logger.error(`[job][csv]: Cannot write [${headers.join(separator)}] in [${filePath}]`, err); } } @@ -238,7 +234,7 @@ async function enrichInFile(data, enrichConfig, state) { try { response = await requestGraphql(data, args, index, state.apikey); } catch (err) { - logger.error(`[graphql] Cannot request graphql service at ${config.get('graphql.host')}/graphql`, JSON.stringify(err?.response?.data?.errors)); + logger.error(`[graphql] Cannot request graphql service at ${config.graphql.host}/graphql`, JSON.stringify(err?.response?.data?.errors)); throw err; } @@ -257,8 +253,8 @@ async function enrichInFile(data, enrichConfig, state) { /** * Starts the enrichment process for CSV file. * step : - * - read file by paquet of 1000 - * - enrich the paquet + * - read file by packet of 1000 + * - enrich the packet * - write the enriched data in enriched file * * A state is updated during the job. @@ -288,7 +284,7 @@ async function processEnrichCSV(id, index, args, state, prefix, separator) { try { await fs.ensureFile(enrichedFile); } catch (err) { - logger.error(`[job csv] Cannot ensure ${enrichedFile}`, err); + logger.error(`[job][csv]: Cannot ensure ${enrichedFile}`, err); throw err; } @@ -338,7 +334,7 @@ async function processEnrichCSV(id, index, args, state, prefix, separator) { try { await enrichInFile(copyData, enrichConfig, state); } catch (err) { - logger.error(`[job csv] Cannot enrich in file [${enrichedFile}]`, err); + logger.error(`[job][csv]: Cannot enrich in file [${enrichedFile}]`, err); await fail(state); return; } @@ -358,12 +354,12 @@ async function processEnrichCSV(id, index, args, state, prefix, separator) { try { await enrichInFile(data, enrichConfig, state); } catch (err) { - logger.error(`[job csv] Cannot enrich in file [${enrichedFile}]`, err); + logger.error(`[job][csv]: Cannot enrich in file [${enrichedFile}]`, err); await fail(state); return; } } - logger.info(`[job csv] ${state.enrichedLines}/${state.linesRead} enriched lines`); + logger.info(`[job][csv]: ${state.enrichedLines}/${state.linesRead} enriched lines`); } module.exports = processEnrichCSV; diff --git a/src/enrich/lib/file.js b/services/enrich/src/file.js similarity index 100% rename from src/enrich/lib/file.js rename to services/enrich/src/file.js diff --git a/src/enrich/lib/job.js b/services/enrich/src/job.js similarity index 95% rename from src/enrich/lib/job.js rename to services/enrich/src/job.js index 1f5188b7..1b33ddd3 100644 --- a/src/enrich/lib/job.js +++ b/services/enrich/src/job.js @@ -1,10 +1,6 @@ -const { - createState, - endState, -} = require('./models/state'); +const { createState, endState } = require('./models/state'); const processEnrichJSON = require('./json'); - const processEnrichCSV = require('./csv'); /** diff --git a/src/enrich/lib/json.js b/services/enrich/src/json.js similarity index 88% rename from src/enrich/lib/json.js rename to services/enrich/src/json.js index 0bb6e9cf..d3a44eb6 100644 --- a/src/enrich/lib/json.js +++ b/services/enrich/src/json.js @@ -7,7 +7,7 @@ const readline = require('readline'); const path = require('path'); const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const { updateStateInFile, @@ -16,8 +16,7 @@ const { const { requestGraphql } = require('./services/graphql'); -const uploadDir = path.resolve(__dirname, '..', 'data', 'upload'); -const enrichedDir = path.resolve(__dirname, '..', 'data', 'enriched'); +const { uploadDir, enrichedDir } = config.paths.data; /** * Get graphql params to get all unpaywall attributes. @@ -112,7 +111,7 @@ async function writeInFileJSON(data, enrichedFile, state) { try { await fs.writeFile(enrichedFile, stringTab, { flag: 'a' }); } catch (err) { - logger.error(`[job jsonl] Cannot write [${stringTab}] in [${enrichedFile}]`, err); + logger.error(`[job][jsonl]: Cannot write [${stringTab}] in [${enrichedFile}]`, err); await fail(state); throw err; } @@ -139,7 +138,7 @@ async function enrichInFile(data, enrichConfig, state) { try { response = await requestGraphql(data, args, index, state.apikey); } catch (err) { - logger.error(`[graphql] Cannot request graphql service at ${config.get('graphql.host')}/graphql`, JSON.stringify(err?.response?.data?.errors)); + logger.error(`[graphql] Cannot request graphql service at ${config.graphql.host}/graphql`, JSON.stringify(err?.response?.data?.errors)); throw err; } // enrichment @@ -185,7 +184,7 @@ async function processEnrichJSON(id, index, args, prefix, state) { try { await fs.ensureFile(enrichedFile); } catch (err) { - logger.error(`[job jsonl] Cannot ensure [${enrichedFile}]`, err); + logger.error(`[job][jsonl]: Cannot ensure [${enrichedFile}]`, err); } let loaded = 0; @@ -214,7 +213,7 @@ async function processEnrichJSON(id, index, args, prefix, state) { parsedLine = JSON.parse(line); data.push(parsedLine); } catch (err) { - logger.error(`[job jsonl] Cannot parse [${line}] in json format`, err); + logger.error(`[job][jsonl]: Cannot parse [${line}] in json format`, err); await fail(state); return; } @@ -223,7 +222,7 @@ async function processEnrichJSON(id, index, args, prefix, state) { try { await enrichInFile(data, enrichConfig, state); } catch (err) { - logger.error(`[job jsonl] Cannot enrich in file [${enrichedFile}]`, err); + logger.error(`[job][jsonl]: Cannot enrich in file [${enrichedFile}]`, err); await fail(state); return; } @@ -236,12 +235,12 @@ async function processEnrichJSON(id, index, args, prefix, state) { try { await enrichInFile(data, enrichConfig, state); } catch (err) { - logger.error(`[job jsonl] Cannot enrich in file [${enrichedFile}]`, err); + logger.error(`[job][jsonl]: Cannot enrich in file [${enrichedFile}]`, err); await fail(state); return; } } - logger.info(`[job jsonl] ${state.enrichedLines}/${state.linesRead} enriched lines`); + logger.info(`[job][jsonl]: ${state.enrichedLines}/${state.linesRead} enriched lines`); } module.exports = processEnrichJSON; diff --git a/src/enrich/lib/morgan.js b/services/enrich/src/logger/access.js similarity index 70% rename from src/enrich/lib/morgan.js rename to services/enrich/src/logger/access.js index 9e16d039..ff0a114a 100644 --- a/src/enrich/lib/morgan.js +++ b/services/enrich/src/logger/access.js @@ -3,14 +3,14 @@ const fs = require('fs-extra'); const rfs = require('rotating-file-stream'); const path = require('path'); const { format } = require('date-fns'); -const { accessLogRotate } = require('config'); +const { nodeEnv, accessLogRotate, paths } = require('config'); -const accessLogDir = path.resolve(__dirname, '..', 'log', 'access'); +const isProd = (nodeEnv === 'production'); /** * Get the name of access file. * - * @param {number} date - Date in minisecond + * @param {number} date - Date in milliseconds * * @returns {string} Name of access file. */ @@ -24,10 +24,10 @@ let accessLogStream; if (accessLogRotate) { accessLogStream = rfs.createStream(logFilename, { interval: '1d', // rotate daily - path: accessLogDir, + path: paths.log.accessDir, }); } else { - accessLogStream = fs.createWriteStream(path.resolve(accessLogDir, 'access.log'), { flags: 'a+' }); + accessLogStream = fs.createWriteStream(path.resolve(paths.log.accessDir, 'access.log'), { flags: 'a+' }); } morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); @@ -37,4 +37,4 @@ morgan.token('user', (req) => { return '-'; }); -module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: accessLogStream }); +module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: isProd ? accessLogStream : process.stdout }); diff --git a/src/graphql/lib/logger.js b/services/enrich/src/logger/appLogger.js similarity index 91% rename from src/graphql/lib/logger.js rename to services/enrich/src/logger/appLogger.js index d2d91902..e83d3544 100644 --- a/src/graphql/lib/logger.js +++ b/services/enrich/src/logger/appLogger.js @@ -1,5 +1,5 @@ const path = require('path'); -const { nodeEnv } = require('config'); +const { nodeEnv, paths } = require('config'); const isProd = (nodeEnv === 'production'); @@ -22,7 +22,7 @@ const { const processConfiguration = [ new transports.DailyRotateFile({ name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), + filename: path.resolve(paths.log.applicationDir, '%DATE%.log'), datePattern: 'yyyy-MM-DD', level: 'info', }), diff --git a/services/enrich/src/logger/healthcheck.js b/services/enrich/src/logger/healthcheck.js new file mode 100644 index 00000000..f56e9d9f --- /dev/null +++ b/services/enrich/src/logger/healthcheck.js @@ -0,0 +1,41 @@ +const morgan = require('morgan'); +const fs = require('fs-extra'); +const rfs = require('rotating-file-stream'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths, healthcheckLogRotate } = require('config'); + +/** + * Get the name of healthcheck log file. + * + * @param {number} date - Date in milliseconds + * + * @returns {string} Name of healthcheck log file. + */ +function logFilename(date) { + if (!date) return 'healthcheck.log'; + return `${format(new Date(date) - 1000 * 60 * 60 * 24, 'yyyy-MM-dd')}-healthcheck.log`; +} + +let healthCheckLogStream; + +if (healthcheckLogRotate) { + healthCheckLogStream = rfs.createStream(logFilename, { + interval: '1d', // rotate daily + path: paths.log.healthCheckDir, + }); +} else { + healthCheckLogStream = fs.createWriteStream(path.resolve(paths.log.healthCheckDir, 'healthcheck.log'), { flags: 'a+' }); +} + +morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); + +morgan.token('user', (req) => { + if (req.user) return req.user; + return '-'; +}); + +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: healthCheckLogStream }, +); diff --git a/src/enrich/lib/middlewares/args.js b/services/enrich/src/middlewares/args.js similarity index 91% rename from src/enrich/lib/middlewares/args.js rename to services/enrich/src/middlewares/args.js index 72978869..0a2b8951 100644 --- a/src/enrich/lib/middlewares/args.js +++ b/services/enrich/src/middlewares/args.js @@ -1,6 +1,6 @@ const { redisClient } = require('../services/redis'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Authentication middleware that checks if if the arguments passed @@ -28,14 +28,14 @@ async function checkArgs(req, res, next) { try { apikeyConfig = await redisClient.get(apikey); } catch (err) { - logger.error(`[redis] Cannot get [${apikey}] on redis`, err); + logger.error(`[redis]: Cannot get [${apikey}] on redis`, err); return next({ message: err.message }); } try { apikeyConfig = JSON.parse(apikeyConfig); } catch (err) { - logger.error(`[redis] Cannot parse [${apikeyConfig}]`, err); + logger.error(`[redis]: Cannot parse [${apikeyConfig}]`, err); return next({ message: err.message }); } diff --git a/src/enrich/lib/middlewares/auth.js b/services/enrich/src/middlewares/auth.js similarity index 87% rename from src/enrich/lib/middlewares/auth.js rename to services/enrich/src/middlewares/auth.js index e822d047..35f1bddb 100644 --- a/src/enrich/lib/middlewares/auth.js +++ b/services/enrich/src/middlewares/auth.js @@ -1,6 +1,6 @@ const { redisClient } = require('../services/redis'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Authentication middleware that checks if the content of the x-api-key header @@ -28,14 +28,14 @@ async function checkAuth(req, res, next) { try { apikeyConfig = await redisClient.get(apikey); } catch (err) { - logger.error(`[redis] Cannot get [${apikey}] on redis`, err); + logger.error(`[redis]: Cannot get [${apikey}] on redis`, err); return next({ message: err.message }); } try { apikeyConfig = JSON.parse(apikeyConfig); } catch (err) { - logger.error(`[redis] Cannot parse [${apikeyConfig}]`, err); + logger.error(`[redis]: Cannot parse [${apikeyConfig}]`, err); return next({ message: err.message }); } diff --git a/src/enrich/lib/middlewares/filename.js b/services/enrich/src/middlewares/filename.js similarity index 100% rename from src/enrich/lib/middlewares/filename.js rename to services/enrich/src/middlewares/filename.js diff --git a/src/enrich/lib/middlewares/job.js b/services/enrich/src/middlewares/job.js similarity index 100% rename from src/enrich/lib/middlewares/job.js rename to services/enrich/src/middlewares/job.js diff --git a/src/enrich/lib/middlewares/latest.js b/services/enrich/src/middlewares/latest.js similarity index 100% rename from src/enrich/lib/middlewares/latest.js rename to services/enrich/src/middlewares/latest.js diff --git a/src/enrich/lib/middlewares/multer.js b/services/enrich/src/middlewares/multer.js similarity index 85% rename from src/enrich/lib/middlewares/multer.js rename to services/enrich/src/middlewares/multer.js index c03c0835..f44c2dfc 100644 --- a/src/enrich/lib/middlewares/multer.js +++ b/services/enrich/src/middlewares/multer.js @@ -2,8 +2,7 @@ const multer = require('multer'); const uuid = require('uuid'); const path = require('path'); const fs = require('fs-extra'); - -const uploadDir = path.resolve(__dirname, '..', '..', 'data', 'upload'); +const { paths } = require('config'); /** * Download middleware for the enrichment process. @@ -13,7 +12,7 @@ const storage = multer.diskStorage( { destination: (req, file, cb) => { const apikey = req.get('x-api-key'); - const dir = path.resolve(uploadDir, apikey); + const dir = path.resolve(paths.data.uploadDir, apikey); fs.exists(dir, (exist) => { if (!exist) { return fs.mkdir(dir, (error) => cb(error, dir)); diff --git a/src/enrich/lib/middlewares/state.js b/services/enrich/src/middlewares/state.js similarity index 68% rename from src/enrich/lib/middlewares/state.js rename to services/enrich/src/middlewares/state.js index 65b747c1..55735654 100644 --- a/src/enrich/lib/middlewares/state.js +++ b/services/enrich/src/middlewares/state.js @@ -1,21 +1,20 @@ const path = require('path'); const fs = require('fs-extra'); - -const statesDir = path.resolve(__dirname, '..', '..', 'data', 'states'); +const { paths } = require('config'); async function upsertDirectoryOfUser(req, res, next) { const apikey = req.get('x-api-key'); let dirExist = false; try { - dirExist = await fs.exists(path.resolve(statesDir, apikey)); + dirExist = await fs.exists(path.resolve(paths.data.statesDir, apikey)); } catch (err) { return next({ message: err.message }); } if (!dirExist) { try { - await fs.mkdir(path.resolve(statesDir, apikey)); + await fs.mkdir(path.resolve(paths.data.statesDir, apikey)); } catch (err) { return next({ message: err.message }); } diff --git a/src/enrich/lib/models/cron.js b/services/enrich/src/models/cron.js similarity index 74% rename from src/enrich/lib/models/cron.js rename to services/enrich/src/models/cron.js index 71cf5204..3014b86a 100644 --- a/src/enrich/lib/models/cron.js +++ b/services/enrich/src/models/cron.js @@ -1,6 +1,7 @@ const { CronJob } = require('cron'); +const { timezone } = require('config'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Class cron which overloads the node-cron library by adding features. @@ -19,7 +20,7 @@ class Cron { this.schedule = schedule; this.task = task; this.active = active; - this.process = new CronJob(schedule, this.task, null, false, 'Europe/Paris'); + this.process = new CronJob(schedule, this.task, null, false, timezone); if (active) { this.start(); } @@ -46,8 +47,8 @@ class Cron { setTask(task) { this.process.stop(); this.task = task; - logger.info(`[cron ${this.name}] config: task updated`); - this.process = new CronJob(this.schedule, this.task, null, false, 'Europe/Paris'); + logger.info(`[cron][${this.name}]: config: task updated`); + this.process = new CronJob(this.schedule, this.task, null, false, timezone); if (this.active) this.process.start(); } @@ -59,10 +60,10 @@ class Cron { setSchedule(schedule) { this.process.stop(); this.schedule = schedule; - logger.info(`[cron: ${this.name}] config - schedule is updated [${this.schedule}]`); + logger.info(`[cron][${this.name}]: config - schedule is updated [${this.schedule}]`); this.process = new CronJob(this.schedule, async () => { await this.task(); - }, null, false, 'Europe/Paris'); + }, null, false, timezone); if (this.active) this.process.start(); } @@ -72,10 +73,10 @@ class Cron { start() { try { this.process.start(); - logger.info(`[cron ${this.name}] started`); - logger.info(`[cron ${this.name}] config: schedule: [${this.schedule}]`); + logger.info(`[cron][${this.name}]: started`); + logger.info(`[cron][${this.name}]: config: schedule: [${this.schedule}]`); } catch (err) { - logger.error(`[cron ${this.name}] error in start`, err); + logger.error(`[cron][${this.name}]: error in start`, err); return; } this.active = true; @@ -87,9 +88,9 @@ class Cron { stop() { try { this.process.stop(); - logger.info(`[cron: ${this.name}] stopped`); + logger.info(`[cron][${this.name}]: stopped`); } catch (err) { - logger.error(`[cron ${this.name}] error in stop`, err); + logger.error(`[cron][${this.name}]: error in stop`, err); return; } this.active = false; diff --git a/src/enrich/lib/models/state.js b/services/enrich/src/models/state.js similarity index 84% rename from src/enrich/lib/models/state.js rename to services/enrich/src/models/state.js index c183e2f5..52b341d1 100644 --- a/src/enrich/lib/models/state.js +++ b/services/enrich/src/models/state.js @@ -1,10 +1,9 @@ /* eslint-disable no-param-reassign */ const path = require('path'); const fs = require('fs-extra'); +const { paths } = require('config'); -const logger = require('../logger'); - -const stateDir = path.resolve(__dirname, '..', '..', 'data', 'states'); +const logger = require('../logger/appLogger'); /** * Create a new State in file on folder data/state//.json @@ -17,9 +16,10 @@ const stateDir = path.resolve(__dirname, '..', '..', 'data', 'states'); */ async function createState(id, apikey) { const filename = `${id}.json`; - const filenamePath = path.resolve(stateDir, apikey, filename); + const filenamePath = path.resolve(paths.data.statesDir, apikey, filename); const state = { + id, path: filenamePath, filename, apikey, @@ -32,7 +32,7 @@ async function createState(id, apikey) { error: false, }; - const dir = path.resolve(stateDir, apikey); + const dir = path.resolve(paths.data.statesDir, apikey); const exist = await fs.exists(dir); @@ -58,7 +58,7 @@ async function createState(id, apikey) { * @returns {Promise} State of enrich process in JSON format. */ async function getState(filename, apikey) { - const filenamePath = path.resolve(stateDir, apikey, filename); + const filenamePath = path.resolve(paths.data.statesDir, apikey, filename); let state; @@ -82,8 +82,7 @@ async function getState(filename, apikey) { /** * Write the latest version of the state of enrich process to the file. * - * @param {Object} state - State in JSON format. - * @param {string} filename - State filename. + * @param {Object} state - State of job. * * @returns {Promise} */ @@ -99,12 +98,12 @@ async function updateStateInFile(state) { /** * Update the state of enrich process when there is an error. * - * @param {string} filename - State filename. - * @param {string} apikey - Apikey of user. + * @param {Object} state - State of job. * * @returns {Promise} */ async function fail(state) { + logger.info(`[state]: job fail with id [${state.id}]`); state.done = true; state.endAt = new Date(); state.error = true; diff --git a/src/enrich/lib/ping.js b/services/enrich/src/ping.js similarity index 100% rename from src/enrich/lib/ping.js rename to services/enrich/src/ping.js diff --git a/src/enrich/lib/routers/file.js b/services/enrich/src/routers/file.js similarity index 100% rename from src/enrich/lib/routers/file.js rename to services/enrich/src/routers/file.js diff --git a/services/enrich/src/routers/healthcheck.js b/services/enrich/src/routers/healthcheck.js new file mode 100644 index 00000000..5eb10fe8 --- /dev/null +++ b/services/enrich/src/routers/healthcheck.js @@ -0,0 +1,10 @@ +const router = require('express').Router(); + +const healthCheckLogger = require('../logger/healthcheck'); + +/** + * Route use for healthcheck. + */ +router.get('/healthcheck', healthCheckLogger, (req, res, next) => res.status(204).end()); + +module.exports = router; diff --git a/src/enrich/lib/routers/job.js b/services/enrich/src/routers/job.js similarity index 100% rename from src/enrich/lib/routers/job.js rename to services/enrich/src/routers/job.js diff --git a/services/enrich/src/routers/openapi.js b/services/enrich/src/routers/openapi.js new file mode 100644 index 00000000..bdf85c7d --- /dev/null +++ b/services/enrich/src/routers/openapi.js @@ -0,0 +1,9 @@ +const router = require('express').Router(); +const path = require('path'); + +/** + * Route that give the openapi.json file. + */ +router.get('/openapi.yml', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'openapi.yml'))); + +module.exports = router; diff --git a/src/enrich/lib/routers/ping.js b/services/enrich/src/routers/ping.js similarity index 100% rename from src/enrich/lib/routers/ping.js rename to services/enrich/src/routers/ping.js diff --git a/src/enrich/lib/routers/state.js b/services/enrich/src/routers/state.js similarity index 100% rename from src/enrich/lib/routers/state.js rename to services/enrich/src/routers/state.js diff --git a/src/enrich/lib/services/graphql.js b/services/enrich/src/services/graphql.js similarity index 69% rename from src/enrich/lib/services/graphql.js rename to services/enrich/src/services/graphql.js index 0277df31..251356b9 100644 --- a/src/enrich/lib/services/graphql.js +++ b/services/enrich/src/services/graphql.js @@ -1,12 +1,13 @@ const axios = require('axios'); const config = require('config'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); const graphql = axios.create({ - baseURL: config.get('graphql.host'), + baseURL: config.graphql.host, + timeout: 30000, }); -graphql.host = config.get('graphql.host'); +graphql.host = config.graphql.host; /** * Request graphql service to get unpaywall data. @@ -29,19 +30,25 @@ async function requestGraphql(data, args, index, apikey) { dois = await map1.filter((elem) => elem !== undefined); dois = dois.join('","'); - res = await graphql({ - method: 'POST', - url: '/graphql', - data: - { - query: `{ GetByDOI(dois: ["${dois}"]) ${args.toString()} }`, - }, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - 'x-api-key': apikey, - index, - }, - }); + try { + res = await graphql({ + method: 'POST', + url: '/graphql', + data: + { + query: `{ GetByDOI(dois: ["${dois}"]) ${args.toString()} }`, + }, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'x-api-key': apikey, + index, + }, + }); + } catch (err) { + logger.error('[graphql] Cannot get unpaywall data'); + throw err; + } + return res?.data?.data?.GetByDOI; } diff --git a/services/enrich/src/services/redis.js b/services/enrich/src/services/redis.js new file mode 100644 index 00000000..b0d7bf81 --- /dev/null +++ b/services/enrich/src/services/redis.js @@ -0,0 +1,50 @@ +const { createClient } = require('redis'); +const util = require('util'); +const { redis } = require('config'); +const logger = require('../logger/appLogger'); + +const redisClient = createClient({ + legacyMode: true, + socket: { + host: redis.host, + port: redis.port, + }, + password: redis.password, +}); + +// +redisClient.get = util.promisify(redisClient.get); +redisClient.ping = util.promisify(redisClient.ping); + +/** + * Ping redis service. + * + * @returns {Promise} Ping + */ +async function pingRedis() { + try { + await redisClient.ping(); + } catch (err) { + logger.error(`[redis]: Cannot ping ${redis.host}:${redis.port}`, err); + return false; + } + logger.info(`[redis]: ping success ${redis.host}:${redis.port}`); + return true; +} + +async function startConnectionRedis() { + try { + await redisClient.connect(); + } catch (err) { + logger.error(`[redis]: Cannot start connection ${redis.host}:${redis.port}`, err); + return false; + } + logger.info(`[redis]: connect success ${redis.host}:${redis.port}`); + return true; +} + +module.exports = { + redisClient, + startConnectionRedis, + pingRedis, +}; diff --git a/src/enrich/test/auth.js b/services/enrich/test/auth.js similarity index 98% rename from src/enrich/test/auth.js rename to services/enrich/test/auth.js index f47d782d..a43f7e46 100644 --- a/src/enrich/test/auth.js +++ b/services/enrich/test/auth.js @@ -200,7 +200,7 @@ describe('Test: auth service in enrich service', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -415,7 +415,7 @@ describe('Test: auth service in enrich service', () => { .request(enrichService) .get(`/states/${id}.json`) .set('x-api-key', 'user'); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; diff --git a/src/enrich/test/enrichCSV.js b/services/enrich/test/enrichCSV.js similarity index 100% rename from src/enrich/test/enrichCSV.js rename to services/enrich/test/enrichCSV.js diff --git a/src/enrich/test/enrichJSON.js b/services/enrich/test/enrichJSON.js similarity index 97% rename from src/enrich/test/enrichJSON.js rename to services/enrich/test/enrichJSON.js index 028cfe88..913ae694 100644 --- a/src/enrich/test/enrichJSON.js +++ b/services/enrich/test/enrichJSON.js @@ -84,7 +84,7 @@ describe('Test: enrich service jsonl', () => { .request(enrichService) .get(`/states/${id}.json`) .set('x-api-key', 'user'); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -160,7 +160,7 @@ describe('Test: enrich service jsonl', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -237,7 +237,7 @@ describe('Test: enrich service jsonl', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -313,7 +313,7 @@ describe('Test: enrich service jsonl', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -390,7 +390,7 @@ describe('Test: enrich service jsonl', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; @@ -466,7 +466,7 @@ describe('Test: enrich service jsonl', () => { .get(`/states/${id}.json`) .set('x-api-key', 'user'); expect(res3).have.status(200); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); } while (!res3?.body?.done); const state = res3?.body; diff --git a/src/enrich/test/mapping/unpaywall.json b/services/enrich/test/mapping/unpaywall.json similarity index 100% rename from src/enrich/test/mapping/unpaywall.json rename to services/enrich/test/mapping/unpaywall.json diff --git a/src/enrich/test/sources/enriched/csv/file01.csv b/services/enrich/test/sources/enriched/csv/file01.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file01.csv rename to services/enrich/test/sources/enriched/csv/file01.csv diff --git a/src/enrich/test/sources/enriched/csv/file02.csv b/services/enrich/test/sources/enriched/csv/file02.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file02.csv rename to services/enrich/test/sources/enriched/csv/file02.csv diff --git a/src/enrich/test/sources/enriched/csv/file03.csv b/services/enrich/test/sources/enriched/csv/file03.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file03.csv rename to services/enrich/test/sources/enriched/csv/file03.csv diff --git a/src/enrich/test/sources/enriched/csv/file04.csv b/services/enrich/test/sources/enriched/csv/file04.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file04.csv rename to services/enrich/test/sources/enriched/csv/file04.csv diff --git a/src/enrich/test/sources/enriched/csv/file05.csv b/services/enrich/test/sources/enriched/csv/file05.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file05.csv rename to services/enrich/test/sources/enriched/csv/file05.csv diff --git a/src/enrich/test/sources/enriched/csv/file06.csv b/services/enrich/test/sources/enriched/csv/file06.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file06.csv rename to services/enrich/test/sources/enriched/csv/file06.csv diff --git a/src/enrich/test/sources/enriched/csv/file07.csv b/services/enrich/test/sources/enriched/csv/file07.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file07.csv rename to services/enrich/test/sources/enriched/csv/file07.csv diff --git a/src/enrich/test/sources/enriched/csv/file08.csv b/services/enrich/test/sources/enriched/csv/file08.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file08.csv rename to services/enrich/test/sources/enriched/csv/file08.csv diff --git a/src/enrich/test/sources/enriched/csv/file09.csv b/services/enrich/test/sources/enriched/csv/file09.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file09.csv rename to services/enrich/test/sources/enriched/csv/file09.csv diff --git a/src/enrich/test/sources/enriched/csv/file10.csv b/services/enrich/test/sources/enriched/csv/file10.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file10.csv rename to services/enrich/test/sources/enriched/csv/file10.csv diff --git a/src/enrich/test/sources/enriched/csv/file11.csv b/services/enrich/test/sources/enriched/csv/file11.csv similarity index 100% rename from src/enrich/test/sources/enriched/csv/file11.csv rename to services/enrich/test/sources/enriched/csv/file11.csv diff --git a/src/enrich/test/sources/enriched/jsonl/file01.jsonl b/services/enrich/test/sources/enriched/jsonl/file01.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file01.jsonl rename to services/enrich/test/sources/enriched/jsonl/file01.jsonl diff --git a/src/enrich/test/sources/enriched/jsonl/file02.jsonl b/services/enrich/test/sources/enriched/jsonl/file02.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file02.jsonl rename to services/enrich/test/sources/enriched/jsonl/file02.jsonl diff --git a/src/enrich/test/sources/enriched/jsonl/file03.jsonl b/services/enrich/test/sources/enriched/jsonl/file03.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file03.jsonl rename to services/enrich/test/sources/enriched/jsonl/file03.jsonl diff --git a/src/enrich/test/sources/enriched/jsonl/file04.jsonl b/services/enrich/test/sources/enriched/jsonl/file04.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file04.jsonl rename to services/enrich/test/sources/enriched/jsonl/file04.jsonl diff --git a/src/enrich/test/sources/enriched/jsonl/file05.jsonl b/services/enrich/test/sources/enriched/jsonl/file05.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file05.jsonl rename to services/enrich/test/sources/enriched/jsonl/file05.jsonl diff --git a/src/enrich/test/sources/enriched/jsonl/file06.jsonl b/services/enrich/test/sources/enriched/jsonl/file06.jsonl similarity index 100% rename from src/enrich/test/sources/enriched/jsonl/file06.jsonl rename to services/enrich/test/sources/enriched/jsonl/file06.jsonl diff --git a/src/enrich/test/sources/mustBeEnrich/file01.csv b/services/enrich/test/sources/mustBeEnrich/file01.csv similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file01.csv rename to services/enrich/test/sources/mustBeEnrich/file01.csv diff --git a/src/enrich/test/sources/mustBeEnrich/file01.jsonl b/services/enrich/test/sources/mustBeEnrich/file01.jsonl similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file01.jsonl rename to services/enrich/test/sources/mustBeEnrich/file01.jsonl diff --git a/src/enrich/test/sources/mustBeEnrich/file02.csv b/services/enrich/test/sources/mustBeEnrich/file02.csv similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file02.csv rename to services/enrich/test/sources/mustBeEnrich/file02.csv diff --git a/src/enrich/test/sources/mustBeEnrich/file02.jsonl b/services/enrich/test/sources/mustBeEnrich/file02.jsonl similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file02.jsonl rename to services/enrich/test/sources/mustBeEnrich/file02.jsonl diff --git a/src/enrich/test/sources/mustBeEnrich/file03.csv b/services/enrich/test/sources/mustBeEnrich/file03.csv similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file03.csv rename to services/enrich/test/sources/mustBeEnrich/file03.csv diff --git a/src/enrich/test/sources/mustBeEnrich/file04.csv b/services/enrich/test/sources/mustBeEnrich/file04.csv similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file04.csv rename to services/enrich/test/sources/mustBeEnrich/file04.csv diff --git a/src/enrich/test/sources/mustBeEnrich/file05.csv b/services/enrich/test/sources/mustBeEnrich/file05.csv similarity index 100% rename from src/enrich/test/sources/mustBeEnrich/file05.csv rename to services/enrich/test/sources/mustBeEnrich/file05.csv diff --git a/src/enrich/test/sources/tmp/enriched.csv b/services/enrich/test/sources/tmp/enriched.csv similarity index 100% rename from src/enrich/test/sources/tmp/enriched.csv rename to services/enrich/test/sources/tmp/enriched.csv diff --git a/src/enrich/test/sources/tmp/enriched.jsonl b/services/enrich/test/sources/tmp/enriched.jsonl similarity index 100% rename from src/enrich/test/sources/tmp/enriched.jsonl rename to services/enrich/test/sources/tmp/enriched.jsonl diff --git a/src/enrich/test/sources/unpaywall/fake1.jsonl b/services/enrich/test/sources/unpaywall/fake1.jsonl similarity index 100% rename from src/enrich/test/sources/unpaywall/fake1.jsonl rename to services/enrich/test/sources/unpaywall/fake1.jsonl diff --git a/src/enrich/test/utils/apikey.js b/services/enrich/test/utils/apikey.js similarity index 100% rename from src/enrich/test/utils/apikey.js rename to services/enrich/test/utils/apikey.js diff --git a/src/enrich/test/utils/elastic.js b/services/enrich/test/utils/elastic.js similarity index 100% rename from src/enrich/test/utils/elastic.js rename to services/enrich/test/utils/elastic.js diff --git a/src/enrich/test/utils/file.js b/services/enrich/test/utils/file.js similarity index 100% rename from src/enrich/test/utils/file.js rename to services/enrich/test/utils/file.js diff --git a/src/enrich/test/utils/ping.js b/services/enrich/test/utils/ping.js similarity index 100% rename from src/enrich/test/utils/ping.js rename to services/enrich/test/utils/ping.js diff --git a/src/fakeUnpaywall/.eslintrc.json b/services/fakeUnpaywall/.eslintrc.json similarity index 100% rename from src/fakeUnpaywall/.eslintrc.json rename to services/fakeUnpaywall/.eslintrc.json diff --git a/src/fakeUnpaywall/.gitignore b/services/fakeUnpaywall/.gitignore similarity index 68% rename from src/fakeUnpaywall/.gitignore rename to services/fakeUnpaywall/.gitignore index 63ea107e..ffaded73 100644 --- a/src/fakeUnpaywall/.gitignore +++ b/services/fakeUnpaywall/.gitignore @@ -1,2 +1,4 @@ +node_modules/ +log/ changefiles-day.json changefiles-week.json \ No newline at end of file diff --git a/src/fakeUnpaywall/README.md b/services/fakeUnpaywall/README.md similarity index 100% rename from src/fakeUnpaywall/README.md rename to services/fakeUnpaywall/README.md diff --git a/src/fakeUnpaywall/app.js b/services/fakeUnpaywall/app.js similarity index 55% rename from src/fakeUnpaywall/app.js rename to services/fakeUnpaywall/app.js index 8878fb93..8a14493b 100644 --- a/src/fakeUnpaywall/app.js +++ b/services/fakeUnpaywall/app.js @@ -1,13 +1,13 @@ const express = require('express'); const cors = require('cors'); -const logger = require('./lib/logger'); +const logger = require('./src/logger'); -const updateChangefilesExample = require('./lib/controllers/changefiles'); +const updateChangefilesExample = require('./src/controllers/changefiles'); -const routerSnapshots = require('./lib/routers/snapshots'); -const routerChangeFiles = require('./lib/routers/changefiles'); -const routerPing = require('./lib/routers/ping'); +const routerSnapshots = require('./src/routers/snapshots'); +const routerChangeFiles = require('./src/routers/changefiles'); +const routerPing = require('./src/routers/ping'); // start server const app = express(); @@ -19,13 +19,13 @@ app.use(routerSnapshots); app.use(routerChangeFiles); app.use(routerPing); -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); +// Errors and unknown routes +app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}: this route does not exist.` })); app.use((error, req, res, next) => res.status(500).json({ message: error.message })); app.listen(3000, async () => { - logger.info('[express] fakeUnpaywall service listening on 3000'); + logger.info('[express]: fakeUnpaywall service listening on 3000'); await updateChangefilesExample('day'); await updateChangefilesExample('week'); }); diff --git a/src/fakeUnpaywall/package-lock.json b/services/fakeUnpaywall/package-lock.json similarity index 99% rename from src/fakeUnpaywall/package-lock.json rename to services/fakeUnpaywall/package-lock.json index 47a091df..3545fbed 100644 --- a/src/fakeUnpaywall/package-lock.json +++ b/services/fakeUnpaywall/package-lock.json @@ -1,12 +1,12 @@ { "name": "fakeunpaywall", - "version": "1.3.0", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "fakeunpaywall", - "version": "1.3.0", + "version": "1.3.5", "license": "CeCILL", "dependencies": { "cors": "^2.8.5", @@ -3781,8 +3781,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", diff --git a/src/fakeUnpaywall/package.json b/services/fakeUnpaywall/package.json similarity index 100% rename from src/fakeUnpaywall/package.json rename to services/fakeUnpaywall/package.json diff --git a/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl b/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl new file mode 100644 index 00000000..e336ea7b --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl @@ -0,0 +1,2 @@ +{"doi": "3","version": 2, "updated": "2019-01-01T01:00:00.000000" } +{"doi": "4","version": 3, "updated": "2019-01-01T01:00:00.000000" } diff --git a/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl.gz b/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl.gz new file mode 100644 index 00000000..0482295b Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2019-01-01-history.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl b/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl new file mode 100644 index 00000000..67c1c723 --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl @@ -0,0 +1,6 @@ +{"doi": "1","version": 1, "updated": "2019-01-01T01:00:00.000000" } +{"doi": "2","version": 1, "updated": "2019-01-01T01:00:00.000000" } +{"doi": "3","version": 1, "updated": "2019-01-01T01:00:00.000000" } +{"doi": "4","version": 1, "updated": "2019-01-01T01:00:00.000000" } +{"doi": "5","version": 1, "updated": "2019-01-01T01:00:00.000000" } + diff --git a/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl.gz b/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl.gz new file mode 100644 index 00000000..038d727d Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2019-01-01-snapshot.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2019-01-02-history.jsonl.gz b/services/fakeUnpaywall/snapshots/2019-01-02-history.jsonl.gz new file mode 100644 index 00000000..289d6452 Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2019-01-02-history.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl b/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl new file mode 100644 index 00000000..66df4f92 --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl @@ -0,0 +1,5 @@ +{"doi": "1","version": 1, "updated": "2020-01-01T01:00:00.000000" } +{"doi": "2","version": 1, "updated": "2020-01-01T01:00:00.000000" } +{"doi": "3","version": 1, "updated": "2020-01-01T01:00:00.000000" } +{"doi": "4","version": 1, "updated": "2020-01-01T01:00:00.000000" } +{"doi": "5","version": 1, "updated": "2020-01-01T01:00:00.000000" } diff --git a/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl.gz b/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl.gz new file mode 100644 index 00000000..f0792233 Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2020-01-01-snapshot.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl b/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl new file mode 100644 index 00000000..3f847407 --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl @@ -0,0 +1,3 @@ +{"doi": "1","version": 2, "updated": "2020-01-02T01:00:00.000000" } +{"doi": "2","version": 2, "updated": "2020-01-02T01:00:00.000000" } +{"doi": "3","version": 2, "updated": "2020-01-02T01:00:00.000000" } diff --git a/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl.gz b/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl.gz new file mode 100644 index 00000000..18c4c13f Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2020-01-02-history.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl b/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl new file mode 100644 index 00000000..1a58f730 --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl @@ -0,0 +1,2 @@ +{"doi": "1","version": 3, "updated": "2020-01-03T01:00:00.000000" } +{"doi": "2","version": 3, "updated": "2020-01-03T01:00:00.000000" } diff --git a/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl.gz b/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl.gz new file mode 100644 index 00000000..b3cd3050 Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2020-01-03-history.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl b/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl new file mode 100644 index 00000000..9b128c52 --- /dev/null +++ b/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl @@ -0,0 +1,2 @@ +{"doi": "6","version": 1, "updated": "2020-01-05T01:00:00.000000" } +{"doi": "7","version": 1, "updated": "2020-01-05T01:00:00.000000" } diff --git a/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl.gz b/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl.gz new file mode 100644 index 00000000..a0c974d5 Binary files /dev/null and b/services/fakeUnpaywall/snapshots/2020-01-05-history.jsonl.gz differ diff --git a/services/fakeUnpaywall/snapshots/changefiles-day-example.json b/services/fakeUnpaywall/snapshots/changefiles-day-example.json new file mode 100644 index 00000000..55b7d55a --- /dev/null +++ b/services/fakeUnpaywall/snapshots/changefiles-day-example.json @@ -0,0 +1,94 @@ +{ + "list": [ + { + "date": "", + "filename": "fake1.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 50, + "size": 19896, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "fake2.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 100, + "size": 44137, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake2.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "fake3.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 2000, + "size": 877494, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake3.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "fake1-error.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 50, + "size": 19918, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1-error.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "fake1.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 50, + "size": 19896, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz?api_key=default" + }, + { + "date": "2020-01-05", + "filename": "2020-01-05-history.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 5, + "size": 1000, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/2020-01-05-history.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "2020-01-04-history.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 5, + "size": 1000, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/2020-01-04-history.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "2020-01-03-history.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 5, + "size": 1000, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/2020-01-03-history.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "2020-01-02-history.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 5, + "size": 1000, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/2020-01-02-history.jsonl.gz?api_key=default" + }, + { + "date": "", + "filename": "2019-01-02-history.jsonl.gz", + "filetype": "jsonl", + "last_modified": "", + "lines": 5, + "size": 1000, + "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/2019-01-02-history.jsonl.gz?api_key=default" + } + ] +} \ No newline at end of file diff --git a/src/fakeUnpaywall/snapshots/changefiles-week-example.json b/services/fakeUnpaywall/snapshots/changefiles-week-example.json similarity index 100% rename from src/fakeUnpaywall/snapshots/changefiles-week-example.json rename to services/fakeUnpaywall/snapshots/changefiles-week-example.json diff --git a/src/fakeUnpaywall/snapshots/fake1-error.jsonl.gz b/services/fakeUnpaywall/snapshots/fake1-error.jsonl.gz similarity index 100% rename from src/fakeUnpaywall/snapshots/fake1-error.jsonl.gz rename to services/fakeUnpaywall/snapshots/fake1-error.jsonl.gz diff --git a/src/update/test/sources/fake1.jsonl.gz b/services/fakeUnpaywall/snapshots/fake1.jsonl.gz similarity index 99% rename from src/update/test/sources/fake1.jsonl.gz rename to services/fakeUnpaywall/snapshots/fake1.jsonl.gz index ffd5bbb0..684673cf 100644 Binary files a/src/update/test/sources/fake1.jsonl.gz and b/services/fakeUnpaywall/snapshots/fake1.jsonl.gz differ diff --git a/src/fakeUnpaywall/snapshots/fake2.jsonl.gz b/services/fakeUnpaywall/snapshots/fake2.jsonl.gz similarity index 100% rename from src/fakeUnpaywall/snapshots/fake2.jsonl.gz rename to services/fakeUnpaywall/snapshots/fake2.jsonl.gz diff --git a/src/update/test/sources/fake3.jsonl.gz b/services/fakeUnpaywall/snapshots/fake3.jsonl.gz similarity index 99% rename from src/update/test/sources/fake3.jsonl.gz rename to services/fakeUnpaywall/snapshots/fake3.jsonl.gz index af21e056..91007baa 100644 Binary files a/src/update/test/sources/fake3.jsonl.gz and b/services/fakeUnpaywall/snapshots/fake3.jsonl.gz differ diff --git a/src/fakeUnpaywall/snapshots/snapshot.jsonl.gz b/services/fakeUnpaywall/snapshots/snapshot.jsonl.gz similarity index 100% rename from src/fakeUnpaywall/snapshots/snapshot.jsonl.gz rename to services/fakeUnpaywall/snapshots/snapshot.jsonl.gz diff --git a/services/fakeUnpaywall/sources/history1.jsonl b/services/fakeUnpaywall/sources/history1.jsonl new file mode 100644 index 00000000..65d07a90 --- /dev/null +++ b/services/fakeUnpaywall/sources/history1.jsonl @@ -0,0 +1,2 @@ +{"doi": "10.000/00.00.00","year": 2000,"genre": "v3","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.00","updated": "2020-01-03T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} +{"doi": "10.000/00.00.01","year": 2000,"genre": "v3","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.01","updated": "2020-01-03T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} \ No newline at end of file diff --git a/services/fakeUnpaywall/sources/history2.jsonl b/services/fakeUnpaywall/sources/history2.jsonl new file mode 100644 index 00000000..6cb21983 --- /dev/null +++ b/services/fakeUnpaywall/sources/history2.jsonl @@ -0,0 +1,2 @@ +{"doi": "10.000/00.00.00","year": 2000,"genre": "v2","is_oa": false,"title": "Title","doi_url": "https://doi.org/10.000/00.00.00","updated": "2020-01-02T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} +{"doi": "10.000/00.00.01","year": 2000,"genre": "v2","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.01","updated": "2020-01-02T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} \ No newline at end of file diff --git a/services/fakeUnpaywall/sources/history3.jsonl b/services/fakeUnpaywall/sources/history3.jsonl new file mode 100644 index 00000000..504a48f4 --- /dev/null +++ b/services/fakeUnpaywall/sources/history3.jsonl @@ -0,0 +1,2 @@ +{"doi": "10.000/00.00.00","year": 2000,"genre": "v1","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.00","updated": "2020-01-01T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} +{"doi": "10.000/00.00.01","year": 2000,"genre": "v1","is_oa": false,"title": "Title","doi_url": "https://doi.org/10.000/00.00.01","updated": "2020-01-01T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} \ No newline at end of file diff --git a/src/fakeUnpaywall/lib/controllers/changefiles.js b/services/fakeUnpaywall/src/controllers/changefiles.js similarity index 80% rename from src/fakeUnpaywall/lib/controllers/changefiles.js rename to services/fakeUnpaywall/src/controllers/changefiles.js index 7ad3cb24..b6cdc09c 100644 --- a/src/fakeUnpaywall/lib/controllers/changefiles.js +++ b/services/fakeUnpaywall/src/controllers/changefiles.js @@ -78,6 +78,31 @@ async function updateChangefilesExample(interval) { changefilesDay.list[4].last_modified = new Date(now - oneYear - (1 * oneDay)) .toISOString().slice(0, 19); + changefilesDay.list[5].date = new Date('2020-01-05') + .toISOString().slice(0, 10); + changefilesDay.list[5].last_modified = new Date('2020-01-05') + .toISOString().slice(0, 19); + + changefilesDay.list[6].date = new Date('2020-01-04') + .toISOString().slice(0, 10); + changefilesDay.list[6].last_modified = new Date('2020-01-04') + .toISOString().slice(0, 19); + + changefilesDay.list[7].date = new Date('2020-01-03') + .toISOString().slice(0, 10); + changefilesDay.list[7].last_modified = new Date('2020-01-03') + .toISOString().slice(0, 19); + + changefilesDay.list[8].date = new Date('2020-01-02') + .toISOString().slice(0, 10); + changefilesDay.list[8].last_modified = new Date('2020-01-02') + .toISOString().slice(0, 19); + + changefilesDay.list[9].date = new Date('2019-01-02') + .toISOString().slice(0, 10); + changefilesDay.list[9].last_modified = new Date('2019-01-02') + .toISOString().slice(0, 19); + try { await fs.writeFile(changefilesDayPath, JSON.stringify(changefilesDay, null, 2), 'utf8'); } catch (err) { diff --git a/src/fakeUnpaywall/lib/logger.js b/services/fakeUnpaywall/src/logger.js similarity index 98% rename from src/fakeUnpaywall/lib/logger.js rename to services/fakeUnpaywall/src/logger.js index 507b15ef..704d4aaf 100644 --- a/src/fakeUnpaywall/lib/logger.js +++ b/services/fakeUnpaywall/src/logger.js @@ -16,7 +16,6 @@ const { colorize, } = format; -// TODO log for prod // function prodFormat() { // const replaceError = ({ // name, level, message, stack, diff --git a/src/fakeUnpaywall/lib/middlewares/auth.js b/services/fakeUnpaywall/src/middlewares/auth.js similarity index 100% rename from src/fakeUnpaywall/lib/middlewares/auth.js rename to services/fakeUnpaywall/src/middlewares/auth.js diff --git a/src/fakeUnpaywall/lib/routers/changefiles.js b/services/fakeUnpaywall/src/routers/changefiles.js similarity index 100% rename from src/fakeUnpaywall/lib/routers/changefiles.js rename to services/fakeUnpaywall/src/routers/changefiles.js diff --git a/src/fakeUnpaywall/lib/routers/ping.js b/services/fakeUnpaywall/src/routers/ping.js similarity index 100% rename from src/fakeUnpaywall/lib/routers/ping.js rename to services/fakeUnpaywall/src/routers/ping.js diff --git a/src/fakeUnpaywall/lib/routers/snapshots.js b/services/fakeUnpaywall/src/routers/snapshots.js similarity index 100% rename from src/fakeUnpaywall/lib/routers/snapshots.js rename to services/fakeUnpaywall/src/routers/snapshots.js diff --git a/src/frontend/.dockerignore b/services/frontend/.dockerignore similarity index 100% rename from src/frontend/.dockerignore rename to services/frontend/.dockerignore diff --git a/src/frontend/.eslintrc.json b/services/frontend/.eslintrc.json similarity index 100% rename from src/frontend/.eslintrc.json rename to services/frontend/.eslintrc.json diff --git a/src/frontend/.gitignore b/services/frontend/.gitignore similarity index 100% rename from src/frontend/.gitignore rename to services/frontend/.gitignore diff --git a/src/frontend/.npmrc b/services/frontend/.npmrc similarity index 100% rename from src/frontend/.npmrc rename to services/frontend/.npmrc diff --git a/src/frontend/Dockerfile b/services/frontend/Dockerfile similarity index 72% rename from src/frontend/Dockerfile rename to services/frontend/Dockerfile index 67423627..965bc2fd 100644 --- a/src/frontend/Dockerfile +++ b/services/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.17-alpine3.18 as build +FROM node:18.19.1-alpine3.19 as build LABEL maintainer="ezTeam " @@ -11,24 +11,27 @@ ARG NUXT_PUBLIC_UPDATE_HOST ARG NUXT_PUBLIC_ENRICH_HOST ARG NUXT_PUBLIC_APIKEY_HOST ARG NUXT_PUBLIC_MAIL_HOST -ARG NUXT_PUBLIC_HEALTH_HOST -ARG NUXT_MAIL_HOST -ARG NUXT_MAIL_APIKEY ARG NUXT_PUBLIC_ELASTIC_ENV ARG NUXT_PUBLIC_VERSION +ARG NUXT_MAIL_HOST +ARG NUXT_MAIL_APIKEY WORKDIR /usr/src/app COPY package*.json ./ -RUN npm i +RUN npm ci COPY . . RUN npm run build -FROM node:18.17-alpine3.18 +FROM node:18.19.1-alpine3.19 EXPOSE 3000 ENV NODE_ENV production COPY --from=build /usr/src/app/.output /usr/src/app + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + CMD [ "node", "/usr/src/app/server/index.mjs" ] \ No newline at end of file diff --git a/src/frontend/README.md b/services/frontend/README.md similarity index 81% rename from src/frontend/README.md rename to services/frontend/README.md index fb7ef1a9..3a3e1774 100644 --- a/src/frontend/README.md +++ b/services/frontend/README.md @@ -1,8 +1,14 @@ # ezunpaywall-frontend -frontend service of ezunpaywall +Web interface for : +- Show metrics on unpaywall data +- Examples of how to use the graphql API and enrichment service +-openAPI documentation +- A contact form +- A server administration section +- A history of data update reports. -## Service environment variables +## Environment variables | name | default | description | | --- | --- | --- | @@ -16,7 +22,6 @@ frontend service of ezunpaywall | NUXT_PUBLIC_APIKEY_HOST | http://localhost:59704 | Host of ezunpaywall apikey service | | NUXT_MAIL_APIKEY | changeme | Apikey to send mail of mail service | | NUXT_MAIL_HOST | http://localhost:59705 | Host of ezunpaywall mail service | -| NUXT_PUBLIC_HEALTH_HOST | http://localhost:59707 | Host of ezunpaywall health service | | NUXT_PUBLIC_ELASTIC_ENV | development | version of elastic | | NUXT_PUBLIC_VERSION | development | version displayed on frontend | diff --git a/src/frontend/app.vue b/services/frontend/app.vue similarity index 100% rename from src/frontend/app.vue rename to services/frontend/app.vue diff --git a/src/frontend/components/administration/EzmesureButton.vue b/services/frontend/components/administration/EzmesureButton.vue similarity index 100% rename from src/frontend/components/administration/EzmesureButton.vue rename to services/frontend/components/administration/EzmesureButton.vue diff --git a/src/frontend/components/administration/Login.vue b/services/frontend/components/administration/Login.vue similarity index 92% rename from src/frontend/components/administration/Login.vue rename to services/frontend/components/administration/Login.vue index 471703cf..025a5142 100644 --- a/src/frontend/components/administration/Login.vue +++ b/services/frontend/components/administration/Login.vue @@ -13,12 +13,11 @@ > @@ -49,7 +48,7 @@ const { $apikey } = useNuxtApp(); const loading = ref(false); const valid = ref(false); -const password = ref(''); +const password = ref('password'); const passwordVisible = ref(false); const passwordRules = computed(() => (value) => !!value || t('required')); @@ -72,7 +71,6 @@ async function tryLogin() { adminStore.setIsAdmin(true); adminStore.setPassword(password.value); loading.value = false; - snackStore.success(t('info.administration.login')); } diff --git a/src/frontend/components/administration/LogoutButton.vue b/services/frontend/components/administration/LogoutButton.vue similarity index 100% rename from src/frontend/components/administration/LogoutButton.vue rename to services/frontend/components/administration/LogoutButton.vue diff --git a/src/frontend/components/administration/apikey/ApikeyCard.vue b/services/frontend/components/administration/apikey/ApikeyCard.vue similarity index 68% rename from src/frontend/components/administration/apikey/ApikeyCard.vue rename to services/frontend/components/administration/apikey/ApikeyCard.vue index e5c98688..7ce8a0cd 100644 --- a/src/frontend/components/administration/apikey/ApikeyCard.vue +++ b/services/frontend/components/administration/apikey/ApikeyCard.vue @@ -33,7 +33,7 @@ - {{ apikey }} + {{ props.apikey }} @@ -43,19 +43,21 @@ mdi-account-circle - {{ t("administration.apikey.ownerValue", { owner: config.owner }) }} + {{ t("administration.apikey.ownerValue", { owner: props.config.owner }) }} mdi-text-account - {{ t("administration.apikey.descriptionValue", { description: config.description }) }} + {{ t("administration.apikey.descriptionValue", { description: props.config.description }) }} mdi-calendar-account-outline - {{ t("administration.apikey.createdAtValue", { date: config.createdAt }) }} + + {{ t("administration.apikey.createdAtValue", { date: props.config.createdAt }) }} + @@ -96,40 +98,24 @@ {{ t("edit") }} - {{ t("delete") }} - diff --git a/src/frontend/components/administration/apikey/ApikeyTab.vue b/services/frontend/components/administration/apikey/ApikeyTab.vue similarity index 58% rename from src/frontend/components/administration/apikey/ApikeyTab.vue rename to services/frontend/components/administration/apikey/ApikeyTab.vue index 6e30d653..1258e05f 100644 --- a/src/frontend/components/administration/apikey/ApikeyTab.vue +++ b/services/frontend/components/administration/apikey/ApikeyTab.vue @@ -49,11 +49,6 @@ {{ t("administration.apikey.create") }} - @@ -110,7 +131,10 @@ import { storeToRefs } from 'pinia'; import { useSnacksStore } from '@/store/snacks'; import { useAdminStore } from '@/store/admin'; +import SearchBar from '@/components/administration/apikey/SearchBar.vue'; import CreateDialog from '@/components/administration/apikey/CreateDialog.vue'; +import DeleteDialog from '@/components/administration/apikey/DeleteDialog.vue'; +import UpdateDialog from '@/components/administration/apikey/UpdateDialog.vue'; import ImportDialog from '@/components/administration/apikey/ImportDialog.vue'; import ExportDialog from '@/components/administration/apikey/ExportDialog.vue'; import Loader from '@/components/skeleton/Loader.vue'; @@ -125,11 +149,36 @@ const { $apikey } = useNuxtApp(); const { password } = storeToRefs(adminStore); const loading = ref(false); + +const searchValue = ref(''); + const createDialogVisible = ref(false); +const updateDialogVisible = ref(false); +const deleteDialogVisible = ref(false); const importDialogVisible = ref(false); const exportDialogVisible = ref(false); + +// TODO, use one ref +const selectedApikey = ref(''); +const selectedName = ref(''); +const selectedDescription = ref(''); +const selectedOwner = ref(''); +const selectedAccess = ref([]); +const selectedAttributes = ref([]); +const selectedAllowed = ref(false); const apikeys = ref([]); +const apikeysFiltered = computed(() => { + let filteredAPIkeys = apikeys.value; + if (searchValue.value) { + filteredAPIkeys = apikeys.value.filter( + (key) => key.apikey.includes(searchValue.value), + ); + return filteredAPIkeys; + } + return apikeys.value; +}); + async function getApikeys() { let res; loading.value = true; @@ -150,6 +199,28 @@ async function getApikeys() { apikeys.value = res?.data; } +async function openUpdateDialog(id) { + const apikey = apikeys.value.find((e) => e.apikey === id); + selectedApikey.value = id; + selectedName.value = apikey.config.name; + selectedDescription.value = apikey.config.description; + selectedOwner.value = apikey.config.owner; + selectedAccess.value = apikey.config.access; + selectedAttributes.value = apikey.config.attributes; + selectedAllowed.value = apikey.config.allowed; + await nextTick(); + updateDialogVisible.value = true; +} + +async function openDeleteDialog(id) { + selectedApikey.value = id; + deleteDialogVisible.value = true; +} + +function updateSearchValue(newValue) { + searchValue.value = newValue; +} + onMounted(() => { getApikeys(); }); diff --git a/src/frontend/components/administration/apikey/CreateDialog.vue b/services/frontend/components/administration/apikey/CreateDialog.vue similarity index 97% rename from src/frontend/components/administration/apikey/CreateDialog.vue rename to services/frontend/components/administration/apikey/CreateDialog.vue index b06499e1..8072070f 100644 --- a/src/frontend/components/administration/apikey/CreateDialog.vue +++ b/services/frontend/components/administration/apikey/CreateDialog.vue @@ -69,7 +69,7 @@ {{ t('administration.apikey.attributes') }} - - {{ apikey }} + {{ props.apikey }} diff --git a/src/frontend/components/administration/apikey/ExportDialog.vue b/services/frontend/components/administration/apikey/ExportDialog.vue similarity index 100% rename from src/frontend/components/administration/apikey/ExportDialog.vue rename to services/frontend/components/administration/apikey/ExportDialog.vue diff --git a/src/frontend/components/administration/apikey/ImportDialog.vue b/services/frontend/components/administration/apikey/ImportDialog.vue similarity index 100% rename from src/frontend/components/administration/apikey/ImportDialog.vue rename to services/frontend/components/administration/apikey/ImportDialog.vue diff --git a/services/frontend/components/administration/apikey/SearchBar.vue b/services/frontend/components/administration/apikey/SearchBar.vue new file mode 100644 index 00000000..d6ef6f20 --- /dev/null +++ b/services/frontend/components/administration/apikey/SearchBar.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/frontend/components/administration/apikey/UpdateDialog.vue b/services/frontend/components/administration/apikey/UpdateDialog.vue similarity index 67% rename from src/frontend/components/administration/apikey/UpdateDialog.vue rename to services/frontend/components/administration/apikey/UpdateDialog.vue index 243f7450..b19a240d 100644 --- a/src/frontend/components/administration/apikey/UpdateDialog.vue +++ b/services/frontend/components/administration/apikey/UpdateDialog.vue @@ -76,9 +76,13 @@ {{ t('administration.apikey.attributes') }} - @@ -114,7 +118,7 @@ diff --git a/services/frontend/components/administration/elastic/ElasticCard.vue b/services/frontend/components/administration/elastic/ElasticCard.vue new file mode 100644 index 00000000..32029896 --- /dev/null +++ b/services/frontend/components/administration/elastic/ElasticCard.vue @@ -0,0 +1,140 @@ + + + + diff --git a/services/frontend/components/administration/health/HealthCard.vue b/services/frontend/components/administration/health/HealthCard.vue new file mode 100644 index 00000000..0254c314 --- /dev/null +++ b/services/frontend/components/administration/health/HealthCard.vue @@ -0,0 +1,81 @@ + + + diff --git a/src/frontend/components/administration/health/HealthTab.vue b/services/frontend/components/administration/health/HealthTab.vue similarity index 64% rename from src/frontend/components/administration/health/HealthTab.vue rename to services/frontend/components/administration/health/HealthTab.vue index 8dc9566e..d6adada5 100644 --- a/src/frontend/components/administration/health/HealthTab.vue +++ b/services/frontend/components/administration/health/HealthTab.vue @@ -16,6 +16,7 @@ v-bind="props" icon="mdi-reload" :disabled="loading" + :loading="loading" @click.stop="getHealths()" /> @@ -32,7 +33,7 @@ @@ -63,34 +65,37 @@ import HealthCard from '@/components/administration/health/HealthCard.vue'; import Loader from '@/components/skeleton/Loader.vue'; import NoData from '@/components/skeleton/NoData.vue'; -import { useSnacksStore } from '@/store/snacks'; - const { t } = useI18n(); -const snackStore = useSnacksStore(); -const { $health } = useNuxtApp(); const loading = ref(false); -const healths = ref(false); -async function getHealths() { - let res; +const { + $graphql, + $update, + $enrich, + $apikey, + $mail, +} = useNuxtApp(); + +const healthCards = ref([]); + +const services = [ + { name: 'graphql', api: $graphql }, + { name: 'update', api: $update }, + { name: 'enrich', api: $enrich }, + { name: 'apikey', api: $apikey }, + { name: 'mail', api: $mail }, +]; + +function getHealths() { loading.value = true; - try { - res = await $health({ - method: 'GET', - url: '/status', + if (healthCards.value) { + healthCards.value.forEach((card) => { + if (card?.getHealth) { + card.getHealth(); + } }); - } catch (e) { - snackStore.error(t('error.health.get')); - loading.value = false; - return; } - healths.value = res?.data; loading.value = false; } - -onMounted(() => { - getHealths(); -}); - diff --git a/src/frontend/components/administration/update/CronButton.vue b/services/frontend/components/administration/update/CronButton.vue similarity index 63% rename from src/frontend/components/administration/update/CronButton.vue rename to services/frontend/components/administration/update/CronButton.vue index 9294ca32..dbbdfcee 100644 --- a/src/frontend/components/administration/update/CronButton.vue +++ b/services/frontend/components/administration/update/CronButton.vue @@ -1,15 +1,18 @@ @@ -19,7 +24,8 @@ import Login from '@/components/administration/Login.vue'; import LogoutButton from '@/components/administration/LogoutButton.vue'; import EzmesureButton from '@/components/administration/EzmesureButton.vue'; -import WeekHistory from '@/components/report/ReportsCard.vue'; +import ElasticCard from '@/components/administration/elastic/ElasticCard.vue'; +import ReportsCard from '@/components/report/ReportsCard.vue'; import HealthTab from '@/components/administration/health/HealthTab.vue'; import ApikeyTab from '@/components/administration/apikey/ApikeyTab.vue'; diff --git a/src/frontend/pages/contact.vue b/services/frontend/pages/contact.vue similarity index 96% rename from src/frontend/pages/contact.vue rename to services/frontend/pages/contact.vue index 6ecdcd56..9cfc42ac 100644 --- a/src/frontend/pages/contact.vue +++ b/services/frontend/pages/contact.vue @@ -79,7 +79,7 @@ const snackStore = useSnacksStore(); const form = ref(null); const email = ref(''); const message = ref(''); -const subject = ref(t('contact.requestInformation')); +const subject = ref({ key: 'informations', name: t('contact.requestInformation') }); const sendBrowser = ref(true); const valid = ref(false); const loading = ref(false); @@ -109,7 +109,7 @@ const messageRules = computed(() => [(v) => !!v || t('contact.contentIsRequired' const subjectRules = computed(() => [(v) => !!v || t('contact.subjectIsRequired')]); function resetForm() { - message.value = ' '; + message.value = ''; } async function validate() { diff --git a/src/frontend/pages/enrich.vue b/services/frontend/pages/enrich.vue similarity index 100% rename from src/frontend/pages/enrich.vue rename to services/frontend/pages/enrich.vue diff --git a/src/frontend/pages/graphql.vue b/services/frontend/pages/graphql.vue similarity index 100% rename from src/frontend/pages/graphql.vue rename to services/frontend/pages/graphql.vue diff --git a/src/frontend/pages/index.vue b/services/frontend/pages/index.vue similarity index 100% rename from src/frontend/pages/index.vue rename to services/frontend/pages/index.vue diff --git a/src/frontend/pages/open-api.vue b/services/frontend/pages/open-api.vue similarity index 67% rename from src/frontend/pages/open-api.vue rename to services/frontend/pages/open-api.vue index c7dbf1eb..a9b46d48 100644 --- a/src/frontend/pages/open-api.vue +++ b/services/frontend/pages/open-api.vue @@ -20,8 +20,10 @@ diff --git a/src/frontend/pages/report-history.vue b/services/frontend/pages/report-history.vue similarity index 77% rename from src/frontend/pages/report-history.vue rename to services/frontend/pages/report-history.vue index 261d174c..73f9eefa 100644 --- a/src/frontend/pages/report-history.vue +++ b/services/frontend/pages/report-history.vue @@ -1,6 +1,8 @@ diff --git a/src/frontend/plugins/apikey.js b/services/frontend/plugins/apikey.js similarity index 100% rename from src/frontend/plugins/apikey.js rename to services/frontend/plugins/apikey.js diff --git a/src/frontend/plugins/enrich.js b/services/frontend/plugins/enrich.js similarity index 100% rename from src/frontend/plugins/enrich.js rename to services/frontend/plugins/enrich.js diff --git a/src/frontend/plugins/graphql.js b/services/frontend/plugins/graphql.js similarity index 100% rename from src/frontend/plugins/graphql.js rename to services/frontend/plugins/graphql.js diff --git a/src/frontend/plugins/highlight.client.js b/services/frontend/plugins/highlight.client.js similarity index 100% rename from src/frontend/plugins/highlight.client.js rename to services/frontend/plugins/highlight.client.js diff --git a/src/frontend/plugins/mail.js b/services/frontend/plugins/mail.js similarity index 78% rename from src/frontend/plugins/mail.js rename to services/frontend/plugins/mail.js index e7129e64..4d34921c 100644 --- a/src/frontend/plugins/mail.js +++ b/services/frontend/plugins/mail.js @@ -1,5 +1,4 @@ import axios from 'axios'; - import { defineNuxtPlugin } from '#imports'; export default defineNuxtPlugin((nuxtApp) => { @@ -7,9 +6,6 @@ export default defineNuxtPlugin((nuxtApp) => { const mail = axios.create({ baseURL: mailHost, - headers: { - 'x-api-key': nuxtApp.$config.public.mailApikey, - }, }); return { diff --git a/src/frontend/plugins/update.js b/services/frontend/plugins/update.js similarity index 100% rename from src/frontend/plugins/update.js rename to services/frontend/plugins/update.js diff --git a/src/frontend/plugins/vuetify.js b/services/frontend/plugins/vuetify.js similarity index 84% rename from src/frontend/plugins/vuetify.js rename to services/frontend/plugins/vuetify.js index ad7da8a9..5a85f619 100644 --- a/src/frontend/plugins/vuetify.js +++ b/services/frontend/plugins/vuetify.js @@ -2,9 +2,6 @@ import { createVuetify } from 'vuetify'; import * as components from 'vuetify/components'; import * as directives from 'vuetify/directives'; import colors from 'vuetify/lib/util/colors'; -import { VDataTable } from 'vuetify/labs/VDataTable'; -import { VStepper, VStepperHeader } from 'vuetify/labs/VStepper'; - import { defineNuxtPlugin } from '#imports'; export default defineNuxtPlugin((nuxtApp) => { @@ -12,9 +9,6 @@ export default defineNuxtPlugin((nuxtApp) => { ssr: true, components: { ...components, - VDataTable, - VStepper, - VStepperHeader, }, directives, theme: { diff --git a/examples/example.csv b/services/frontend/public/example.csv similarity index 100% rename from examples/example.csv rename to services/frontend/public/example.csv diff --git a/examples/example.jsonl b/services/frontend/public/example.jsonl similarity index 100% rename from examples/example.jsonl rename to services/frontend/public/example.jsonl diff --git a/services/frontend/public/favicon.ico b/services/frontend/public/favicon.ico new file mode 100644 index 00000000..df9b15fd Binary files /dev/null and b/services/frontend/public/favicon.ico differ diff --git a/src/frontend/server/routes/nuxt/mail/index.js b/services/frontend/server/routes/nuxt/mail/index.js similarity index 100% rename from src/frontend/server/routes/nuxt/mail/index.js rename to services/frontend/server/routes/nuxt/mail/index.js diff --git a/src/frontend/static/images/ezmesure-logo.svg b/services/frontend/static/images/ezmesure-logo.svg similarity index 100% rename from src/frontend/static/images/ezmesure-logo.svg rename to services/frontend/static/images/ezmesure-logo.svg diff --git a/src/frontend/static/images/lang/en.png b/services/frontend/static/images/lang/en.png similarity index 100% rename from src/frontend/static/images/lang/en.png rename to services/frontend/static/images/lang/en.png diff --git a/src/frontend/static/images/lang/fr.png b/services/frontend/static/images/lang/fr.png similarity index 100% rename from src/frontend/static/images/lang/fr.png rename to services/frontend/static/images/lang/fr.png diff --git a/src/frontend/store/admin.js b/services/frontend/store/admin.js similarity index 100% rename from src/frontend/store/admin.js rename to services/frontend/store/admin.js diff --git a/src/frontend/store/enrich.js b/services/frontend/store/enrich.js similarity index 100% rename from src/frontend/store/enrich.js rename to services/frontend/store/enrich.js diff --git a/src/frontend/store/snacks.js b/services/frontend/store/snacks.js similarity index 100% rename from src/frontend/store/snacks.js rename to services/frontend/store/snacks.js diff --git a/src/frontend/tsconfig.json b/services/frontend/tsconfig.json similarity index 100% rename from src/frontend/tsconfig.json rename to services/frontend/tsconfig.json diff --git a/src/enrich/.gitignore b/services/graphql/.dockerignore similarity index 85% rename from src/enrich/.gitignore rename to services/graphql/.dockerignore index 922a83d2..d5eb2250 100644 --- a/src/enrich/.gitignore +++ b/services/graphql/.dockerignore @@ -1,7 +1,7 @@ node_modules/ log/ -test/ data/ -.eslintrc.json +test/ .gitignore -README.md +.eslintrc.json +README.md \ No newline at end of file diff --git a/src/graphql/.eslintrc.json b/services/graphql/.eslintrc.json similarity index 100% rename from src/graphql/.eslintrc.json rename to services/graphql/.eslintrc.json diff --git a/services/graphql/.gitignore b/services/graphql/.gitignore new file mode 100644 index 00000000..07f16694 --- /dev/null +++ b/services/graphql/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +log/ +data/ \ No newline at end of file diff --git a/services/graphql/Dockerfile b/services/graphql/Dockerfile new file mode 100644 index 00000000..8139bf08 --- /dev/null +++ b/services/graphql/Dockerfile @@ -0,0 +1,30 @@ +FROM node:18.19.1-alpine3.19 +LABEL maintainer="ezTeam " + +EXPOSE 3000 + +ENV NODE_ENV production + +ARG ACCESS_LOG_ROTATE +ARG TIMEZONE +ARG REDIS_HOST +ARG REDIS_PORT +ARG REDIS_PASSWORD +ARG ELASTICSEARCH_HOSTS +ARG ELASTICSEARCH_PORT +ARG ELASTICSEARCH_USERNAME +ARG ELASTICSEARCH_PASSWORD +ARG ELASTICSEARCH_INDEX_BASE +ARG ELASTICSEARCH_INDEX_HISTORY +ARG HEALTH_TIMEOUT + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm ci --omit=dev +COPY . . + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/services/graphql/README.md b/services/graphql/README.md new file mode 100644 index 00000000..1ddbb649 --- /dev/null +++ b/services/graphql/README.md @@ -0,0 +1,105 @@ +# ezunpaywall-graphql + +A graphql API for querying unpaywall data via one or more DOIs. + +## Config + +To set up this service, you can use environment variables. The config is displayed at startup. Sensitive data are not displayed. + +``` +# if sensitive data are not updated +warn: [config]: Redis password has the default value +warn: [config]: Elastic password has the default value + +info: { + "nodeEnv": "development", + "accessLogRotate": false, + "timezone": "Europe/Paris" + "redis": { + "host": "redis", + "port": "6379", + "password": "********" + }, + "elasticsearch": { + "host": "http://elastic", + "port": 9200, + "user": "elastic", + "password": "********", + "indexBase": "unpaywall_base", + "indexHistory": "unpaywall_history" + }, + "healthTimeout": 3000 +} +``` + +## Environment variables + +| name | default | description | +| --- | --- | --- | +| NODE_ENV | development | environment of node | +| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | +| TIMEZONE | Europe/Paris | timezone of app used in cron | +| REDIS_HOST | redis | redis host | +| REDIS_PORT | 6379 | redis port | +| REDIS_PASSWORD | changeme | redis password | +| ELASTICSEARCH_HOSTS | http://elastic | elasticsearch host | +| ELASTICSEARCH_PORT | 9200 | elasticsearch port | +| ELASTICSEARCH_USERNAME | elastic | elasticsearch admin username | +| ELASTICSEARCH_PASSWORD | changeme | elasticsearch admin password | +| ELASTICSEARCH_INDEX_ALIAS | upw | graphql entry point | +| HEALTH_TIMEOUT | 3000 | timeout to query the health route | + +## Activity diagram + +![Activity-diagram](./doc/activity-diagram-graphql.png) + +### Object structure + +[data-format](https://unpaywall.org/data-format) + +## Graphql Request + +### API key + +You can put your API key in the query or in the header. +- In the query, use the key: `apikey` +- in the header, use the key: `x-api-key` + +### Curl + +```bash +# GET +curl --request GET \ + --url 'https://unpaywall.inist.fr/api/graphql?query=%7Bunpaywall(dois%3A%5B%2210.1001%2Fjama.2016.9797%22%5D)%7Bdoi%2C%20is_oa%2C%20oa_status%2C%20data_standard%2C%20updated%2C%20best_oa_location%7B%20evidence%20%7D%7D%7D' \ + --header 'Content-Type: application/json' \ + --header 'x-api-key: demo' + +# POST +curl --request POST \ + --url https://unpaywall.inist.fr/api/graphql \ + --header 'Content-Type: application/json' \ + --header 'x-api-key: demo' \ + --data '{"query":"{unpaywall(dois:[\"10.1001/jama.2016.9797\"]){doi,is_oa,oa_status,data_standard,updated,best_oa_location {endpoint_id}}}"}' +``` + +## Cron + +One cron automatically update metrics of unpaywall data. the elastic request takes time and is saved locally. + +## Log format + +``` +:ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":response-time" ":user-agent" ":countDOI" +``` + +## Open API + +[open-api documentation](https://unpaywall.inist.fr/open-api?doc=graphql) + +## Test + +``` +# Functional tests +npm run test +# For the rest, it's your turn to play +``` \ No newline at end of file diff --git a/services/graphql/app.js b/services/graphql/app.js new file mode 100644 index 00000000..6eaabd20 --- /dev/null +++ b/services/graphql/app.js @@ -0,0 +1,88 @@ +const fs = require('fs-extra'); +const path = require('path'); +const express = require('express'); +const responseTime = require('response-time'); +const cors = require('cors'); +const { json } = require('body-parser'); +const { ApolloServer } = require('@apollo/server'); +const { ApolloServerPluginLandingPageProductionDefault } = require('@apollo/server/plugin/landingPage/default'); +const { paths } = require('config'); + +const { expressMiddleware } = require('@apollo/server/express4'); + +const { pingRedis, startConnectionRedis } = require('./src/services/redis'); + +const auth = require('./src/middlewares/auth'); +const countDOIPlugin = require('./src/middlewares/countDOI'); + +const accessLogger = require('./src/logger/access'); +const appLogger = require('./src/logger/appLogger'); + +const getConfig = require('./src/config'); + +const cronMetrics = require('./src/controllers/cron/metrics'); +const { setMetrics } = require('./src/controllers/metrics'); + +const { pingElastic } = require('./src/services/elastic'); + +const routerHealthCheck = require('./src/routers/healthcheck'); +const routerPing = require('./src/routers/ping'); +const routerOpenapi = require('./src/routers/openapi'); + +const typeDefs = require('./src/models'); +const resolvers = require('./src/resolvers'); + +// create log directory +fs.ensureDir(path.resolve(paths.log.applicationDir)); +fs.ensureDir(path.resolve(paths.log.accessDir)); +fs.ensureDir(path.resolve(paths.log.healthCheckDir)); + +process.env.NODE_ENV = 'production'; + +const server = new ApolloServer({ + typeDefs, + resolvers, + introspection: true, + csrfPrevention: false, + plugins: [ApolloServerPluginLandingPageProductionDefault({ footer: false }), countDOIPlugin], + context: ({ req }) => ({ req }), +}); + +(async () => { + const app = express(); + + app.use(responseTime()); + app.use(cors({ + origin: '*', + allowedHeaders: ['Content-Type', 'x-api-key'], + method: ['GET', 'POST'], + })); + + // initiate healthcheck router with his logger + app.use(routerHealthCheck); + + // initiate access logger + app.use(accessLogger); + + // initiate all other routes + app.use(routerPing); + app.use(routerPing); + app.use(routerOpenapi); + + await server.start(); + + // initiate graphql endpoint + app.use('/graphql', cors(), json(), auth, expressMiddleware(server, { context: async ({ req }) => req })); + + app.listen(3000, async () => { + appLogger.info('[express]: ezunpaywall graphQL API listening on 3000'); + pingElastic().then(() => { + setMetrics(); + }); + getConfig(); + await startConnectionRedis(); + pingRedis(); + + cronMetrics.start(); + }); +})(); diff --git a/src/graphql/certs/.gitkeep b/services/graphql/certs/.gitkeep similarity index 100% rename from src/graphql/certs/.gitkeep rename to services/graphql/certs/.gitkeep diff --git a/src/graphql/config/custom-environment-variables.json b/services/graphql/config/custom-environment-variables.json similarity index 76% rename from src/graphql/config/custom-environment-variables.json rename to services/graphql/config/custom-environment-variables.json index 25340603..806f820c 100644 --- a/src/graphql/config/custom-environment-variables.json +++ b/services/graphql/config/custom-environment-variables.json @@ -1,6 +1,7 @@ { "nodeEnv": "NODE_ENV", "accessLogRotate": "ACCESS_LOG_ROTATE", + "timezone": "TIMEZONE", "redis": { "host": "REDIS_HOST", "port": "REDIS_PORT", @@ -11,7 +12,8 @@ "port": "ELASTICSEARCH_PORT", "user": "ELASTICSEARCH_USERNAME", "password": "ELASTICSEARCH_PASSWORD", - "indexAlias": "ELASTICSEARCH_INDEX_ALIAS" + "indexBase": "ELASTICSEARCH_INDEX_BASE", + "indexHistory": "ELASTICSEARCH_INDEX_HISTORY" }, "healthTimeout": "HEALTH_TIMEOUT" } \ No newline at end of file diff --git a/src/graphql/config/default.json b/services/graphql/config/default.json similarity index 52% rename from src/graphql/config/default.json rename to services/graphql/config/default.json index f57ad5e9..49451fe9 100644 --- a/src/graphql/config/default.json +++ b/services/graphql/config/default.json @@ -1,6 +1,7 @@ { "nodeEnv": "development", "accessLogRotate": false, + "timezone": "Europe/Paris", "redis": { "host": "redis", "port": "6379", @@ -11,7 +12,15 @@ "port": 9200, "user": "elastic", "password": "changeme", - "indexAlias": "upw" + "indexBase": "unpaywall_base", + "indexHistory": "unpaywall_history" + }, + "paths": { + "log": { + "applicationDir": "./log/application", + "accessDir": "./log/access", + "healthCheckDir": "./log/healthcheck" + } }, "healthTimeout": 3000 } \ No newline at end of file diff --git a/services/graphql/doc/activity-diagram-graphql.png b/services/graphql/doc/activity-diagram-graphql.png new file mode 100644 index 00000000..b923b703 Binary files /dev/null and b/services/graphql/doc/activity-diagram-graphql.png differ diff --git a/services/graphql/openapi.yml b/services/graphql/openapi.yml new file mode 100644 index 00000000..8818adb5 --- /dev/null +++ b/services/graphql/openapi.yml @@ -0,0 +1,189 @@ +openapi: 3.0.0 +info: + description: The graphql service allows access to unpaywall data stored in elastic. + version: 1.0.0 + title: Graphql service + contact: + email: ezteam@couperin.org + name: ezTeam + license: + name: CeCILL 2.1 + url: http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html +servers: + - url: https://unpaywall.inist.fr/api +tags: + - name: ping +paths: + /graphql: + get: + tags: + - ping + operationId: get-graphql + summary: Name of service + description: Get name of graphql service + parameters: [] + responses: + '200': + description: OK + content: + '*/*': + schema: + type: string + x-examples: + example-1: graphql service + examples: + service: + value: graphql service + Success: + examples: + response: + value: + message: graphql service + + + /graphql/ping: + get: + tags: + - ping + operationId: get-graphql-ping + summary: Ping graphql service + description: ping graphql service + parameters: [] + responses: + '204': + description: No Content + + /graphql/health: + get: + tags: + - ping + operationId: get-graphql-health + summary: Health + description: Health on all service connected to graphql service + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + redis: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elastic: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elapsedTime: + type: integer + status: + type: boolean + x-examples: + Example 1: + redis: + elapsedTime: 0 + status: true + elastic: + elapsedTime: 1 + status: true + elapsedTime: 1 + status: true + examples: + Success: + value: + redis: + elapsedTime: 1 + status: true + elastic: + elapsedTime: 1 + status: true + elapsedTime: 1 + status: true + Error redis: + value: + redis: + elapsedTime: 3001 + status: false + error: time out + elastic: + elapsedTime: 1 + status: true + elapsedTime: 3001 + status: false + parameters: [] + /graphql/health/redis: + get: + tags: + - ping + operationId: get-graphql-health-redis + summary: Health on redis service + description: Health on redis + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + + /graphql/health/elastic: + get: + tags: + - ping + operationId: get-graphql-health-elastic + summary: Health on elastic service + description: Health on elastic + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + + + +externalDocs: + description: Find out more about Swagger + url: http://swagger.io +components: + responses: + Health: + description: Example response + content: + application/json: + schema: + type: object + properties: + name: + type: string + status: + type: boolean + elapsedTime: + type: integer + x-examples: + Example 1: + name: redis + status: true + elapsedTime: 1 + examples: + Success: + value: + name: name of service + status: true + elapsedTime: 1 + Error redis: + value: + name: redis + elapsedTime: 3002 + error: time out + status: false + securitySchemes: + x-api-key: + type: apiKey + in: header + name: API Key diff --git a/src/graphql/package-lock.json b/services/graphql/package-lock.json similarity index 99% rename from src/graphql/package-lock.json rename to services/graphql/package-lock.json index f74d4cdd..50c211f5 100644 --- a/src/graphql/package-lock.json +++ b/services/graphql/package-lock.json @@ -1,12 +1,12 @@ { - "name": "ezunpaywall-graphql-api", - "version": "1.3.0", + "name": "ezunpaywall-graphql", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "ezunpaywall-graphql-api", - "version": "1.3.0", + "name": "ezunpaywall-graphql", + "version": "1.3.5", "license": "CeCILL", "dependencies": { "@apollo/server": "^4.9.3", @@ -5276,8 +5276,7 @@ "@apollo/cache-control-types": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", - "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", - "requires": {} + "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==" }, "@apollo/protobufjs": { "version": "1.2.7", @@ -5369,8 +5368,7 @@ "@apollo/utils.dropunuseddefinitions": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", - "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", - "requires": {} + "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==" }, "@apollo/utils.fetcher": { "version": "2.0.1", @@ -5406,14 +5404,12 @@ "@apollo/utils.printwithreducedwhitespace": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", - "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", - "requires": {} + "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==" }, "@apollo/utils.removealiases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", - "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", - "requires": {} + "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==" }, "@apollo/utils.sortast": { "version": "2.0.1", @@ -5426,8 +5422,7 @@ "@apollo/utils.stripsensitiveliterals": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", - "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", - "requires": {} + "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==" }, "@apollo/utils.usagereporting": { "version": "2.1.0", @@ -5590,8 +5585,7 @@ "@graphql-typed-document-node/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "requires": {} + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==" }, "@humanwhocodes/config-array": { "version": "0.11.11", @@ -5721,8 +5715,7 @@ "@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "requires": {} + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==" }, "@redis/client": { "version": "1.5.9", @@ -5737,26 +5730,22 @@ "@redis/graph": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "requires": {} + "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==" }, "@redis/json": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", - "requires": {} + "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==" }, "@redis/search": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "requires": {} + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==" }, "@redis/time-series": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==" }, "@types/body-parser": { "version": "1.19.2", @@ -5930,8 +5919,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", diff --git a/src/graphql/package.json b/services/graphql/package.json similarity index 100% rename from src/graphql/package.json rename to services/graphql/package.json diff --git a/src/graphql/lib/config.js b/services/graphql/src/config.js similarity index 94% rename from src/graphql/lib/config.js rename to services/graphql/src/config.js index 9c643049..ef2b5b27 100644 --- a/src/graphql/lib/config.js +++ b/services/graphql/src/config.js @@ -1,6 +1,6 @@ const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const defaultConfig = require('../config/default.json'); const copyConfig = JSON.parse(JSON.stringify(config)); diff --git a/src/graphql/lib/controllers/cron/metrics.js b/services/graphql/src/controllers/cron/metrics.js similarity index 60% rename from src/graphql/lib/controllers/cron/metrics.js rename to services/graphql/src/controllers/cron/metrics.js index 02dc4d45..fa168572 100644 --- a/src/graphql/lib/controllers/cron/metrics.js +++ b/services/graphql/src/controllers/cron/metrics.js @@ -1,5 +1,5 @@ const Cron = require('../../cron'); -const logger = require('../../logger'); +const logger = require('../../logger/appLogger'); const { setMetrics } = require('../metrics'); @@ -10,9 +10,9 @@ const { setMetrics } = require('../metrics'); */ async function task() { await setMetrics(); - logger.info('[cron dailyMetrics]: metrics is updated'); + logger.info('[cron][metrics]: metrics is updated'); } -const cron = new Cron('dailyMetrics', '0 0 0 * * *', task); +const cron = new Cron('metrics', '0 0 0 * * *', task); module.exports = cron; diff --git a/src/graphql/lib/controllers/health.js b/services/graphql/src/controllers/health.js similarity index 100% rename from src/graphql/lib/controllers/health.js rename to services/graphql/src/controllers/health.js diff --git a/src/graphql/lib/controllers/metrics.js b/services/graphql/src/controllers/metrics.js similarity index 76% rename from src/graphql/lib/controllers/metrics.js rename to services/graphql/src/controllers/metrics.js index 7185ed38..3745db46 100644 --- a/src/graphql/lib/controllers/metrics.js +++ b/services/graphql/src/controllers/metrics.js @@ -1,4 +1,5 @@ -const logger = require('../logger'); +const { elasticsearch } = require('config'); +const logger = require('../logger/appLogger'); const { getMetrics } = require('../services/elastic'); @@ -18,7 +19,7 @@ let metrics = { * @returns {Promise} */ async function setMetrics() { - metrics = await getMetrics('unpaywall'); + metrics = await getMetrics(elasticsearch.indexBase); logger.info('[metrics] metrics is updated'); } diff --git a/src/graphql/lib/cron.js b/services/graphql/src/cron.js similarity index 73% rename from src/graphql/lib/cron.js rename to services/graphql/src/cron.js index 0c5f79e0..f0a782a3 100644 --- a/src/graphql/lib/cron.js +++ b/services/graphql/src/cron.js @@ -1,6 +1,7 @@ const { CronJob } = require('cron'); +const { timezone } = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); /** * Class cron which overloads the node-cron library by adding features. @@ -19,7 +20,7 @@ class Cron { this.schedule = schedule; this.task = task; this.active = false; - this.process = new CronJob(schedule, this.task, null, false, 'Europe/Paris'); + this.process = new CronJob(schedule, this.task, null, false, timezone); } /** @@ -43,8 +44,8 @@ class Cron { setTask(task) { this.process.stop(); this.task = task; - logger.info(`[cron: ${this.name}] config - task updated`); - this.process = new CronJob(this.schedule, this.task, null, false, 'Europe/Paris'); + logger.info(`[cron][${this.name}]: config - task updated`); + this.process = new CronJob(this.schedule, this.task, null, false, timezone); if (this.active) this.process.start(); } @@ -56,10 +57,10 @@ class Cron { setSchedule(schedule) { this.process.stop(); this.schedule = schedule; - logger.info(`[cron: ${this.name}] schedule is updated [${this.schedule}]`); + logger.info(`[cron][${this.name}]: schedule is updated [${this.schedule}]`); this.process = new CronJob(this.schedule, async () => { await this.task(); - }, null, false, 'Europe/Paris'); + }, null, false, timezone); if (this.active) this.process.start(); } @@ -69,10 +70,10 @@ class Cron { start() { try { this.process.start(); - logger.info(`[cron: ${this.name}] cron process is started`); - logger.info(`[cron: ${this.name}] schedule: [${this.schedule}]`); + logger.info(`[cron][${this.name}]: cron process is started`); + logger.info(`[cron][${this.name}]: schedule: [${this.schedule}]`); } catch (err) { - logger.error(`[cron ${this.name}] Cannot start cron process`, err); + logger.error(`[cron][${this.name}]: Cannot start cron process`, err); return; } this.active = true; @@ -84,9 +85,9 @@ class Cron { stop() { try { this.process.stop(); - logger.info(`[cron: ${this.name}] cron process is stopped`); + logger.info(`[cron][${this.name}]: cron process is stopped`); } catch (err) { - logger.error(`[cron ${this.name}] Cannot stop cron process`, err); + logger.error(`[cron][${this.name}]: Cannot stop cron process`, err); return; } this.active = false; diff --git a/src/graphql/lib/morgan.js b/services/graphql/src/logger/access.js similarity index 71% rename from src/graphql/lib/morgan.js rename to services/graphql/src/logger/access.js index eb5af2b7..c7b13222 100644 --- a/src/graphql/lib/morgan.js +++ b/services/graphql/src/logger/access.js @@ -3,14 +3,14 @@ const fs = require('fs-extra'); const rfs = require('rotating-file-stream'); const path = require('path'); const { format } = require('date-fns'); -const { accessLogRotate } = require('config'); +const { nodeEnv, paths, accessLogRotate } = require('config'); -const accessLogDir = path.resolve(__dirname, '..', 'log', 'access'); +const isProd = (nodeEnv === 'production'); /** * Get the name of access file. * - * @param {number} date - Date in minisecond + * @param {number} date - Date in milliseconds * * @returns {string} Name of access file. */ @@ -24,10 +24,10 @@ let accessLogStream; if (accessLogRotate) { accessLogStream = rfs.createStream(logFilename, { interval: '1d', // rotate daily - path: accessLogDir, + path: paths.log.accessDir, }); } else { - accessLogStream = fs.createWriteStream(path.resolve(accessLogDir, 'access.log'), { flags: 'a+' }); + accessLogStream = fs.createWriteStream(path.resolve(paths.log.accessDir, 'access.log'), { flags: 'a+' }); } morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); @@ -42,4 +42,4 @@ morgan.token('countDOI', (req) => { return '-'; }); -module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":response-time" ":user-agent" ":countDOI"', { stream: accessLogStream }); +module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":response-time" ":user-agent" ":countDOI"', { stream: isProd ? accessLogStream : process.stdout }); diff --git a/src/mail/lib/logger.js b/services/graphql/src/logger/appLogger.js similarity index 91% rename from src/mail/lib/logger.js rename to services/graphql/src/logger/appLogger.js index d2d91902..e83d3544 100644 --- a/src/mail/lib/logger.js +++ b/services/graphql/src/logger/appLogger.js @@ -1,5 +1,5 @@ const path = require('path'); -const { nodeEnv } = require('config'); +const { nodeEnv, paths } = require('config'); const isProd = (nodeEnv === 'production'); @@ -22,7 +22,7 @@ const { const processConfiguration = [ new transports.DailyRotateFile({ name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), + filename: path.resolve(paths.log.applicationDir, '%DATE%.log'), datePattern: 'yyyy-MM-DD', level: 'info', }), diff --git a/services/graphql/src/logger/healthcheck.js b/services/graphql/src/logger/healthcheck.js new file mode 100644 index 00000000..f56e9d9f --- /dev/null +++ b/services/graphql/src/logger/healthcheck.js @@ -0,0 +1,41 @@ +const morgan = require('morgan'); +const fs = require('fs-extra'); +const rfs = require('rotating-file-stream'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths, healthcheckLogRotate } = require('config'); + +/** + * Get the name of healthcheck log file. + * + * @param {number} date - Date in milliseconds + * + * @returns {string} Name of healthcheck log file. + */ +function logFilename(date) { + if (!date) return 'healthcheck.log'; + return `${format(new Date(date) - 1000 * 60 * 60 * 24, 'yyyy-MM-dd')}-healthcheck.log`; +} + +let healthCheckLogStream; + +if (healthcheckLogRotate) { + healthCheckLogStream = rfs.createStream(logFilename, { + interval: '1d', // rotate daily + path: paths.log.healthCheckDir, + }); +} else { + healthCheckLogStream = fs.createWriteStream(path.resolve(paths.log.healthCheckDir, 'healthcheck.log'), { flags: 'a+' }); +} + +morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); + +morgan.token('user', (req) => { + if (req.user) return req.user; + return '-'; +}); + +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: healthCheckLogStream }, +); diff --git a/src/graphql/lib/resolvers/getByDOI.js b/services/graphql/src/middlewares/apikey.js similarity index 63% rename from src/graphql/lib/resolvers/getByDOI.js rename to services/graphql/src/middlewares/apikey.js index d9e1f9f8..f8fac8ea 100644 --- a/src/graphql/lib/resolvers/getByDOI.js +++ b/services/graphql/src/middlewares/apikey.js @@ -1,16 +1,9 @@ -/* eslint-disable guard-for-in */ -/* eslint-disable no-restricted-syntax */ const graphqlFields = require('graphql-fields'); - -const config = require('config'); - +const logger = require('../logger/appLogger'); const { redisClient } = require('../services/redis'); -const { elasticClient } = require('../services/elastic'); - -const logger = require('../logger'); /** - * Flatten nested properties of an object by seperating keys with dots. + * Flatten nested properties of an object by separating keys with dots. * Example: { foo: { bar: 'foo' } } => { 'foo.bar': 'foo' } * * @param {Object} obj - Object need to be flatten. @@ -39,8 +32,14 @@ function flatten(obj) { return flattened; } -async function GetByDOI(parent, args, contextValue, info) { - const apikey = contextValue.get('X-API-KEY'); +/** + * + * @param {*} req - Request + * @param {*} args - Graphql args + * @param {*} info - Info about graphql + */ +async function checkApikey(req, args, info) { + const apikey = req.get('X-API-KEY'); if (!apikey) { throw Error('Not authorized'); @@ -80,13 +79,7 @@ async function GetByDOI(parent, args, contextValue, info) { } } - let index = contextValue?.get('index'); - - const { attributes } = contextValue; - - if (!index) { - index = config.get('elasticsearch.indexAlias'); - } + const { attributes } = req; if (!attributes.includes('*')) { const test = graphqlFields(info); @@ -98,39 +91,6 @@ async function GetByDOI(parent, args, contextValue, info) { } }); } - - const dois = []; - - // Normalize request - args.dois.forEach((doi) => { - dois.push(doi.toLowerCase()); - }); - - const filter = [{ terms: { doi: dois } }]; - - const query = { - bool: { - filter, - }, - }; - - let res; - try { - res = await elasticClient.search({ - index, - size: dois.length || 1000, - body: { - query, - _source: attributes, - }, - - }); - } catch (err) { - logger.error('[elastic] Cannot request elastic', err); - return null; - } - // eslint-disable-next-line no-underscore-dangle - return res.body.hits.hits.map((hit) => hit._source); } -module.exports = GetByDOI; +module.exports = checkApikey; diff --git a/src/graphql/lib/middlewares/auth.js b/services/graphql/src/middlewares/auth.js similarity index 96% rename from src/graphql/lib/middlewares/auth.js rename to services/graphql/src/middlewares/auth.js index d6b1a666..0886980f 100644 --- a/src/graphql/lib/middlewares/auth.js +++ b/services/graphql/src/middlewares/auth.js @@ -1,6 +1,6 @@ const { redisClient } = require('../services/redis'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); /** * Authentication middleware that checks if the content of the x-api-key header diff --git a/services/graphql/src/middlewares/countDOI.js b/services/graphql/src/middlewares/countDOI.js new file mode 100644 index 00000000..767a0418 --- /dev/null +++ b/services/graphql/src/middlewares/countDOI.js @@ -0,0 +1,22 @@ +/* eslint-disable no-param-reassign */ + +const countDOIPlugin = { + requestDidStart() { + return { + executionDidStart() { + return { + willResolveField({ args, contextValue }) { + const countDOI = args?.dois?.length; + + if (!countDOI) { return; } + + contextValue.res.req.countDOI = countDOI; + contextValue.countDOI = countDOI; + }, + }; + }, + }; + }, +}; + +module.exports = countDOIPlugin; diff --git a/services/graphql/src/models/index.js b/services/graphql/src/models/index.js new file mode 100644 index 00000000..e2efe0ca --- /dev/null +++ b/services/graphql/src/models/index.js @@ -0,0 +1,23 @@ +const unpaywall = require('./unpaywall'); +const unpaywallHistory = require('./unpaywallHistory'); +const oaLocation = require('./oalocation'); +const zauthors = require('./zauthors'); +const metrics = require('./metrics'); + +const typeDefs = `#graphql + ${unpaywall} + ${unpaywallHistory} + ${oaLocation} + ${zauthors} + ${metrics} + + type Query { + unpaywall(dois: [ID!]!): [UnpaywallType] + unpaywallHistory(dois: [ID!]!, date: String): [unpaywallHistoryType] + GetByDOI(dois: [ID!]!): [UnpaywallType] + metrics: MetricsType + dailyMetrics: MetricsType + } +`; + +module.exports = typeDefs; diff --git a/src/graphql/lib/models/metrics.js b/services/graphql/src/models/metrics.js similarity index 100% rename from src/graphql/lib/models/metrics.js rename to services/graphql/src/models/metrics.js diff --git a/src/graphql/lib/models/oalocation.js b/services/graphql/src/models/oalocation.js similarity index 100% rename from src/graphql/lib/models/oalocation.js rename to services/graphql/src/models/oalocation.js diff --git a/src/graphql/lib/models/unpaywall.js b/services/graphql/src/models/unpaywall.js similarity index 100% rename from src/graphql/lib/models/unpaywall.js rename to services/graphql/src/models/unpaywall.js diff --git a/services/graphql/src/models/unpaywallHistory.js b/services/graphql/src/models/unpaywallHistory.js new file mode 100644 index 00000000..07e9b457 --- /dev/null +++ b/services/graphql/src/models/unpaywallHistory.js @@ -0,0 +1,30 @@ +const unpaywallHistoryType = ` + type unpaywallHistoryType { + doi: ID + best_oa_location: OaLocationType + first_oa_location: OaLocationType + data_standard: Int + doi_url: String + genre: String + is_paratext: Boolean + is_oa: Boolean + has_repository_copy: Boolean + journal_is_in_doaj: Boolean + journal_is_oa: Boolean + journal_issns: String + journal_issn_l: String + journal_name: String + oa_locations: [OaLocationType] + oa_status: String + published_date: String + publisher: String + title: String + updated: String + year: String + z_authors: [ZAuthorsType] + referencedAt: String + endValidity: String + } +`; + +module.exports = unpaywallHistoryType; diff --git a/src/graphql/lib/models/zauthors.js b/services/graphql/src/models/zauthors.js similarity index 100% rename from src/graphql/lib/models/zauthors.js rename to services/graphql/src/models/zauthors.js diff --git a/src/graphql/lib/ping.js b/services/graphql/src/ping.js similarity index 100% rename from src/graphql/lib/ping.js rename to services/graphql/src/ping.js diff --git a/src/graphql/lib/resolvers/dailyMetrics.js b/services/graphql/src/resolvers/dailyMetrics.js similarity index 100% rename from src/graphql/lib/resolvers/dailyMetrics.js rename to services/graphql/src/resolvers/dailyMetrics.js diff --git a/src/graphql/lib/resolvers/index.js b/services/graphql/src/resolvers/index.js similarity index 70% rename from src/graphql/lib/resolvers/index.js rename to services/graphql/src/resolvers/index.js index 0fd2facb..155554e8 100644 --- a/src/graphql/lib/resolvers/index.js +++ b/services/graphql/src/resolvers/index.js @@ -1,12 +1,13 @@ const unpaywall = require('./unpaywall'); -const GetByDOI = require('./getByDOI'); +const unpaywallHistory = require('./unpaywallHistory'); const metrics = require('./metrics'); const dailyMetrics = require('./dailyMetrics'); const resolvers = { Query: { unpaywall, - GetByDOI, + unpaywallHistory, + GetByDOI: unpaywall, metrics, dailyMetrics, }, diff --git a/src/graphql/lib/resolvers/metrics.js b/services/graphql/src/resolvers/metrics.js similarity index 57% rename from src/graphql/lib/resolvers/metrics.js rename to services/graphql/src/resolvers/metrics.js index c9a1c05f..6f600ede 100644 --- a/src/graphql/lib/resolvers/metrics.js +++ b/services/graphql/src/resolvers/metrics.js @@ -1,7 +1,14 @@ +const { elasticsearch } = require('config'); + const { getMetrics } = require('../services/elastic'); const metrics = async (parent, args, req) => { - const index = req?.get('index'); + let index = req?.get('index'); + + if (!index) { + index = elasticsearch.indexBase; + } + const res = await getMetrics(index); return res; }; diff --git a/services/graphql/src/resolvers/unpaywall.js b/services/graphql/src/resolvers/unpaywall.js new file mode 100644 index 00000000..8c18ef5b --- /dev/null +++ b/services/graphql/src/resolvers/unpaywall.js @@ -0,0 +1,36 @@ +const { elasticsearch } = require('config'); + +const checkApikey = require('../middlewares/apikey'); +const { search } = require('../services/elastic'); + +async function unpaywall(parent, args, req, info) { + await checkApikey(req, args, info); + + const { attributes } = req; + let index = req?.get('index'); + + if (!index) { + index = elasticsearch.indexBase; + } + + // Normalize request + const dois = []; + args.dois.forEach((doi) => { + dois.push(doi.toLowerCase()); + }); + + const body = { + query: { + bool: { + filter: [ + { terms: { doi: dois } }, + ], + }, + }, + _source: attributes, + }; + + return search(index, dois.length, body); +} + +module.exports = unpaywall; diff --git a/services/graphql/src/resolvers/unpaywallHistory.js b/services/graphql/src/resolvers/unpaywallHistory.js new file mode 100644 index 00000000..5b759a9f --- /dev/null +++ b/services/graphql/src/resolvers/unpaywallHistory.js @@ -0,0 +1,124 @@ +const { elasticsearch } = require('config'); +const checkApikey = require('../middlewares/apikey'); +const { search } = require('../services/elastic'); +const logger = require('../logger/appLogger'); + +async function unpaywallHistory(parent, args, req, info) { + // TODO perf: use one requet than two + // TODO add limit for max DOI requested + + await checkApikey(req, args, info); + + const { attributes } = req; + let index = req?.get('index'); + + if (!index) { index = elasticsearch.indexHistory; } + + const dois = []; + + // Normalize request + args.dois.forEach((doi) => { + dois.push(doi.toLowerCase()); + }); + + const body = { + query: { + bool: { + filter: [ + { + terms: { doi: dois }, + }, + ], + }, + }, + sort: { updated: 'desc' }, + _source: attributes, + }; + + const cloneBody = JSON.parse(JSON.stringify(body)); + + const { date } = args; + if (date) { + body.query.bool.filter.push( + { + range: { + endValidity: { + gte: date, + }, + }, + }, + { + range: { + updated: { + lte: date, + }, + }, + }, + ); + body.collapse = { + field: 'doi', + }; + } + + let historyRes = []; + try { + // TODO use scroll + historyRes = await search(index, 1000, body); + } catch (err) { + logger.error(`[apollo]: Cannot search document in index [${index}]`, err); + throw err; + } + + const DOIInResponse = new Set(historyRes.map((res) => res.doi)); + const DOINotInResponse = dois.filter((doi) => !DOIInResponse.has(doi)); + + // Return the complete history with the current data + if (!date) { + let baseRes; + // get current data + try { + baseRes = await search(elasticsearch.indexBase, dois.length, cloneBody); + } catch (err) { + logger.error(`[apollo]: Cannot search document in index [${elasticsearch.indexBase}]`, err); + throw err; + } + if (baseRes.length > 0) { + historyRes.unshift(baseRes[0]); + } + } + + // if we have no data in history, try to search in index_base + if (date && DOINotInResponse.length !== 0) { + cloneBody.query.bool.filter.push( + { + range: { + updated: { + lt: date, + }, + }, + }, + { + range: { + referencedAt: { + lt: date, + }, + }, + }, + ); + cloneBody.query.bool.filter[0].terms.doi = DOINotInResponse; + let baseRes; + // get current data + try { + baseRes = await search(elasticsearch.indexBase, dois.length, cloneBody); + } catch (err) { + logger.error(`[apollo]: Cannot search document in index [${elasticsearch.indexBase}]`, err); + throw err; + } + + return [...baseRes, ...historyRes]; + } + + return historyRes; +} + +module.exports = unpaywallHistory; diff --git a/services/graphql/src/routers/healthcheck.js b/services/graphql/src/routers/healthcheck.js new file mode 100644 index 00000000..5eb10fe8 --- /dev/null +++ b/services/graphql/src/routers/healthcheck.js @@ -0,0 +1,10 @@ +const router = require('express').Router(); + +const healthCheckLogger = require('../logger/healthcheck'); + +/** + * Route use for healthcheck. + */ +router.get('/healthcheck', healthCheckLogger, (req, res, next) => res.status(204).end()); + +module.exports = router; diff --git a/services/graphql/src/routers/openapi.js b/services/graphql/src/routers/openapi.js new file mode 100644 index 00000000..bdf85c7d --- /dev/null +++ b/services/graphql/src/routers/openapi.js @@ -0,0 +1,9 @@ +const router = require('express').Router(); +const path = require('path'); + +/** + * Route that give the openapi.json file. + */ +router.get('/openapi.yml', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'openapi.yml'))); + +module.exports = router; diff --git a/src/graphql/lib/routers/ping.js b/services/graphql/src/routers/ping.js similarity index 100% rename from src/graphql/lib/routers/ping.js rename to services/graphql/src/routers/ping.js diff --git a/src/graphql/lib/services/elastic.js b/services/graphql/src/services/elastic.js similarity index 67% rename from src/graphql/lib/services/elastic.js rename to services/graphql/src/services/elastic.js index c493010b..03842916 100644 --- a/src/graphql/lib/services/elastic.js +++ b/services/graphql/src/services/elastic.js @@ -3,9 +3,8 @@ const path = require('path'); const { Client } = require('@elastic/elasticsearch'); const { URL } = require('url'); -const { elasticsearch } = require('config'); -const { nodeEnv } = require('config'); -const logger = require('../logger'); +const { elasticsearch, nodeEnv } = require('config'); +const logger = require('../logger/appLogger'); const isProd = (nodeEnv === 'production'); @@ -17,7 +16,7 @@ if (isProd) { try { ca = fs.readFileSync(caPath, 'utf8'); } catch (err) { - logger.error(`[elastic] Cannot read elastic certificate file in [${caPath}]`, err); + logger.error(`[elastic]: Cannot read elastic certificate file in [${caPath}]`, err); } ssl = { ca, @@ -34,7 +33,7 @@ const elasticClient = new Client({ }, ssl, }, - requestTimeout: 2000, + requestTimeout: 5000, }); /** @@ -47,11 +46,11 @@ async function pingElastic() { try { elasticStatus = await elasticClient.ping(); } catch (err) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port}`, err); + logger.error(`[elastic]: Cannot ping ${elasticsearch.host}:${elasticsearch.port}`, err); return false; } if (elasticStatus?.statusCode !== 200) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port} - ${elasticStatus?.statusCode}`); + logger.error(`[elastic]: Cannot ping ${elasticsearch.host}:${elasticsearch.port} - ${elasticStatus?.statusCode}`); return false; } return true; @@ -67,19 +66,19 @@ async function pingElastic() { * count of oa_status: 'green' * count of oa_status: 'closed' * - * @param {string} index elastic index to request + * @param {string} indexName - Index name * * @returns {Promise} metrics */ -async function getMetrics(index) { +async function getMetrics(indexName) { let res; try { res = await elasticClient.count({ - index, + index: indexName, }, { requestTimeout: '600s' }); } catch (err) { - logger.error(`[elastic] Cannot count on index [${index}]`, err); + logger.error(`[elastic]: Cannot count on index [${indexName}]`, err); return null; } @@ -87,7 +86,7 @@ async function getMetrics(index) { try { res = await elasticClient.search({ - index, + index: indexName, body: { aggs: { isOA: { @@ -124,7 +123,7 @@ async function getMetrics(index) { }, }, { requestTimeout: '600s' }); } catch (err) { - logger.error('[elastic] Cannot get unpaywall metric', err); + logger.error('[elastic]: Cannot get unpaywall metric', err); return null; } @@ -147,8 +146,33 @@ async function getMetrics(index) { }; } +/** + * Search unpaywall document in elastic + * @param {string} indexName - Index name + * @param {number} size - Size of elements requested + * @param {Object} body - Config of elastic request + * + * @returns {Object} - Elastic response + */ +async function search(indexName, size, body) { + let res; + try { + res = await elasticClient.search({ + index: indexName, + size, + body, + }); + } catch (err) { + logger.error(`[elastic]: Cannot request elastic in index [${indexName}]`, err); + throw err; + } + // eslint-disable-next-line no-underscore-dangle + return res.body.hits.hits.map((hit) => hit._source); +} + module.exports = { elasticClient, pingElastic, getMetrics, + search, }; diff --git a/src/graphql/lib/services/redis.js b/services/graphql/src/services/redis.js similarity index 50% rename from src/graphql/lib/services/redis.js rename to services/graphql/src/services/redis.js index 6bd904a6..6b0d65cc 100644 --- a/src/graphql/lib/services/redis.js +++ b/services/graphql/src/services/redis.js @@ -1,15 +1,15 @@ -const redis = require('redis'); +const { createClient } = require('redis'); const util = require('util'); -const config = require('config'); -const logger = require('../logger'); +const { redis } = require('config'); +const logger = require('../logger/appLogger'); -const redisClient = redis.createClient({ +const redisClient = createClient({ legacyMode: true, socket: { - host: config.get('redis.host'), - port: config.get('redis.port'), + host: redis.host, + port: redis.port, }, - password: config.get('redis.password'), + password: redis.password, }); redisClient.get = util.promisify(redisClient.get); @@ -24,7 +24,7 @@ async function pingRedis() { try { await redisClient.ping(); } catch (err) { - logger.error(`[redis] Cannot ping ${config.get('redis.host')}:${config.get('redis.port')}`, err); + logger.error(`[redis] Cannot ping ${redis.host}:${redis.port}`, err); return false; } return true; @@ -34,10 +34,10 @@ async function startConnectionRedis() { try { await redisClient.connect(); } catch (err) { - logger.error(`[redis] Cannot start connection ${config.get('redis.host')}:${config.get('redis.port')}`, err); + logger.error(`[redis] Cannot start connection ${redis.host}:${redis.port}`, err); return false; } - logger.info(`[redis] connect success ${config.get('redis.host')}:${config.get('redis.port')}`); + logger.info(`[redis] connect success ${redis.host}:${redis.port}`); return true; } diff --git a/src/graphql/test/getGraphqlRequest.js b/services/graphql/test/GetByDOIGet.js similarity index 56% rename from src/graphql/test/getGraphqlRequest.js rename to services/graphql/test/GetByDOIGet.js index c069debb..f22ec59d 100644 --- a/src/graphql/test/getGraphqlRequest.js +++ b/services/graphql/test/GetByDOIGet.js @@ -20,27 +20,26 @@ const { chai.use(chaiHttp); const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; -const doi1 = '10.1186/s40510-015-0109-6'; // ligne 1 of fake1.jsonl -const doi2 = '10.14393/ufu.di.2018.728'; // line 35 of fake1.jsonl +const doi1 = '1'; +const doi2 = '6'; -describe('test graphqlRequest', () => { +describe('Test GET GetByDOI resolver', () => { before(async function () { this.timeout(30000); await ping(); await deleteAllAPIKey(); await loadDevAPIKey(); - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); - await insertDataUnpaywall(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); }); describe('GET: get unpaywall data with one DOI', () => { - it(`Should get unpaywall data - {GetByDOI(dois:["${doi1}"]){doi, is_oa}}`, async () => { + it(`Should get unpaywall data - { GetByDOI(dois: ["${doi1}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{GetByDOI(dois:["${doi1}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: `{ GetByDOI(dois: ["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -50,12 +49,11 @@ describe('test graphqlRequest', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it('It should get empty tab - {GetByDOI(dois:["Coin Coin"]){doi, is_oa}}', async () => { + it('It should get empty tab - { GetByDOI(dois: ["Coin Coin"]) { doi, is_oa } }', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: '{GetByDOI(dois:["Coin Coin"]){doi, is_oa}}' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: '{ GetByDOI(dois: ["Coin Coin"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -64,13 +62,12 @@ describe('test graphqlRequest', () => { }); }); - describe('GET: get unpaywall data with one DOI nor normalized', () => { - it(`Ghould get unpaywall data - {GetByDOI(dois:["${doi1.toUpperCase()}"]){doi, is_oa}}`, async () => { + describe('GET: get unpaywall data with one DOI not normalized', () => { + it(`Ghould get unpaywall data - { GetByDOI(dois: ["${doi1.toUpperCase()}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{GetByDOI(dois:["${doi1.toUpperCase()}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: `{ GetByDOI(dois: ["${doi1.toUpperCase()}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -82,12 +79,11 @@ describe('test graphqlRequest', () => { }); describe('GET: get unpaywall data with two DOI', () => { - it(`should get unpaywall data - {GetByDOI(dois:["${doi1}","${doi2}"]){doi, is_oa}}`, async () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1}","${doi2}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{GetByDOI(dois:["${doi1}","${doi2}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: `{ GetByDOI(dois: ["${doi1}","${doi2}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -96,12 +92,11 @@ describe('test graphqlRequest', () => { expect(data[1]).have.property('is_oa').eq(false); }); - it(`should get unpaywall data - {GetByDOI(dois:["${doi1}","Coin Coin"]){doi, is_oa}}`, async () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1}","Coin Coin"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{GetByDOI(dois:["${doi1}","Coin Coin"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: `{ GetByDOI(dois: ["${doi1}","Coin Coin"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -109,12 +104,11 @@ describe('test graphqlRequest', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it('It should get empty tab - {GetByDOI(dois:["Coin Coin","Coin Coin2"]){doi, is_oa}}', async () => { + it('It should get empty tab - { GetByDOI(dois: ["Coin Coin","Coin Coin2"]) { doi, is_oa } }', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: '{GetByDOI(dois:["Coin Coin","Coin Coin2"]){doi, is_oa}}' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: '{ GetByDOI(dois: ["Coin Coin","Coin Coin2"]) { doi, is_oa} }' }) + .set('x-api-key', 'user'); expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; diff --git a/src/graphql/test/post1GraphqlRequest.js b/services/graphql/test/GetByDOIPost1.js similarity index 56% rename from src/graphql/test/post1GraphqlRequest.js rename to services/graphql/test/GetByDOIPost1.js index 7b68e122..b8198706 100644 --- a/src/graphql/test/post1GraphqlRequest.js +++ b/services/graphql/test/GetByDOIPost1.js @@ -20,27 +20,26 @@ const { chai.use(chaiHttp); const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; -const doi1 = '10.1186/s40510-015-0109-6'; // ligne 1 of fake1.jsonl -const doi2 = '10.14393/ufu.di.2018.728'; // line 35 of fake1.jsonl +const doi1 = '1'; +const doi2 = '6'; -describe('test graphqlRequest POST', () => { +describe('Test POST 1 GetByDOI resolver', () => { before(async function () { this.timeout(30000); await ping(); await deleteAllAPIKey(); await loadDevAPIKey(); - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); - await insertDataUnpaywall(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); }); describe('POST: get unpaywall data with one DOI', () => { - it(`should get unpaywall data - {GetByDOI(dois:["${doi1}"]){doi, is_oa}}`, async () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: `{GetByDOI(dois:["${doi1}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: `{ GetByDOI(dois: ["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -50,12 +49,12 @@ describe('test graphqlRequest POST', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it('It should get empty tab - {GetByDOI(dois:["Coin Coin"]){doi, is_oa}}', async () => { + it('It should get empty tab - { GetByDOI(dois: ["Coin Coin"]) { doi, is_oa } }', async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: '{GetByDOI(dois:["Coin Coin"]){doi, is_oa}}' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: '{ GetByDOI(dois: ["Coin Coin"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -64,13 +63,12 @@ describe('test graphqlRequest POST', () => { }); }); - describe('POST: get unpaywall data with one DOI nor normalized', () => { - it(`should get unpaywall data - {GetByDOI(dois:["${doi1.toUpperCase()}"]){doi, is_oa}}`, async () => { + describe('POST: get unpaywall data with one DOI not normalized', () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1.toUpperCase()}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: `{GetByDOI(dois:["${doi1.toUpperCase()}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: `{ GetByDOI(dois: ["${doi1.toUpperCase()}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -82,12 +80,12 @@ describe('test graphqlRequest POST', () => { }); describe('POST: get unpaywall data with two DOI', () => { - it(`should get unpaywall data - {GetByDOI(dois:["${doi1}","${doi2}"]){doi, is_oa}}`, async () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1}","${doi2}"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: `{GetByDOI(dois:["${doi1}","${doi2}"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: `{ GetByDOI(dois: ["${doi1}","${doi2}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -96,12 +94,12 @@ describe('test graphqlRequest POST', () => { expect(data[1]).have.property('is_oa').eq(false); }); - it(`should get unpaywall data - {GetByDOI(dois:["${doi1}","Coin Coin"]){doi, is_oa}}`, async () => { + it(`should get unpaywall data - { GetByDOI(dois: ["${doi1}","Coin Coin"]) { doi, is_oa } }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: `{GetByDOI(dois:["${doi1}","Coin Coin"]){doi, is_oa}}` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: `{ GetByDOI(dois: ["${doi1}","Coin Coin"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; @@ -109,12 +107,12 @@ describe('test graphqlRequest POST', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it('It should get empty tab - {GetByDOI(dois:["Coin Coin","Coin Coin2"]){doi, is_oa}}', async () => { + it('It should get empty tab - { GetByDOI(dois: ["Coin Coin","Coin Coin2"]) { doi, is_oa } }', async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: '{GetByDOI(dois:["Coin Coin","Coin Coin2"]){doi, is_oa}}' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .send({ query: '{ GetByDOI(dois: ["Coin Coin","Coin Coin2"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + expect(res).have.status(200); const data = res?.body?.data?.GetByDOI; diff --git a/src/graphql/test/post2GraphqlRequest.js b/services/graphql/test/GetByDOIPost2.js similarity index 57% rename from src/graphql/test/post2GraphqlRequest.js rename to services/graphql/test/GetByDOIPost2.js index eecf984d..d454849a 100644 --- a/src/graphql/test/post2GraphqlRequest.js +++ b/services/graphql/test/GetByDOIPost2.js @@ -20,32 +20,31 @@ const { chai.use(chaiHttp); const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; -const doi1 = '10.1186/s40510-015-0109-6'; // ligne 1 of fake1.jsonl -const doi2 = '10.14393/ufu.di.2018.728'; // line 35 of fake1.jsonl +const doi1 = '1'; +const doi2 = '6'; -describe('test graphqlRequest POST', () => { +describe('Test POST 2 GetByDOI resolver', () => { before(async function () { this.timeout(30000); await ping(); await deleteAllAPIKey(); await loadDevAPIKey(); - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); - await insertDataUnpaywall(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); }); describe('POST: get unpaywall data with one DOI', () => { - it(`should get unpaywall data - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variables : { dois: [${doi1}] }`, async () => { + it(`should get unpaywall data - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variables : { dois: [${doi1}] }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: [doi1], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -56,17 +55,16 @@ describe('test graphqlRequest POST', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it('It should get empty tab - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variable : { dois: [\'Coin coin\'] }', async () => { + it('It should get empty tab - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variable : { dois: [\'Coin coin\'] }', async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: ['Coin coin'], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -76,18 +74,17 @@ describe('test graphqlRequest POST', () => { }); }); - describe('POST: get unpaywall data with one DOI nor normalized', () => { - it(`should get unpaywall data - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variables : { dois : ['${doi1.toUpperCase()}'] }`, async () => { + describe('POST: get unpaywall data with one DOI not normalized', () => { + it(`should get unpaywall data - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variables : { dois : ['${doi1.toUpperCase()}'] }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: [doi1.toUpperCase()], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -99,17 +96,16 @@ describe('test graphqlRequest POST', () => { }); describe('POST: get unpaywall data with two DOI', () => { - it(`should get unpaywall data - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variables : { dois : ${[doi1, doi2]} }`, async () => { + it(`should get unpaywall data - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variables : { dois : ${[doi1, doi2]} }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: [doi1, doi2], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -119,17 +115,16 @@ describe('test graphqlRequest POST', () => { expect(data[1]).have.property('is_oa').eq(false); }); - it(`should get unpaywall data - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variables : { dois : ${[doi1, 'Coin coin']} }`, async () => { + it(`should get unpaywall data - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variables : { dois : ${[doi1, 'Coin coin']} }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: [doi1, 'Coin Coin'], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); @@ -138,17 +133,16 @@ describe('test graphqlRequest POST', () => { expect(data[0]).have.property('is_oa').eq(true); }); - it(`It should get empty tab - query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}} - variables : { dois : ${['Coin coin', 'Coin coin2']} }`, async () => { + it(`It should get empty tab - query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } } - variables : { dois : ${['Coin coin', 'Coin coin2']} }`, async () => { const res = await chai.request(graphqlURL) .post('/graphql') - .send({ query: 'query ($dois: [ID!]!) {GetByDOI(dois: $dois) {doi, is_oa}}' }) + .send({ query: 'query ($dois: [ID!]!) { GetByDOI(dois: $dois) { doi, is_oa } }' }) .send({ variables: { dois: ['Coin Coin', 'Coin Coin2'], }, }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); diff --git a/src/graphql/test/auth.js b/services/graphql/test/auth.js similarity index 66% rename from src/graphql/test/auth.js rename to services/graphql/test/auth.js index 042aa9a1..0e1008fa 100644 --- a/src/graphql/test/auth.js +++ b/services/graphql/test/auth.js @@ -21,7 +21,7 @@ chai.use(chaiHttp); const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; -const doi1 = '10.1186/s40510-015-0109-6'; // line 1 of fake1.jsonl +const doi1 = '1'; describe('Test: auth service in graphql service', () => { before(async function () { @@ -29,18 +29,17 @@ describe('Test: auth service in graphql service', () => { await ping(); await deleteAllAPIKey(); await loadDevAPIKey(); - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); - await insertDataUnpaywall(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); }); describe('Test with user API key', () => { it('Should do graphql request', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); expect(res).have.status(200); }); @@ -50,9 +49,8 @@ describe('Test: auth service in graphql service', () => { it('Should do graphql request', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'graphql') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'graphql'); expect(res).have.status(200); }); @@ -62,9 +60,8 @@ describe('Test: auth service in graphql service', () => { it('Should do graphql request', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa, best_oa_location { license } } }` }) - .set('x-api-key', 'restrictedUser') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa, best_oa_location { license } } }` }) + .set('x-api-key', 'restrictedUser'); expect(res).have.status(200); }); @@ -74,8 +71,7 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('Not authorized'); @@ -86,9 +82,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'wrong apikey') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'wrong apikey'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('Not authorized'); @@ -99,9 +94,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'enrich') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'enrich'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('Not authorized'); @@ -112,9 +106,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'update') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'update'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('Not authorized'); @@ -125,9 +118,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa } }` }) - .set('x-api-key', 'notAllowed') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'notAllowed'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('Not authorized'); @@ -138,9 +130,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa, oa_status } }` }) - .set('x-api-key', 'restrictedUser') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa, oa_status } }` }) + .set('x-api-key', 'restrictedUser'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('You don\'t have access to oa_status'); @@ -151,9 +142,8 @@ describe('Test: auth service in graphql service', () => { it('Should return a error message', async () => { const res = await chai.request(graphqlURL) .get('/graphql') - .query({ query: `{ GetByDOI(dois:["${doi1}"]) { doi, is_oa, best_oa_location { license }, first_oa_location { license } } }` }) - .set('x-api-key', 'restrictedUser') - .set('index', 'unpaywall-test'); + .query({ query: `{ unpaywall(dois:["${doi1}"]) { doi, is_oa, best_oa_location { license }, first_oa_location { license } } }` }) + .set('x-api-key', 'restrictedUser'); expect(res).have.status(200); expect(res?.body.errors[0].message).eq('You don\'t have access to first_oa_location.license'); diff --git a/services/graphql/test/mapping/unpaywall.json b/services/graphql/test/mapping/unpaywall.json new file mode 100644 index 00000000..be9f88db --- /dev/null +++ b/services/graphql/test/mapping/unpaywall.json @@ -0,0 +1,227 @@ +{ + "settings": { + "number_of_shards": 3 + }, + "mappings": { + "dynamic_templates": [ + { + "strings_as_keywords": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword" + } + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "best_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "data_standard": { + "type": "long" + }, + "doi": { + "type": "keyword" + }, + "doi_url": { + "type": "keyword" + }, + "first_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "genre": { + "type": "keyword" + }, + "has_repository_copy": { + "type": "boolean" + }, + "is_oa": { + "type": "boolean" + }, + "is_paratext": { + "type": "boolean" + }, + "journal_is_in_doaj": { + "type": "boolean" + }, + "journal_is_oa": { + "type": "boolean" + }, + "journal_issn_l": { + "type": "keyword" + }, + "journal_issns": { + "type": "keyword" + }, + "journal_name": { + "type": "keyword" + }, + "oa_locations": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "oa_status": { + "type": "keyword" + }, + "published_date": { + "type": "date", + "format": "iso8601" + }, + "publisher": { + "type": "keyword" + }, + "referencedAt": { + "type": "date" + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date", + "format": "iso8601" + }, + "year": { + "type": "keyword" + }, + "z_authors": { + "properties": { + "family": { + "type": "keyword" + }, + "given": { + "type": "keyword" + }, + "sequence": { + "type": "keyword" + }, + "ORCID": { + "type": "keyword" + }, + "authenticated-orcid": { + "type": "boolean" + }, + "affiliation": { + "properties": { + "name": { + "type": "keyword" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/services/graphql/test/mapping/unpaywall_history.json b/services/graphql/test/mapping/unpaywall_history.json new file mode 100644 index 00000000..8c11a002 --- /dev/null +++ b/services/graphql/test/mapping/unpaywall_history.json @@ -0,0 +1,233 @@ +{ + "settings": { + "number_of_shards": 3 + }, + "mappings": { + "dynamic_templates": [ + { + "strings_as_keywords": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword" + } + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "best_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "date": { + "type": "date" + }, + "data_standard": { + "type": "long" + }, + "doi": { + "type": "keyword" + }, + "doi_url": { + "type": "keyword" + }, + "endValidity": { + "type": "date" + }, + "first_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "genre": { + "type": "keyword" + }, + "has_repository_copy": { + "type": "boolean" + }, + "is_oa": { + "type": "boolean" + }, + "is_paratext": { + "type": "boolean" + }, + "journal_is_in_doaj": { + "type": "boolean" + }, + "journal_is_oa": { + "type": "boolean" + }, + "journal_issn_l": { + "type": "keyword" + }, + "journal_issns": { + "type": "keyword" + }, + "journal_name": { + "type": "keyword" + }, + "oa_locations": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "oa_status": { + "type": "keyword" + }, + "published_date": { + "type": "date", + "format": "iso8601" + }, + "publisher": { + "type": "keyword" + }, + "referencedAt": { + "type": "date" + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date", + "format": "iso8601" + }, + "year": { + "type": "keyword" + }, + "z_authors": { + "properties": { + "family": { + "type": "keyword" + }, + "given": { + "type": "keyword" + }, + "sequence": { + "type": "keyword" + }, + "ORCID": { + "type": "keyword" + }, + "authenticated-orcid": { + "type": "boolean" + }, + "affiliation": { + "properties": { + "name": { + "type": "keyword" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/graphql/test/metrics.js b/services/graphql/test/metrics.js similarity index 72% rename from src/graphql/test/metrics.js rename to services/graphql/test/metrics.js index 0714db6b..089d55c5 100644 --- a/src/graphql/test/metrics.js +++ b/services/graphql/test/metrics.js @@ -21,15 +21,15 @@ chai.use(chaiHttp); const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; -describe('test graphql metrics request', () => { +describe('Test GET metrics resolver', () => { before(async function () { this.timeout(30000); await deleteAllAPIKey(); await ping(); await loadDevAPIKey(); - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); - await insertDataUnpaywall(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); }); describe('GET: get metrics', () => { @@ -37,33 +37,31 @@ describe('test graphql metrics request', () => { const res = await chai.request(graphqlURL) .get('/graphql') .query({ query: '{ metrics { doi, isOA, goldOA, hybridOA, bronzeOA, greenOA, closedOA } }' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); const metrics = res?.body?.data?.metrics; - expect(metrics).have.property('doi').eq(50); - expect(metrics).have.property('isOA').eq(43); - expect(metrics).have.property('goldOA').eq(17); + expect(metrics).have.property('doi').eq(10); + expect(metrics).have.property('isOA').eq(5); + expect(metrics).have.property('goldOA').eq(1); expect(metrics).have.property('hybridOA').eq(1); - expect(metrics).have.property('bronzeOA').eq(13); - expect(metrics).have.property('greenOA').eq(12); - expect(metrics).have.property('closedOA').eq(7); + expect(metrics).have.property('bronzeOA').eq(1); + expect(metrics).have.property('greenOA').eq(2); + expect(metrics).have.property('closedOA').eq(5); }); }); describe('GET: get metrics', () => { before(async () => { - await deleteIndex('unpaywall-test'); - await createIndex('unpaywall-test', mappingUnpaywall); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); }); it('Should get metrics - { metrics { doi, isOA, goldOA, hybridOA, bronzeOA, greenOA, closedOA } }', async () => { const res = await chai.request(graphqlURL) .get('/graphql') .query({ query: '{ metrics { doi, isOA, goldOA, hybridOA, bronzeOA, greenOA, closedOA } }' }) - .set('x-api-key', 'user') - .set('index', 'unpaywall-test'); + .set('x-api-key', 'user'); expect(res).have.status(200); const metrics = res?.body?.data?.metrics; diff --git a/services/graphql/test/sources/indexBaseData.jsonl b/services/graphql/test/sources/indexBaseData.jsonl new file mode 100644 index 00000000..f52b377f --- /dev/null +++ b/services/graphql/test/sources/indexBaseData.jsonl @@ -0,0 +1,10 @@ +{"doi": "1", "version": 2, "is_oa": true, "oa_status": "green", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2019-01-01T01:00:00.000000" } +{"doi": "2", "version": 1, "is_oa": true, "oa_status": "green", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000"} +{"doi": "3", "version": 1, "is_oa": true, "oa_status": "bronze", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "4", "version": 1, "is_oa": true, "oa_status": "hybrid", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "5", "version": 1, "is_oa": true, "oa_status": "gold", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "6", "version": 1, "is_oa": false, "oa_status": "closed", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "7", "version": 1, "is_oa": false, "oa_status": "closed", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "8", "version": 1, "is_oa": false, "oa_status": "closed", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "9", "version": 1, "is_oa": false, "oa_status": "closed", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } +{"doi": "10", "version": 1, "is_oa": false, "oa_status": "closed", "updated": "2020-01-01T01:00:00.000000", "referencedAt": "2020-01-01T01:00:00.000000" } diff --git a/services/graphql/test/sources/indexHistoryData.jsonl b/services/graphql/test/sources/indexHistoryData.jsonl new file mode 100644 index 00000000..34d29fd3 --- /dev/null +++ b/services/graphql/test/sources/indexHistoryData.jsonl @@ -0,0 +1 @@ +{"doi": "1","version": 1, "is_oa": false, "updated": "2019-01-01T01:00:00.000000", "endValidity": "2020-01-01T01:00:00.000000", "referencedAt": "2019-01-01T01:00:00.000000" } diff --git a/services/graphql/test/unpaywallGet.js b/services/graphql/test/unpaywallGet.js new file mode 100644 index 00000000..2161a394 --- /dev/null +++ b/services/graphql/test/unpaywallGet.js @@ -0,0 +1,127 @@ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const mappingUnpaywall = require('./mapping/unpaywall.json'); + +const { + createIndex, + deleteIndex, + insertDataUnpaywall, +} = require('./utils/elastic'); + +const ping = require('./utils/ping'); + +const { + loadDevAPIKey, + deleteAllAPIKey, +} = require('./utils/apikey'); + +chai.use(chaiHttp); + +const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; +const doi1 = '1'; +const doi2 = '6'; + +describe('Test GET unpaywall resolver', () => { + before(async function () { + this.timeout(30000); + await ping(); + await deleteAllAPIKey(); + await loadDevAPIKey(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); + }); + + describe('GET: get unpaywall data with one DOI', () => { + it(`Should get unpaywall data - {unpaywall(dois:["${doi1}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: `{unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it('It should get empty tab - {unpaywall(dois:["Coin Coin"]) { doi, is_oa } }', async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: '{unpaywall(dois:["Coin Coin"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.an('array'); + expect(data).eql([]); + }); + }); + + describe('GET: get unpaywall data with one DOI not normalized', () => { + it(`Ghould get unpaywall data - {unpaywall(dois:["${doi1.toUpperCase()}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: `{unpaywall(dois:["${doi1.toUpperCase()}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + }); + + describe('GET: get unpaywall data with two DOI', () => { + it(`should get unpaywall data - {unpaywall(dois:["${doi1}","${doi2}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: `{unpaywall(dois:["${doi1}","${doi2}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + expect(data[1]).have.property('is_oa').eq(false); + }); + + it(`should get unpaywall data - {unpaywall(dois:["${doi1}","Coin Coin"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: `{unpaywall(dois:["${doi1}","Coin Coin"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it('It should get empty tab - {unpaywall(dois:["Coin Coin","Coin Coin2"]) { doi, is_oa } }', async () => { + const res = await chai.request(graphqlURL) + .get('/graphql') + .query({ query: '{unpaywall(dois:["Coin Coin","Coin Coin2"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array').eql([]); + }); + }); + + after(async () => { + await deleteAllAPIKey(); + await loadDevAPIKey(); + }); +}); diff --git a/services/graphql/test/unpaywallHistoryPost1.js b/services/graphql/test/unpaywallHistoryPost1.js new file mode 100644 index 00000000..9ccb1f5c --- /dev/null +++ b/services/graphql/test/unpaywallHistoryPost1.js @@ -0,0 +1,123 @@ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const unpaywallBaseMapping = require('./mapping/unpaywall.json'); +const unpaywallHistoryMapping = require('./mapping/unpaywall.json'); + +const { + createIndex, + deleteIndex, + insertDataUnpaywall, +} = require('./utils/elastic'); + +const ping = require('./utils/ping'); + +const { + loadDevAPIKey, + deleteAllAPIKey, +} = require('./utils/apikey'); + +chai.use(chaiHttp); + +const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; +const doi1 = '1'; + +const date1 = '2019-06-01'; +const date2 = '2020-01-02'; +const date3 = '2010-10-01'; + +describe('Test POST 2 unpaywallHistory resolver', () => { + before(async function () { + this.timeout(30000); + await ping(); + await deleteAllAPIKey(); + await loadDevAPIKey(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', unpaywallBaseMapping); + await deleteIndex('unpaywall_history'); + await createIndex('unpaywall_history', unpaywallHistoryMapping); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); + await insertDataUnpaywall('indexHistoryData.jsonl', 'unpaywall_history'); + }); + + describe('Test: Try to get a unpaywall data', () => { + it('Should get unpaywall data from unpaywall_base and unpaywall_history index', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{ unpaywallHistory (dois: ["${doi1}"]) { doi, is_oa, updated, endValidity, referencedAt } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywallHistory; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + expect(data[0]).have.property('updated').eq('2020-01-01T01:00:00.000000'); + expect(data[0]).have.property('endValidity').eq(null); + expect(data[1]).have.property('doi').eq(doi1); + expect(data[1]).have.property('is_oa').eq(false); + expect(data[1]).have.property('updated').eq('2019-01-01T01:00:00.000000'); + expect(data[1]).have.property('endValidity').eq('2020-01-01T01:00:00.000000'); + }); + }); + + describe(`Test: Try to get a unpaywall data at date [${date1}]`, () => { + it('Should get unpaywall data from unpaywall_history index', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{ unpaywallHistory (dois: ["${doi1}"], date: "${date1}") { doi, is_oa, updated, endValidity, referencedAt } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywallHistory; + + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(false); + expect(data[0]).have.property('updated').eq('2019-01-01T01:00:00.000000'); + expect(data[0]).have.property('endValidity').eq('2020-01-01T01:00:00.000000'); + }); + }); + + describe(`Test: Try to get a unpaywall data at date [${date2}]`, () => { + it('Should get unpaywall data from unpaywall_base index', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{ unpaywallHistory (dois: ["${doi1}"], date: "${date2}") { doi, is_oa, updated, endValidity, referencedAt } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywallHistory; + + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + expect(data[0]).have.property('updated').eq('2020-01-01T01:00:00.000000'); + expect(data[0]).have.property('endValidity').eq(null); + }); + }); + + describe(`Test: Try to get a unpaywall data at date [${date2}]`, () => { + it('Should get empty array', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{ unpaywallHistory (dois: ["${doi1}"], date: "${date3}") { doi, is_oa, updated, endValidity, referencedAt } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywallHistory; + + expect(data).be.a('array'); + }); + }); + + after(async () => { + await deleteAllAPIKey(); + await loadDevAPIKey(); + }); +}); diff --git a/services/graphql/test/unpaywallPost1.js b/services/graphql/test/unpaywallPost1.js new file mode 100644 index 00000000..cb608deb --- /dev/null +++ b/services/graphql/test/unpaywallPost1.js @@ -0,0 +1,127 @@ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const mappingUnpaywall = require('./mapping/unpaywall.json'); + +const { + createIndex, + deleteIndex, + insertDataUnpaywall, +} = require('./utils/elastic'); + +const ping = require('./utils/ping'); + +const { + loadDevAPIKey, + deleteAllAPIKey, +} = require('./utils/apikey'); + +chai.use(chaiHttp); + +const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; +const doi1 = '1'; +const doi2 = '6'; + +describe('Test POST 2 unpaywall resolver', () => { + before(async function () { + this.timeout(30000); + await ping(); + await deleteAllAPIKey(); + await loadDevAPIKey(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); + }); + + describe('POST: get unpaywall data with one DOI', () => { + it(`should get unpaywall data - {unpaywall(dois:["${doi1}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{unpaywall(dois:["${doi1}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it('It should get empty tab - {unpaywall(dois:["Coin Coin"]) { doi, is_oa } }', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: '{unpaywall(dois:["Coin Coin"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.an('array'); + expect(data).eql([]); + }); + }); + + describe('POST: get unpaywall data with one DOI not normalized', () => { + it(`should get unpaywall data - {unpaywall(dois:["${doi1.toUpperCase()}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{unpaywall(dois:["${doi1.toUpperCase()}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + }); + + describe('POST: get unpaywall data with two DOI', () => { + it(`should get unpaywall data - {unpaywall(dois:["${doi1}","${doi2}"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{unpaywall(dois:["${doi1}","${doi2}"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + expect(data[1]).have.property('is_oa').eq(false); + }); + + it(`should get unpaywall data - {unpaywall(dois:["${doi1}","Coin Coin"]) { doi, is_oa } }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: `{unpaywall(dois:["${doi1}","Coin Coin"]) { doi, is_oa } }` }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it('It should get empty tab - {unpaywall(dois:["Coin Coin","Coin Coin2"]) { doi, is_oa } }', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: '{unpaywall(dois:["Coin Coin","Coin Coin2"]) { doi, is_oa } }' }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array').eql([]); + }); + }); + + after(async () => { + await deleteAllAPIKey(); + await loadDevAPIKey(); + }); +}); diff --git a/services/graphql/test/unpaywallPost2.js b/services/graphql/test/unpaywallPost2.js new file mode 100644 index 00000000..c2f9dee4 --- /dev/null +++ b/services/graphql/test/unpaywallPost2.js @@ -0,0 +1,158 @@ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const mappingUnpaywall = require('./mapping/unpaywall.json'); + +const { + createIndex, + deleteIndex, + insertDataUnpaywall, +} = require('./utils/elastic'); + +const ping = require('./utils/ping'); + +const { + loadDevAPIKey, + deleteAllAPIKey, +} = require('./utils/apikey'); + +chai.use(chaiHttp); + +const graphqlURL = process.env.GRAPHQL_HOST || 'http://localhost:59701'; +const doi1 = '1'; +const doi2 = '6'; + +describe('Test POST 2 unpaywall resolver', () => { + before(async function () { + this.timeout(30000); + await ping(); + await deleteAllAPIKey(); + await loadDevAPIKey(); + await deleteIndex('unpaywall_base'); + await createIndex('unpaywall_base', mappingUnpaywall); + await insertDataUnpaywall('indexBaseData.jsonl', 'unpaywall_base'); + }); + + describe('POST: get unpaywall data with one DOI', () => { + it(`should get unpaywall data - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variables : { dois: [${doi1}] }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: [doi1], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it('It should get empty tab - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variable : { dois: [\'Coin coin\'] }', async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: ['Coin coin'], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.an('array'); + expect(data).eql([]); + }); + }); + + describe('POST: get unpaywall data with one DOI not normalized', () => { + it(`should get unpaywall data - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variables : { dois : ['${doi1.toUpperCase()}'] }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: [doi1.toUpperCase()], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('doi').eq(doi1); + expect(data[0]).have.property('is_oa').eq(true); + }); + }); + + describe('POST: get unpaywall data with two DOI', () => { + it(`should get unpaywall data - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variables : { dois : ${[doi1, doi2]} }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: [doi1, doi2], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + expect(data[1]).have.property('is_oa').eq(false); + }); + + it(`should get unpaywall data - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variables : { dois : ${[doi1, 'Coin coin']} }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: [doi1, 'Coin Coin'], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array'); + expect(data[0]).have.property('is_oa').eq(true); + }); + + it(`It should get empty tab - query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } } - variables : { dois : ${['Coin coin', 'Coin coin2']} }`, async () => { + const res = await chai.request(graphqlURL) + .post('/graphql') + .send({ query: 'query ($dois: [ID!]!) {unpaywall(dois: $dois) { doi, is_oa } }' }) + .send({ + variables: { + dois: ['Coin Coin', 'Coin Coin2'], + }, + }) + .set('x-api-key', 'user'); + + expect(res).have.status(200); + + const data = res?.body?.data?.unpaywall; + expect(data).be.a('array').eql([]); + }); + }); + + after(async () => { + await deleteAllAPIKey(); + await loadDevAPIKey(); + }); +}); diff --git a/src/graphql/test/utils/apikey.js b/services/graphql/test/utils/apikey.js similarity index 100% rename from src/graphql/test/utils/apikey.js rename to services/graphql/test/utils/apikey.js diff --git a/src/graphql/test/utils/elastic.js b/services/graphql/test/utils/elastic.js similarity index 84% rename from src/graphql/test/utils/elastic.js rename to services/graphql/test/utils/elastic.js index f9de18d8..d30ab519 100644 --- a/src/graphql/test/utils/elastic.js +++ b/services/graphql/test/utils/elastic.js @@ -35,12 +35,12 @@ async function checkIfIndexExist(name) { } /** - * Insert the content of fake1.jsonl in elastic. + * Insert data in elastic. * * @returns {Promise} */ -async function insertDataUnpaywall() { - const filepath = path.resolve(__dirname, '..', 'sources', 'fake1.jsonl'); +async function insertDataUnpaywall(filename, indexName) { + const filepath = path.resolve(__dirname, '..', 'sources', filename); let readStream; try { readStream = await fs.createReadStream(filepath); @@ -59,7 +59,12 @@ async function insertDataUnpaywall() { data.push(JSON.parse(line)); } - const body = data.flatMap((doc) => [{ index: { _index: 'unpaywall-test', _id: doc.doi } }, doc]); + let body; + if (indexName === 'unpaywall_history') { + body = data.flatMap((doc) => [{ index: { _index: indexName, _id: `${doc.updated}-${doc.doi}` } }, doc]); + } else { + body = data.flatMap((doc) => [{ index: { _index: indexName, _id: doc.doi } }, doc]); + } try { await elasticClient.bulk({ refresh: true, body }); diff --git a/src/graphql/test/utils/ping.js b/services/graphql/test/utils/ping.js similarity index 94% rename from src/graphql/test/utils/ping.js rename to services/graphql/test/utils/ping.js index 87535d04..03d1c782 100644 --- a/src/graphql/test/utils/ping.js +++ b/services/graphql/test/utils/ping.js @@ -20,7 +20,7 @@ async function ping() { const elastic = await chai.request(elasticHost).get('/'); if (elastic?.status !== 200) { - throw new Error(`[elastic] Bad status : ${elastic?.status}`); + throw new Error(`[elastic]: Bad status : ${elastic?.status}`); } const apikey = await chai.request(apikeyHost).get('/ping'); diff --git a/src/mail/.dockerignore b/services/mail/.dockerignore similarity index 83% rename from src/mail/.dockerignore rename to services/mail/.dockerignore index ab4bc62b..115e7995 100644 --- a/src/mail/.dockerignore +++ b/services/mail/.dockerignore @@ -2,5 +2,6 @@ node_modules/ data/ log/ test/ +.gitignore .eslintrc.json README.md \ No newline at end of file diff --git a/src/mail/.eslintrc.json b/services/mail/.eslintrc.json similarity index 100% rename from src/mail/.eslintrc.json rename to services/mail/.eslintrc.json diff --git a/src/graphql/.gitignore b/services/mail/.gitignore similarity index 75% rename from src/graphql/.gitignore rename to services/mail/.gitignore index 4be22fe1..bebefb2a 100644 --- a/src/graphql/.gitignore +++ b/services/mail/.gitignore @@ -1,3 +1,2 @@ -data/ node_modules/ log/ \ No newline at end of file diff --git a/services/mail/Dockerfile b/services/mail/Dockerfile new file mode 100644 index 00000000..27880397 --- /dev/null +++ b/services/mail/Dockerfile @@ -0,0 +1,26 @@ +FROM node:18.19.1-alpine3.19 +LABEL maintainer="ezTeam " + +EXPOSE 3000 + +ENV NODE_ENV production + +ARG ACCESS_LOG_ROTATE +ARG MAIL_SMTP_HOST +ARG MAIL_SMTP_PORT +ARG MAIL_NOTIFICATIONS_SENDER +ARG MAIL_NOTIFICATIONS_RECEIVERS +ARG MAIL_NOTIFICATIONS_MACHINE +ARG MAIL_APIKEY +ARG HEALTH_TIMEOUT + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm ci --omit=dev +COPY . . + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/services/mail/README.md b/services/mail/README.md new file mode 100644 index 00000000..740042ed --- /dev/null +++ b/services/mail/README.md @@ -0,0 +1,57 @@ +# ezunpaywall-mail + +Service that sends email if there is an error in the update process and for the contact page in the web interface. +This service is for administrators. + +## Config + +To set up this service, you can use environment variables. The config is displayed at startup. Sensitive data are not displayed. + +``` +# if sensitive data are not updated +warn: [config]: Apikey has the default value + +info: { + "nodeEnv": "development", + "accessLogRotate": false, + "smtp": { + "host": "maildev", + "port": 25 + }, + "notifications": { + "sender": "ezunpaywall", + "receivers": [ + "ezunpaywall@example.fr" + ], + "machine": "dev" + }, + "apikey": "********", + "healthTimeout": 3000 +} +``` + +## Service environment variables + +| name | default | description | +| --- | --- | --- | +| NODE_ENV | development | environment of node | +| NODE_CONFIG | {} | make tls and secure of mail (only in developement) | +| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | +| MAIL_SMTP_HOST | localhost | SMTP server host | +| MAIL_SMTP_PORT | 25 | SMTP server port | +| MAIL_NOTIFICATIONS_SENDER | ezunpaywall | the sender for emails issued by ezunpaywall | +| MAIL_NOTIFICATIONS_RECEIVERS | ezunpaywall@example.fr" | recipients of the recent activity email | +| MAIL_NOTIFICATIONS_MACHINE | dev | environment of machine | +| MAIL_APIKEY | changeme | mail apikey | +| HEALTH_TIMEOUT | 3000 | timeout to query the health route | + + +## Log format + +``` +:ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" +``` + +## Open API + +[open-api documentation](https://unpaywall.inist.fr/open-api?doc=mail) \ No newline at end of file diff --git a/services/mail/app.js b/services/mail/app.js new file mode 100644 index 00000000..cafbfd30 --- /dev/null +++ b/services/mail/app.js @@ -0,0 +1,50 @@ +const express = require('express'); +const cors = require('cors'); +const fs = require('fs-extra'); +const path = require('path'); +const { paths } = require('config'); + +const appLogger = require('./src/logger/appLogger'); +const accessLogger = require('./src/logger/access'); + +const getConfig = require('./src/config'); + +const routerHealthCheck = require('./src/routers/healthcheck'); +const routerPing = require('./src/routers/ping'); +const routerMail = require('./src/routers/mail'); +const routerOpenapi = require('./src/routers/openapi'); + +// create log directory +fs.ensureDir(path.resolve(paths.log.applicationDir)); +fs.ensureDir(path.resolve(paths.log.accessDir)); +fs.ensureDir(path.resolve(paths.log.healthCheckDir)); + +const app = express(); + +app.use(express.urlencoded({ extended: true })); +app.use(express.json()); +app.use(cors({ + origin: '*', + method: ['GET', 'POST'], +})); + +// initiate healthcheck router with his logger +app.use(routerHealthCheck); + +// initiate access logger +app.use(accessLogger); + +// initiate all other routes +app.use(routerPing); +app.use(routerMail); +app.use(routerOpenapi); + +// Errors and unknown routes +app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}: this route does not exist.` })); + +app.use((error, req, res, next) => res.status(500).json({ message: error.message })); + +app.listen(3000, () => { + appLogger.info('[express]: ezunpaywall mail service listening on 3000'); + getConfig(); +}); diff --git a/src/mail/config/custom-environment-variables.json b/services/mail/config/custom-environment-variables.json similarity index 100% rename from src/mail/config/custom-environment-variables.json rename to services/mail/config/custom-environment-variables.json diff --git a/src/mail/config/default.json b/services/mail/config/default.json similarity index 63% rename from src/mail/config/default.json rename to services/mail/config/default.json index 271872f6..8ce19891 100644 --- a/src/mail/config/default.json +++ b/services/mail/config/default.json @@ -10,6 +10,13 @@ "receivers": ["ezunpaywall@example.fr"], "machine": "dev" }, + "paths": { + "log": { + "applicationDir": "./log/application", + "accessDir": "./log/access", + "healthCheckDir": "./log/healthcheck" + } + }, "apikey": "changeme", "healthTimeout": 3000 } \ No newline at end of file diff --git a/services/mail/openapi.yml b/services/mail/openapi.yml new file mode 100644 index 00000000..53e1645c --- /dev/null +++ b/services/mail/openapi.yml @@ -0,0 +1,261 @@ +openapi: 3.0.0 +info: + description: The mail service allows the sending of mail for the different services + version: 1.0.0 + title: Mail service + contact: + email: ezteam@couperin.org + name: ezTeam + license: + name: CeCILL 2.1 + url: http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html +servers: + - url: https://unpaywall.inist.fr/api +tags: + - name: mail + - name: ping +paths: + /mail: + get: + tags: + - ping + operationId: get-mail + summary: Name of service + description: Get name of mail service + responses: + '200': + description: OK + content: + '*/*': + schema: + type: string + x-examples: + example-1: mail service + examples: + service: + value: mail service + Success: + examples: + response: + value: + message: mail service + + /mail/ping: + get: + tags: + - ping + operationId: get-mail-ping + summary: Ping mail service + description: Ping mail service + responses: + '204': + description: No Content + /mail/health: + get: + tags: + - ping + operationId: get-mail-health + summary: Health + description: Health on all service connected to enrich service + parameters: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + smtp: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + x-examples: + Example 1: + smtp: + elapsedTime: 1 + status: true + examples: + Success: + value: + smtp: + elapsedTime: 1 + status: true + Error smtp: + value: + smtp: + elapsedTime: 133 + status: false + error: self signed certificate + + /mail/health/smtp: + get: + tags: + - ping + operationId: get-mail-health-smtp + summary: Health on SMTP service + description: Health on smtp + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + /mail/contact: + post: + tags: + - mail + operationId: post-mail-contact + summary: Send mail contact + description: Send contact mail + security: + - x-api-key: [] + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + '*/*': + schema: + type: object + properties: {} + email expected: + examples: + response: + value: + message: email are expected + invalid email: + examples: + response: + value: + message: '["john"] is invalid email' + subject expected: + examples: + response: + value: + message: subject are expected + message expected: + examples: + response: + value: + message: message are expected + '401': + $ref: '#/components/responses/Not-authorized' + '403': + description: Forbidden + content: + '*/*': + schema: + type: object + properties: {} + + + /mail/update-start: + post: + tags: + - mail + operationId: post-mail-update-start + summary: Send mail update process start + description: Sending of the email informing the launch of the update process + security: + - x-api-key: [] + parameters: [] + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + '*/*': + schema: + type: object + properties: {} + '401': + $ref: '#/components/responses/Not-authorized' + '403': + description: Forbidden + content: + '*/*': + schema: + type: object + properties: {} + + /mail/update-end: + post: + tags: + - mail + operationId: post-mail-update-end + summary: Send mail update process ended + description: Sending of the email with the report of the end of the update + security: + - x-api-key: [] + parameters: [] + responses: + '202': + description: Accepted + '400': + description: Bad Request + content: + '*/*': + schema: + type: object + properties: {} + '401': + $ref: '#/components/responses/Not-authorized' + '403': + description: Forbidden + content: + '*/*': + schema: + type: object + properties: {} + + +components: + responses: + Not-authorized: + description: Not authorized + headers: {} + content: + application/json: + examples: + response: + value: + message: Not authorized + Health: + description: Example response + content: + Success: + schema: + type: object + properties: + name: + type: string + status: + type: boolean + elapsedTime: + type: integer + x-examples: + Example 1: + name: redis + status: true + elapsedTime: 1 + examples: + Success: + value: + name: name of service + status: true + elapsedTime: 1 + Error smtp: + value: + elapsedTime: 115 + status: false + error: self signed certificate + securitySchemes: + x-api-key: + name: API Key + type: apiKey + in: header diff --git a/src/mail/package-lock.json b/services/mail/package-lock.json similarity index 98% rename from src/mail/package-lock.json rename to services/mail/package-lock.json index 47805ffc..3936f194 100644 --- a/src/mail/package-lock.json +++ b/services/mail/package-lock.json @@ -1,19 +1,21 @@ { "name": "mail", - "version": "1.3.0", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mail", - "version": "1.3.0", + "version": "1.3.5", "license": "ISC", "dependencies": { + "@hapi/joi-date": "^2.0.1", "config": "^3.3.9", "cors": "^2.8.5", "date-fns": "^2.30.0", "express": "^4.18.2", "fs-extra": "^11.1.1", + "joi": "^17.12.2", "mjml": "^4.14.1", "morgan": "^1.10.0", "nodemailer": "^6.9.5", @@ -146,6 +148,27 @@ "node": "^12.22.0 || ^14.17.0 || >=16.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==" + }, + "node_modules/@hapi/joi-date": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@hapi/joi-date/-/joi-date-2.0.1.tgz", + "integrity": "sha512-8be8JUEC8Wm1Do3ryJy+TXmkAL13b2JwXn7gILBoor8LopY/M+hJskodzOOxfJdckkfWnbmbnMEyJW3d/gZMfA==", + "dependencies": { + "moment": "2.x.x" + } + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -242,6 +265,24 @@ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "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==" + }, + "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==" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2510,6 +2551,18 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "node_modules/joi": { + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "node_modules/js-beautify": { "version": "1.14.9", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.9.tgz", @@ -4922,6 +4975,27 @@ "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", "dev": true }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "@hapi/joi-date": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@hapi/joi-date/-/joi-date-2.0.1.tgz", + "integrity": "sha512-8be8JUEC8Wm1Do3ryJy+TXmkAL13b2JwXn7gILBoor8LopY/M+hJskodzOOxfJdckkfWnbmbnMEyJW3d/gZMfA==", + "requires": { + "moment": "2.x.x" + } + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, "@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -4993,6 +5067,24 @@ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" }, + "@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "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==" + }, + "@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==" + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -5033,8 +5125,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", @@ -6677,6 +6768,18 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "joi": { + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", + "requires": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-beautify": { "version": "1.14.9", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.9.tgz", diff --git a/src/mail/package.json b/services/mail/package.json similarity index 93% rename from src/mail/package.json rename to services/mail/package.json index 3c9a6b4f..db123be8 100644 --- a/src/mail/package.json +++ b/services/mail/package.json @@ -11,11 +11,13 @@ "author": "", "license": "ISC", "dependencies": { + "@hapi/joi-date": "^2.0.1", "config": "^3.3.9", "cors": "^2.8.5", "date-fns": "^2.30.0", "express": "^4.18.2", "fs-extra": "^11.1.1", + "joi": "^17.12.2", "mjml": "^4.14.1", "morgan": "^1.10.0", "nodemailer": "^6.9.5", diff --git a/src/mail/lib/config.js b/services/mail/src/config.js similarity index 91% rename from src/mail/lib/config.js rename to services/mail/src/config.js index 84be87fc..592914db 100644 --- a/src/mail/lib/config.js +++ b/services/mail/src/config.js @@ -1,6 +1,6 @@ const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const defaultConfig = require('../config/default.json'); const copyConfig = JSON.parse(JSON.stringify(config)); diff --git a/src/mail/lib/controllers/health.js b/services/mail/src/controllers/health.js similarity index 100% rename from src/mail/lib/controllers/health.js rename to services/mail/src/controllers/health.js diff --git a/src/mail/lib/controllers/mail.js b/services/mail/src/controllers/mail.js similarity index 78% rename from src/mail/lib/controllers/mail.js rename to services/mail/src/controllers/mail.js index bef1e71d..9c9baa46 100644 --- a/src/mail/lib/controllers/mail.js +++ b/services/mail/src/controllers/mail.js @@ -15,25 +15,7 @@ const { function sendMailContact(req, res, next) { const { email, subject, message, - } = req.body; - - if (!email) { - return res.status(400).json({ message: 'Email is expected' }); - } - - const pattern = /.+@.+\..+/; - - if (!pattern.test(email)) { - return res.status(400).json({ message: `Email [${email}] is invalid` }); - } - - if (!subject) { - return res.status(400).json({ message: 'Subject is expected' }); - } - - if (!message) { - return res.status(400).json({ message: 'Message is expected' }); - } + } = req.data; contactMail(email, subject, message); @@ -65,6 +47,7 @@ function sendMailUpdateStarted(req, res, next) { function sendMailUpdateReport(req, res, next) { const state = req.body; + // TODO test state updateReportMail(state); return res.status(202).json(); @@ -78,8 +61,7 @@ function sendMailUpdateReport(req, res, next) { * @param {import('express').NextFunction} next - Do the following. */ function sendMailNoChangefile(req, res, next) { - const { startDate, endDate } = req.body; - // TODO test startDate, endDate + const { startDate, endDate } = req.data; noChangefileMail(startDate, endDate); diff --git a/src/apikey/lib/morgan.js b/services/mail/src/logger/access.js similarity index 70% rename from src/apikey/lib/morgan.js rename to services/mail/src/logger/access.js index 9e16d039..fda3b593 100644 --- a/src/apikey/lib/morgan.js +++ b/services/mail/src/logger/access.js @@ -3,14 +3,14 @@ const fs = require('fs-extra'); const rfs = require('rotating-file-stream'); const path = require('path'); const { format } = require('date-fns'); -const { accessLogRotate } = require('config'); +const { nodeEnv, paths, accessLogRotate } = require('config'); -const accessLogDir = path.resolve(__dirname, '..', 'log', 'access'); +const isProd = (nodeEnv === 'production'); /** * Get the name of access file. * - * @param {number} date - Date in minisecond + * @param {number} date - Date in milliseconds * * @returns {string} Name of access file. */ @@ -24,10 +24,10 @@ let accessLogStream; if (accessLogRotate) { accessLogStream = rfs.createStream(logFilename, { interval: '1d', // rotate daily - path: accessLogDir, + path: paths.log.accessDir, }); } else { - accessLogStream = fs.createWriteStream(path.resolve(accessLogDir, 'access.log'), { flags: 'a+' }); + accessLogStream = fs.createWriteStream(path.resolve(paths.log.accessDir, 'access.log'), { flags: 'a+' }); } morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); @@ -37,4 +37,4 @@ morgan.token('user', (req) => { return '-'; }); -module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: accessLogStream }); +module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: isProd ? accessLogStream : process.stdout }); diff --git a/src/apikey/lib/logger.js b/services/mail/src/logger/appLogger.js similarity index 91% rename from src/apikey/lib/logger.js rename to services/mail/src/logger/appLogger.js index d2d91902..e83d3544 100644 --- a/src/apikey/lib/logger.js +++ b/services/mail/src/logger/appLogger.js @@ -1,5 +1,5 @@ const path = require('path'); -const { nodeEnv } = require('config'); +const { nodeEnv, paths } = require('config'); const isProd = (nodeEnv === 'production'); @@ -22,7 +22,7 @@ const { const processConfiguration = [ new transports.DailyRotateFile({ name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), + filename: path.resolve(paths.log.applicationDir, '%DATE%.log'), datePattern: 'yyyy-MM-DD', level: 'info', }), diff --git a/services/mail/src/logger/healthcheck.js b/services/mail/src/logger/healthcheck.js new file mode 100644 index 00000000..f56e9d9f --- /dev/null +++ b/services/mail/src/logger/healthcheck.js @@ -0,0 +1,41 @@ +const morgan = require('morgan'); +const fs = require('fs-extra'); +const rfs = require('rotating-file-stream'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths, healthcheckLogRotate } = require('config'); + +/** + * Get the name of healthcheck log file. + * + * @param {number} date - Date in milliseconds + * + * @returns {string} Name of healthcheck log file. + */ +function logFilename(date) { + if (!date) return 'healthcheck.log'; + return `${format(new Date(date) - 1000 * 60 * 60 * 24, 'yyyy-MM-dd')}-healthcheck.log`; +} + +let healthCheckLogStream; + +if (healthcheckLogRotate) { + healthCheckLogStream = rfs.createStream(logFilename, { + interval: '1d', // rotate daily + path: paths.log.healthCheckDir, + }); +} else { + healthCheckLogStream = fs.createWriteStream(path.resolve(paths.log.healthCheckDir, 'healthcheck.log'), { flags: 'a+' }); +} + +morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); + +morgan.token('user', (req) => { + if (req.user) return req.user; + return '-'; +}); + +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: healthCheckLogStream }, +); diff --git a/src/mail/lib/mail.js b/services/mail/src/mail.js similarity index 99% rename from src/mail/lib/mail.js rename to services/mail/src/mail.js index 897b8d72..7a80466b 100644 --- a/src/mail/lib/mail.js +++ b/services/mail/src/mail.js @@ -7,7 +7,7 @@ const { smtp } = require('config'); const { format } = require('date-fns'); const { notifications } = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const transporter = nodemailer.createTransport(smtp); diff --git a/src/mail/lib/middlewares/auth.js b/services/mail/src/middlewares/auth.js similarity index 100% rename from src/mail/lib/middlewares/auth.js rename to services/mail/src/middlewares/auth.js diff --git a/services/mail/src/middlewares/mail.js b/services/mail/src/middlewares/mail.js new file mode 100644 index 00000000..6f651490 --- /dev/null +++ b/services/mail/src/middlewares/mail.js @@ -0,0 +1,38 @@ +const joi = require('joi').extend(require('@hapi/joi-date')); + +async function validateNoChangefile(req, res, next) { + const { error, value } = joi.object({ + startDate: joi.date().format('YYYY-MM-DD').required(), + endDate: joi.date().format('YYYY-MM-DD').min(joi.ref('startDate')).required(), + }).with('endDate', 'startDate').validate(req.body); + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data = value; + + return next(); +} + +async function validateMailContact(req, res, next) { + const { error, value } = joi.object({ + email: joi.string().email().required(), + subject: joi.string().required(), + message: joi.string().required(), + }).with('endDate', 'startDate').validate(req.body); + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data = value; + + return next(); +} + +module.exports = { validateNoChangefile, validateMailContact }; diff --git a/src/mail/lib/ping.js b/services/mail/src/ping.js similarity index 100% rename from src/mail/lib/ping.js rename to services/mail/src/ping.js diff --git a/services/mail/src/routers/healthcheck.js b/services/mail/src/routers/healthcheck.js new file mode 100644 index 00000000..5eb10fe8 --- /dev/null +++ b/services/mail/src/routers/healthcheck.js @@ -0,0 +1,10 @@ +const router = require('express').Router(); + +const healthCheckLogger = require('../logger/healthcheck'); + +/** + * Route use for healthcheck. + */ +router.get('/healthcheck', healthCheckLogger, (req, res, next) => res.status(204).end()); + +module.exports = router; diff --git a/src/mail/lib/routers/mail.js b/services/mail/src/routers/mail.js similarity index 73% rename from src/mail/lib/routers/mail.js rename to services/mail/src/routers/mail.js index fbe17f83..259ba458 100644 --- a/src/mail/lib/routers/mail.js +++ b/services/mail/src/routers/mail.js @@ -8,11 +8,16 @@ const { sendMailNoChangefile, } = require('../controllers/mail'); +const { + validateNoChangefile, + validateMailContact, +} = require('../middlewares/mail'); + /** * Route that send a contact mail. * Auth required. */ -router.post('/contact', checkAuth, sendMailContact); +router.post('/contact', checkAuth, validateMailContact, sendMailContact); /** * Route that sends a mail that inform that an update has started start. @@ -30,6 +35,6 @@ router.post('/update-end', checkAuth, sendMailUpdateReport); * Route that informe that no changefiles are available. * Auth required. */ -router.post('/nochangefile', checkAuth, sendMailNoChangefile); +router.post('/nochangefile', checkAuth, validateNoChangefile, sendMailNoChangefile); module.exports = router; diff --git a/services/mail/src/routers/openapi.js b/services/mail/src/routers/openapi.js new file mode 100644 index 00000000..bdf85c7d --- /dev/null +++ b/services/mail/src/routers/openapi.js @@ -0,0 +1,9 @@ +const router = require('express').Router(); +const path = require('path'); + +/** + * Route that give the openapi.json file. + */ +router.get('/openapi.yml', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'openapi.yml'))); + +module.exports = router; diff --git a/src/mail/lib/routers/ping.js b/services/mail/src/routers/ping.js similarity index 100% rename from src/mail/lib/routers/ping.js rename to services/mail/src/routers/ping.js diff --git a/src/mail/templates/contact.mjml b/services/mail/templates/contact.mjml similarity index 100% rename from src/mail/templates/contact.mjml rename to services/mail/templates/contact.mjml diff --git a/src/mail/templates/contact.txt b/services/mail/templates/contact.txt similarity index 100% rename from src/mail/templates/contact.txt rename to services/mail/templates/contact.txt diff --git a/src/mail/templates/images/github.png b/services/mail/templates/images/github.png similarity index 100% rename from src/mail/templates/images/github.png rename to services/mail/templates/images/github.png diff --git a/src/mail/templates/images/twitter.png b/services/mail/templates/images/twitter.png similarity index 100% rename from src/mail/templates/images/twitter.png rename to services/mail/templates/images/twitter.png diff --git a/src/mail/templates/images/youtube.png b/services/mail/templates/images/youtube.png similarity index 100% rename from src/mail/templates/images/youtube.png rename to services/mail/templates/images/youtube.png diff --git a/src/mail/templates/layout.mjml b/services/mail/templates/layout.mjml similarity index 100% rename from src/mail/templates/layout.mjml rename to services/mail/templates/layout.mjml diff --git a/src/mail/templates/noChangefile.mjml b/services/mail/templates/noChangefile.mjml similarity index 100% rename from src/mail/templates/noChangefile.mjml rename to services/mail/templates/noChangefile.mjml diff --git a/src/mail/templates/noChangefile.txt b/services/mail/templates/noChangefile.txt similarity index 100% rename from src/mail/templates/noChangefile.txt rename to services/mail/templates/noChangefile.txt diff --git a/src/mail/templates/updateReport.mjml b/services/mail/templates/updateReport.mjml similarity index 100% rename from src/mail/templates/updateReport.mjml rename to services/mail/templates/updateReport.mjml diff --git a/src/mail/templates/updateReport.txt b/services/mail/templates/updateReport.txt similarity index 100% rename from src/mail/templates/updateReport.txt rename to services/mail/templates/updateReport.txt diff --git a/src/mail/templates/updateStarted.mjml b/services/mail/templates/updateStarted.mjml similarity index 100% rename from src/mail/templates/updateStarted.mjml rename to services/mail/templates/updateStarted.mjml diff --git a/src/mail/templates/updateStarted.txt b/services/mail/templates/updateStarted.txt similarity index 100% rename from src/mail/templates/updateStarted.txt rename to services/mail/templates/updateStarted.txt diff --git a/src/nginx/Dockerfile b/services/nginx/Dockerfile similarity index 50% rename from src/nginx/Dockerfile rename to services/nginx/Dockerfile index 2a231f9b..08b5ec1f 100644 --- a/src/nginx/Dockerfile +++ b/services/nginx/Dockerfile @@ -4,4 +4,7 @@ COPY templates/http.conf.template /etc/nginx/templates/default.conf.template EXPOSE 80 +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:80 || exit 1 + CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/services/nginx/README.md b/services/nginx/README.md new file mode 100644 index 00000000..618384a4 --- /dev/null +++ b/services/nginx/README.md @@ -0,0 +1,17 @@ +# ezunpaywall-nginx + +Entry point and reverse proxy that redirecting all services of ezunpaywall. + +## Environment variables + +| name | default | description | +| --- | --- | --- | +| FRONTEND_HOST | '' | frontend host | +| GRAPHQL_HOST | '' | graphql host | +| UPDATE_HOST | '' | update host | +| ENRICH_HOST | '' | enrich host | +| APIKEY_HOST | '' | apikey host | +| MAIL_HOST | '' | mail host | +| HEALTH_HOST | '' | health host | +| NGINX_HOST | '' | nginx host | +| NGINX_PORT | 80 | output port | \ No newline at end of file diff --git a/src/nginx/templates/.gitignore b/services/nginx/templates/.gitignore similarity index 100% rename from src/nginx/templates/.gitignore rename to services/nginx/templates/.gitignore diff --git a/services/nginx/templates/dev.conf.template b/services/nginx/templates/dev.conf.template new file mode 100644 index 00000000..36af943b --- /dev/null +++ b/services/nginx/templates/dev.conf.template @@ -0,0 +1,49 @@ +server { + server_name ${NGINX_HOST}; + + client_max_body_size 500M; + + listen 80; + listen [::]:80; + + ## Configuration + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_hide_header X-Powered-By; + + location /api { + rewrite ^/api(/.*)$ $1 break; + proxy_pass ${GRAPHQL_HOST}; + } + + location /api/update { + rewrite ^/api/update(/.*)$ $1 break; + proxy_pass ${UPDATE_HOST}; + } + + location /api/enrich { + rewrite ^/api/enrich(/.*)$ $1 break; + proxy_pass ${ENRICH_HOST}; + } + + location /api/apikey { + rewrite ^/api/apikey(/.*)$ $1 break; + proxy_pass ${APIKEY_HOST}; + } + + location /api/mail { + rewrite ^/api/mail(/.*)$ $1 break; + proxy_pass ${MAIL_HOST}; + } + + ## client + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_pass ${FRONTEND_HOST}; + } +} \ No newline at end of file diff --git a/src/nginx/templates/http.conf.template b/services/nginx/templates/http.conf.template similarity index 89% rename from src/nginx/templates/http.conf.template rename to services/nginx/templates/http.conf.template index 5f759ea7..a7aa9a06 100644 --- a/src/nginx/templates/http.conf.template +++ b/services/nginx/templates/http.conf.template @@ -12,12 +12,6 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_hide_header X-Powered-By; - ## client - - location / { - proxy_pass ${FRONTEND_HOST}; - } - location /api { rewrite ^/api(/.*)$ $1 break; proxy_pass ${GRAPHQL_HOST}; @@ -43,8 +37,8 @@ server { proxy_pass ${MAIL_HOST}; } - location /api/health { - rewrite ^/api/health(/.*)$ $1 break; - proxy_pass ${HEALTH_HOST}; + ## client + location / { + proxy_pass ${FRONTEND_HOST}; } } \ No newline at end of file diff --git a/src/nginx/templates/https.conf.template b/services/nginx/templates/https.conf.template similarity index 94% rename from src/nginx/templates/https.conf.template rename to services/nginx/templates/https.conf.template index 54d33c07..2e66d41b 100644 --- a/src/nginx/templates/https.conf.template +++ b/services/nginx/templates/https.conf.template @@ -68,11 +68,6 @@ server { proxy_pass ${MAIL_HOST}; } - location /api/health { - rewrite ^/api/health(/.*)$ $1 break; - proxy_pass ${HEALTH_HOST}; - } - ## Diffie-Hellman ssl_ecdh_curve secp384r1; diff --git a/src/update/.dockerignore b/services/update/.dockerignore similarity index 100% rename from src/update/.dockerignore rename to services/update/.dockerignore diff --git a/src/update/.eslintrc.json b/services/update/.eslintrc.json similarity index 100% rename from src/update/.eslintrc.json rename to services/update/.eslintrc.json diff --git a/src/update/.gitignore b/services/update/.gitignore similarity index 100% rename from src/update/.gitignore rename to services/update/.gitignore diff --git a/services/update/Dockerfile b/services/update/Dockerfile new file mode 100644 index 00000000..f885cc5e --- /dev/null +++ b/services/update/Dockerfile @@ -0,0 +1,42 @@ +FROM node:18.19.1-alpine3.19 +LABEL maintainer="ezTeam " + +EXPOSE 3000 + +ENV NODE_ENV production + +ARG ACCESS_LOG_ROTATE +ARG TIMEZONE +ARG UNPAYWALL_HOST +ARG UNPAYWALL_APIKEY +ARG MAIL_HOST +ARG MAIL_APIKEY +ARG ELASTICSEARCH_HOSTS +ARG ELASTICSEARCH_PORT +ARG ELASTICSEARCH_USERNAME +ARG ELASTICSEARCH_PASSWORD +ARG ELASTICSEARCH_MAX_BULK_SIZE +ARG ELASTICSEARCH_INDEX_ALIAS +ARG ELASTICSEARCH_TIMEOUT +ARG UNPAYWALL_CRON_SCHEDULE +ARG UNPAYWALL_CRON_ACTIVE +ARG UNPAYWALL_CRON_INDEX +ARG UNPAYWALL_CRON_INTERVAL +ARG unpaywall-history_CRON_SCHEDULE +ARG unpaywall-history_CRON_ACTIVE +ARG unpaywall-history_CRON_INDEX_BASE +ARG unpaywall-history_CRON_INDEX_HISTORY +ARG unpaywall-history_CRON_INTERVAL +ARG UPDATE_APIKEY +ARG HEALTH_TIMEOUT + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm ci --omit=dev +COPY . . + +HEALTHCHECK --interval=1m --timeout=10s --retries=5 --start-period=20s \ + CMD wget -Y off --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/services/update/README.md b/services/update/README.md new file mode 100644 index 00000000..eec040a2 --- /dev/null +++ b/services/update/README.md @@ -0,0 +1,180 @@ +# ezunpaywall-update + +Service that updates unpaywall data daily via a cron job. +During the job, a state allows you to monitor the current job. +This service is for administrators. + +## Config + +To set up this service, you can use environment variables. The config is displayed at startup. Sensitive data are not displayed. + +``` +# if sensitive data are not updated +warn: [config]: Unpaywall apikey has the default value +warn: [config]: Mail apikey has the default value +warn: [config]: elasticsearch password has the default value +warn: [config]: Apikey has the default value + +info: { + "nodeEnv": "development", + "accessLogRotate": false, + "timezone": "Europe/Paris", + "unpaywall": { + "host": "http://fakeunpaywall:3000", + "apikey": "********" + }, + "mail": { + "host": "http://mail:3000", + "apikey": "********" + }, + "elasticsearch": { + "host": "http://elastic", + "port": 9200, + "user": "elastic", + "password": "********", + "maxBulkSize": 4000, + "indexAlias": "upw", + "timeout": 20000 + }, + "unpaywallCron": { + "schedule": "0 0 0 * * *", + "active": false, + "index": "unpaywall", + "interval": "day" + }, + "unpaywallHistoryCron": { + "schedule": "0 0 0 * * *", + "active": false, + "indexBase": "unpaywall-base", + "indexHistory": "unpaywall-history", + "interval": "day" + }, + "apikey": "********", + "healthTimeout": 3000 +} +``` + +## Environment variables + +| name | default | description | +| --- | --- | --- | +| NODE_ENV | development | environnement of node | +| ACCESS_LOG_ROTATE | false | use local daily rotation for log | +| TIMEZONE | Europe/Paris | timezone of app used in cron | +| UNPAYWALL_HOST | http://fakeunpaywall:3000 | unpaywall api host to access to changefiles | +| UNPAYWALL_APIKEY | changeme | unpaywall apikey to access to changefiles | +| MAIL_HOST | http://mail:3000 | mail service host | +| MAIL_APIKEY | changeme | mail apikey | +| ELASTICSEARCH_HOSTS | http://elastic | elastic host | +| ELASTICSEARCH_PORT | 9200 | elastic port | +| ELASTICSEARCH_USERNAME | elastic | username of elastic super user | +| ELASTICSEARCH_PASSWORD | changeme | password of elastic super user | +| ELASTICSEARCH_MAX_BULK_SIZE | 4000 | max bulk size of update process | +| ELASTICSEARCH_INDEX_ALIAS | upw | default alias of unpaywall data | +| UNPAYWALL_CRON_SCHEDULE | 0 0 0 * * * | schedule of unpaywall cron | +| UNPAYWALL_CRON_ACTIVE | false | state of unpaywall cron | +| UNPAYWALL_CRON_INDEX | unpaywall | index of unpaywall process of cron | +| UNPAYWALL_CRON_INTERVAL | day | interval of unpaywall process of cron | +| unpaywall-history_CRON_SCHEDULE | 0 0 0 * * * | schedule of unpaywall history cron | +| unpaywall-history_CRON_ACTIVE | false | state of unpaywall history cron | +| unpaywall-history_CRON_INDEX_BASE | unpaywall-base | index base unpaywall used for cron | +| unpaywall-history_CRON_INDEX_HISTORY | unpaywall-history | index history unpaywall used for cron | +| unpaywall-history_CRON_INTERVAL | day | interval of unpaywall history process of cron | +| UPDATE_APIKEY | changeme | update apikey to start update process | +| HEALTH_TIMEOUT | 3000 | timeout to query the health route | + +## Activity diagram + +Update process + +![Activity-diagram](./doc/activity-diagram-update.png) + +### Object structure + +[data-format](https://unpaywall.org/data-format) + +### Data + +2 types of file is generated by update job : +- update file from unpaywall +- reports +They are structured like this +``` +data +├── snapshots +│ ├── 2020-01-01-snapshot.jsonl.gz +│ ├── ... +│ └── 2020-12-01-changefile.jsonl.gz +├── unpaywall +│ └── reports +│ ├── 2020-01-01_12:24:29.json +│ ├── ... +│ └── 2020-12-01_10:32:20.json +└── unpaywallHistory + └── reports + ├── 2020-01-01_10:00:00.json + ├── ... + └── 2020-12-01_10:00:00.json +``` + +### Cron + +3 crons can be used on this service + +**File** + +This cron automatically deletes files generated by updates that are more than 30 days old. + +**unpaywall** + +This cron automatically executes the unpaywall data update job. This cron config can be updated using the API. + +``` +{ + "index": "unpaywall", // elastic index where data will be inserted + "interval": "day", // update file register interval (week or day) + "name": "update", // name of cron + "schedule": "0 0 0 * * *", // schedule of cron + "active": false // if is active or not +} +``` + +**unpaywallHistory** + +This cron automatically updates unpaywall data and populates the history. This cron config can be updated using the API. + +``` +{ + "indexBase": "unpaywall-base", // elastic index where the unpaywall base data will be inserted + "indexHistory": "unpaywall-history", // elastic index where the unpaywall history data will be inserted + "interval": "day", // update file register interval (week or day) + "name": "update", // name of cron + "schedule": "0 0 0 * * *", // schedule of cron + "active": false // if is active or not +} +``` + +### Elastic mapping + +- [unpaywall](./mapping/unpaywall.json) +- [unpaywall-base](./mapping/unpaywall-base.json) +- [unpaywall-history](./mapping/unpaywall-history.json) + +## Access Log format + +``` +:ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" +``` + +## Open API + +[open-api documentation](https://unpaywall.inist.fr/open-api?doc=update) + +## Test + +``` +# Functional tests +npm run test +# Unit test +# it's your turn to play +``` \ No newline at end of file diff --git a/services/update/app.js b/services/update/app.js new file mode 100644 index 00000000..cc685837 --- /dev/null +++ b/services/update/app.js @@ -0,0 +1,87 @@ +const express = require('express'); +const fs = require('fs-extra'); +const path = require('path'); +const cors = require('cors'); +const { paths } = require('config'); + +const accessLogger = require('./src/logger/access'); +const appLogger = require('./src/logger/appLogger'); + +const getConfig = require('./src/config'); + +const routerHealthCheck = require('./src/routers/healthcheck'); +const routerPing = require('./src/routers/ping'); +const routerElastic = require('./src/routers/elastic'); +const routerOpenapi = require('./src/routers/openapi'); +const routerUnpaywall = require('./src/routers/unpaywall'); +const routerStatus = require('./src/routers/status'); +const routerState = require('./src/routers/state'); + +const routerJob = require('./src/routers/job'); +const routerReport = require('./src/routers/report'); +const routerCron = require('./src/routers/cron'); +const routerChangefile = require('./src/routers/changefile'); +const routerSnapshot = require('./src/routers/snapshot'); + +const cronFile = require('./src/cron/cleanFile'); +const dataUpdate = require('./src/cron/dataUpdate'); +const dataUpdateHistoryCron = require('./src/cron/dataUpdateHistory'); +const cronDownloadSnapshot = require('./src/cron/downloadSnapshot'); + +// create data directory +fs.ensureDir(path.resolve(paths.data.changefilesDir)); +fs.ensureDir(path.resolve(paths.data.snapshotsDir)); +fs.ensureDir(path.resolve(paths.data.reportsDir)); + +// create log directory +fs.ensureDir(path.resolve(paths.log.applicationDir)); +fs.ensureDir(path.resolve(paths.log.accessDir)); +fs.ensureDir(path.resolve(paths.log.healthCheckDir)); + +const app = express(); + +app.use(express.json()); +app.use(cors()); + +// initiate healthcheck router with his logger +app.use(routerHealthCheck); + +// initiate access logger +app.use(accessLogger); + +// initiate all other routes +app.use(routerPing); +app.use(routerElastic); +app.use(routerOpenapi); +app.use(routerUnpaywall); +app.use(routerStatus); +app.use(routerState); +app.use(routerJob); +app.use(routerReport); +app.use(routerCron); +app.use(routerChangefile); +app.use(routerSnapshot); + +// Errors and unknown routes +app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}: this route does not exist.` })); + +app.use((error, req, res, next) => res.status(500).json({ message: error.message })); + +app.listen(3000, async () => { + appLogger.info('[express]: ezunpaywall update service listening on 3000'); + getConfig(); + if (cronFile.active) { + cronFile.start(); + } + + if (dataUpdate.cron.active) { + dataUpdate.cron.start(); + } + + if (dataUpdateHistoryCron.cron.active) { + dataUpdateHistoryCron.cron.start(); + } + if (cronDownloadSnapshot.active) { + cronDownloadSnapshot.start(); + } +}); diff --git a/src/update/certs/.gitkeep b/services/update/certs/.gitkeep similarity index 100% rename from src/update/certs/.gitkeep rename to services/update/certs/.gitkeep diff --git a/services/update/config/custom-environment-variables.json b/services/update/config/custom-environment-variables.json new file mode 100644 index 00000000..5ec5e4b5 --- /dev/null +++ b/services/update/config/custom-environment-variables.json @@ -0,0 +1,51 @@ +{ + "nodeEnv": "NODE_ENV", + "accessLogRotate": "ACCESS_LOG_ROTATE", + "timezone": "TIMEZONE", + "unpaywall": { + "host": "UNPAYWALL_HOST", + "apikey": "UNPAYWALL_APIKEY" + }, + "mail": { + "host": "MAIL_HOST", + "apikey": "MAIL_APIKEY" + }, + "elasticsearch": { + "host": "ELASTICSEARCH_HOSTS", + "port": "ELASTICSEARCH_PORT", + "user": "ELASTICSEARCH_USERNAME", + "password": "ELASTICSEARCH_PASSWORD", + "maxBulkSize": "ELASTICSEARCH_MAX_BULK_SIZE", + "indexAlias": "ELASTICSEARCH_INDEX_ALIAS", + "timeout": "ELASTICSEARCH_TIMEOUT" + }, + "cron": { + "downloadSnapshot": { + "schedule": "CRON_DOWNLOAD_SNAPSHOT_SCHEDULE", + "active": "CRON_DOWNLOAD_SNAPSHOT_ACTIVE", + "index": "CRON_DOWNLOAD_SNAPSHOT_INDEX" + }, + "dataUpdate": { + "schedule": "CRON_DATA_UPDATE_SCHEDULE", + "active": "CRON_DATA_UPDATE_ACTIVE", + "index": "CRON_DATA_UPDATE_INDEX", + "interval": "CRON_DATA_UPDATE_INTERVAL" + }, + "dataUpdateHistory": { + "schedule": "CRON_DATA_UPDATE_SCHEDULE", + "active": "CRON_DATA_UPDATE_ACTIVE", + "indexBase": "CRON_DATA_UPDATE_INDEX_BASE", + "indexHistory": "CRON_DATA_UPDATE_INDEX_HISTORY", + "interval": "CRON_DATA_UPDATE_INTERVAL" + }, + "cleanFile": { + "schedule": "CRON_CLEAN_FILE_SCHEDULE", + "active": "CRON_CLEAN_FILE_ACTIVE", + "changefileThreshold": "CRON_CLEAN_FILE_CHANGEFILE_THRESHOLD", + "reportThreshold": "CRON_CLEAN_FILE_REPORT_THRESHOLD", + "snapshotThreshold": "CRON_CLEAN_FILE_SNAPSHOT_THRESHOLD" + } + }, + "apikey": "ADMIN_APIKEY", + "healthTimeout": "HEALTH_TIMEOUT" +} \ No newline at end of file diff --git a/services/update/config/default.json b/services/update/config/default.json new file mode 100644 index 00000000..2428b053 --- /dev/null +++ b/services/update/config/default.json @@ -0,0 +1,64 @@ +{ + "nodeEnv": "development", + "accessLogRotate": false, + "healthcheckLogRotate": false, + "timezone": "Europe/Paris", + "unpaywall": { + "host": "http://fakeunpaywall:3000", + "apikey": "default" + }, + "mail": { + "host": "http://mail:3000", + "apikey": "changeme" + }, + "elasticsearch": { + "host": "http://elastic", + "port": 9200, + "user": "elastic", + "password": "changeme", + "maxBulkSize": 4000, + "indexAlias": "upw", + "timeout": 20000 + }, + "cron": { + "downloadSnapshot": { + "schedule": "0 0 0 1 * *", + "active": true, + "index": "unpaywall" + }, + "dataUpdate": { + "schedule": "0 0 0 * * *", + "active": false, + "index": "unpaywall", + "interval": "day" + }, + "dataUpdateHistory": { + "schedule": "0 0 0 * * *", + "active": true, + "indexBase": "unpaywall-base", + "indexHistory": "unpaywall-history", + "interval": "day" + }, + "cleanFile": { + "schedule": "0 0 0 * * *", + "active": true, + "changefileThreshold": 30, + "reportThreshold": 30, + "snapshotThreshold": 150 + } + }, + "paths": { + "log": { + "applicationDir": "./log/application", + "accessDir": "./log/access", + "healthCheckDir": "./log/healthcheck" + }, + "data": { + "changefilesDir": "./data/changefiles", + "snapshotsDir": "./data/snapshots", + "reportsDir": "./data/reports" + } + }, + "apikey": "changeme", + "healthTimeout": 3000 +} \ No newline at end of file diff --git a/services/update/doc/activity-diagram-update.png b/services/update/doc/activity-diagram-update.png new file mode 100644 index 00000000..5bd8c122 Binary files /dev/null and b/services/update/doc/activity-diagram-update.png differ diff --git a/services/update/mapping/unpaywall-base.json b/services/update/mapping/unpaywall-base.json new file mode 100644 index 00000000..be9f88db --- /dev/null +++ b/services/update/mapping/unpaywall-base.json @@ -0,0 +1,227 @@ +{ + "settings": { + "number_of_shards": 3 + }, + "mappings": { + "dynamic_templates": [ + { + "strings_as_keywords": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword" + } + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "best_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "data_standard": { + "type": "long" + }, + "doi": { + "type": "keyword" + }, + "doi_url": { + "type": "keyword" + }, + "first_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "genre": { + "type": "keyword" + }, + "has_repository_copy": { + "type": "boolean" + }, + "is_oa": { + "type": "boolean" + }, + "is_paratext": { + "type": "boolean" + }, + "journal_is_in_doaj": { + "type": "boolean" + }, + "journal_is_oa": { + "type": "boolean" + }, + "journal_issn_l": { + "type": "keyword" + }, + "journal_issns": { + "type": "keyword" + }, + "journal_name": { + "type": "keyword" + }, + "oa_locations": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "oa_status": { + "type": "keyword" + }, + "published_date": { + "type": "date", + "format": "iso8601" + }, + "publisher": { + "type": "keyword" + }, + "referencedAt": { + "type": "date" + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date", + "format": "iso8601" + }, + "year": { + "type": "keyword" + }, + "z_authors": { + "properties": { + "family": { + "type": "keyword" + }, + "given": { + "type": "keyword" + }, + "sequence": { + "type": "keyword" + }, + "ORCID": { + "type": "keyword" + }, + "authenticated-orcid": { + "type": "boolean" + }, + "affiliation": { + "properties": { + "name": { + "type": "keyword" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/services/update/mapping/unpaywall-history.json b/services/update/mapping/unpaywall-history.json new file mode 100644 index 00000000..8c11a002 --- /dev/null +++ b/services/update/mapping/unpaywall-history.json @@ -0,0 +1,233 @@ +{ + "settings": { + "number_of_shards": 3 + }, + "mappings": { + "dynamic_templates": [ + { + "strings_as_keywords": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword" + } + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "best_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "date": { + "type": "date" + }, + "data_standard": { + "type": "long" + }, + "doi": { + "type": "keyword" + }, + "doi_url": { + "type": "keyword" + }, + "endValidity": { + "type": "date" + }, + "first_oa_location": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "genre": { + "type": "keyword" + }, + "has_repository_copy": { + "type": "boolean" + }, + "is_oa": { + "type": "boolean" + }, + "is_paratext": { + "type": "boolean" + }, + "journal_is_in_doaj": { + "type": "boolean" + }, + "journal_is_oa": { + "type": "boolean" + }, + "journal_issn_l": { + "type": "keyword" + }, + "journal_issns": { + "type": "keyword" + }, + "journal_name": { + "type": "keyword" + }, + "oa_locations": { + "properties": { + "endpoint_id": { + "type": "keyword" + }, + "evidence": { + "type": "keyword" + }, + "host_type": { + "type": "keyword" + }, + "is_best": { + "type": "boolean" + }, + "license": { + "type": "keyword" + }, + "pmh_id": { + "type": "keyword" + }, + "repository_institution": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "url": { + "type": "keyword" + }, + "url_for_landing_page": { + "type": "keyword" + }, + "url_for_pdf": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "oa_status": { + "type": "keyword" + }, + "published_date": { + "type": "date", + "format": "iso8601" + }, + "publisher": { + "type": "keyword" + }, + "referencedAt": { + "type": "date" + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date", + "format": "iso8601" + }, + "year": { + "type": "keyword" + }, + "z_authors": { + "properties": { + "family": { + "type": "keyword" + }, + "given": { + "type": "keyword" + }, + "sequence": { + "type": "keyword" + }, + "ORCID": { + "type": "keyword" + }, + "authenticated-orcid": { + "type": "boolean" + }, + "affiliation": { + "properties": { + "name": { + "type": "keyword" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/update/mapping/unpaywall.json b/services/update/mapping/unpaywall.json similarity index 100% rename from src/update/mapping/unpaywall.json rename to services/update/mapping/unpaywall.json diff --git a/services/update/openapi.yml b/services/update/openapi.yml new file mode 100644 index 00000000..859804fe --- /dev/null +++ b/services/update/openapi.yml @@ -0,0 +1,910 @@ +openapi: 3.0.0 +info: + description: 'The update service allows to update the mirror data. This service queries unpaywall to get the snapshots and inserts their content in an elasticsearch index.' + version: 1.0.0 + title: Update service + contact: + email: ezteam@couperin.org + name: ezTeam + license: + name: CeCILL 2.1 + url: http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html +servers: + - url: https://unpaywall.inist.fr/api +tags: + - name: cron + - name: job + - name: ping +paths: + /update: + get: + tags: + - ping + operationId: get-update + summary: Name of service. + description: Get name of update service. + responses: + '200': + description: OK + content: + application/json: + examples: + response: + value: + message: update service + + /update/ping: + get: + operationId: get-update-ping + summary: Ping update service. + description: Ping update service. + tags: + - ping + responses: + '204': + description: No Content + + /update/health: + get: + tags: + - ping + operationId: get-update-health + summary: Health. + description: Health on all service connected to update service. + parameters: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + redis: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elastic: + type: object + properties: + elapsedTime: + type: integer + status: + type: boolean + elapsedTime: + type: integer + status: + type: boolean + x-examples: + Example 1: + redis: + elapsedTime: 1 + status: true + elastic: + elapsedTime: 1 + status: true + elapsedTime: 1 + status: true + examples: + Success: + value: + redis: + elapsedTime: 1 + status: true + elastic: + elapsedTime: 1 + status: true + elapsedTime: 1 + status: true + Error redis: + value: + redis: + elapsedTime: 3001 + status: false + error: time out + elastic: + elapsedTime: 1 + status: true + elapsedTime: 3001 + status: false + + /update/health/redis: + get: + tags: + - ping + operationId: get-update-health-redis + summary: Health on redis service. + description: Health on redis. + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + /update/health/elastic: + get: + tags: + - ping + operationId: get-update-health-elastic + summary: Health on elastic service. + description: Health on elastic. + parameters: [] + responses: + '200': + $ref: '#/components/responses/Health' + + /update/job/snapshot: + post: + tags: + - job + operationId: post-update-job-snapshot + summary: Start process download and insert snapshot from unpaywall. + description: Download and insert the latest snapshot from unpaywall.org. + security: + - x-api-key: [] + requestBody: + content: + application/json: + schema: + type: object + required: + - userName + properties: + interval: + type: string + description: index where the unpaywall data will be inserted. + responses: + '202': + $ref: '#/components/responses/Accepted' + '401': + $ref: '#/components/responses/Not-authorized' + '409': + $ref: '#/components/responses/Conflict' + + /update/job/download/insert/changefile/period: + post: + tags: + - job + operationId: post-update-job-period + summary: Start process download and insert changefiles from unpaywall. + description: Download and insert changefiles from unpaywall.org. + security: + - x-api-key: [] + requestBody: + description: config for process + content: + application/json: + schema: + type: object + required: + - userName + properties: + index: + type: string + interval: + type: string + startDate: + type: string + endDate: + type: string + ignoreError: + type: boolean + cleanFile: + type: boolean + responses: + '202': + $ref: '#/components/responses/Accepted' + '400': + description: startDate cannot be in the futur or endDate cannot be lower than startDate. + '401': + $ref: '#/components/responses/Not-authorized' + '409': + $ref: '#/components/responses/Conflict' + + /update/job/insert/changefile/${filename}: + post: + tags: + - job + operationId: post-update-job-changefile-$-filename + summary: Start process insert changesfiles downloaded on ezunpaywall. + description: Insert changefiles already downloaded on ezunpaywall. + security: + - x-api-key: [] + parameters: + - in: path + name: filename + description: filename + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + type: object + properties: + index: + type: string + offset: + type: integer + limit: + type: integer + ignoreError: + type: boolean + cleanFile: + type: boolean + description: config for process + responses: + '202': + $ref: '#/components/responses/Accepted' + '400': + description: startDate cannot be in the futur or endDate cannot be lower than startDate. + content: + application/json: + examples: + response: + value: + message: startDate cannot be in the futur or endDate cannot be lower than startDate. + '401': + $ref: '#/components/responses/Not-authorized' + '404': + $ref: '#/components/responses/File-not-found' + '409': + $ref: '#/components/responses/Conflict' + + /update/job/download/insert/history/period: + post: + tags: + - job + operationId: post-update-job-history + summary: Start process download and insert changefiles from unpaywall and feed history. + description: Download and insert changefiles from unpaywall.org and feed history. + security: + - x-api-key: [] + requestBody: + description: config for process + content: + application/json: + schema: + type: object + required: + - userName + properties: + index: + type: string + interval: + type: string + startDate: + type: string + endDate: + type: string + responses: + '202': + $ref: '#/components/responses/Accepted' + '400': + description: startDate cannot be in the futur or endDate cannot be lower than startDate. + '401': + $ref: '#/components/responses/Not-authorized' + '409': + $ref: '#/components/responses/Conflict' + + /update/job/reset: + post: + tags: + - job + operationId: post-update-job-reset + summary: Start process that roll back the current and the history index according to a date. + description: roll back the current and the history index according to a date. + security: + - x-api-key: [] + requestBody: + description: config for process + content: + application/json: + schema: + type: object + required: + - userName + properties: + index: + type: string + startDate: + type: string + responses: + '202': + $ref: '#/components/responses/Accepted' + '400': + description: startDate required + '401': + $ref: '#/components/responses/Not-authorized' + '409': + $ref: '#/components/responses/Conflict' + + /update/reports/${type}: + get: + tags: + - job + operationId: get-update-reports + summary: Get reports. + description: Get list of reports or latest report. + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + - in: query + name: latest + description: latest + required: false + schema: + type: boolean + responses: + '200': + description: report + content: + List of reports: + examples: + response: + value: + - 2022-10-10 13:10:51.json + - 2022-10-10 13:10:50.json + - 2022-10-10 13:10:49.json + - 2022-10-10 13:10:48.json + - 2022-10-10 13:10:47.json + - 2022-10-10 13:10:46.json + - 2022-10-10 13:10:45.json + - 2022-10-10 13:10:44.json + Latest report: + examples: + response: + value: + done: true + createdAt: '2022-10-10T13:10:46.828Z' + endAt: '2022-10-10T13:10:47.084Z' + steps: + - task: getChangefiles + took: 0.002 + status: success + - task: download + file: fake2.jsonl.gz + percent: 100 + took: 0 + status: success + - task: insert + index: unpaywall-test + file: fake2.jsonl.gz + linesRead: 100 + addedDocs: 100 + updatedDocs: 0 + failedDocs: 0 + percent: 100 + took: 0.202 + status: success + error: false + took: 0.256 + + /update/reports/${type}/${filename}: + get: + tags: + - job + operationId: get-update-reports-$-filename + summary: Get report. + description: Get report with his filename. + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + - in: path + name: filename + description: filename + required: true + schema: + type: string + responses: + '200': + description: report + content: + application/json: + schema: + type: object + x-examples: + example-1: + done: true + createdAt: '2022-10-10T13:10:46.828Z' + endAt: '2022-10-10T13:10:47.084Z' + steps: + - task: getChangefiles + took: 0.002 + status: success + - task: download + file: fake2.jsonl.gz + percent: 100 + took: 0 + status: success + - task: insert + index: unpaywall-test + file: fake2.jsonl.gz + linesRead: 100 + addedDocs: 100 + updatedDocs: 0 + failedDocs: 0 + percent: 100 + took: 0.202 + status: success + error: false + took: 0.256 + Report: + examples: + response: + value: + done: true + createdAt: '2022-10-10T13:10:46.828Z' + endAt: '2022-10-10T13:10:47.084Z' + steps: + - task: getChangefiles + took: 0.002 + status: success + - task: download + file: fake2.jsonl.gz + percent: 100 + took: 0 + status: success + - task: insert + index: unpaywall-test + file: fake2.jsonl.gz + linesRead: 100 + addedDocs: 100 + updatedDocs: 0 + failedDocs: 0 + percent: 100 + took: 0.202 + status: success + error: false + took: 0.256 + '404': + $ref: '#/components/responses/File-not-found' + + /update/snapshots: + get: + tags: + - job + operationId: get-update-snapshots + summary: Get snapshots. + description: Get list of snapshot or latest snapshot. + security: + - x-api-key: [] + parameters: + - in: query + name: latest + description: latest + required: false + schema: + type: boolean + responses: + '200': + description: snapshot + content: + Lists of snapshots: + examples: + response: + value: + - snapshot-2022-10-10.jsonl.gz + '401': + $ref: '#/components/responses/Not-authorized' + + /update/snapshots/${filename}: + get: + tags: + - job + operationId: get-update-snapshots-$-filename + summary: Get snapshot. + description: Get snapshot with his filename. + security: + - x-api-key: [] + parameters: + - in: path + name: filename + description: filename + required: true + schema: + type: string + responses: + '200': + description: snapshot + '401': + $ref: '#/components/responses/Not-authorized' + '404': + $ref: '#/components/responses/File-not-found' + + /update/states: + get: + tags: + - job + operationId: get-update-states + summary: Get state. + description: Get latest state. + responses: + '200': + description: state + content: + Latest state: + examples: + response: + value: + done: true + createdAt: '2022-10-10T13:10:51.417Z' + endAt: '2022-10-10T13:10:51.584Z' + steps: + - task: getChangefiles + took: 0.002 + status: success + - task: insert + index: unpaywall-test + file: fake1.jsonl.gz + linesRead: 50 + addedDocs: 50 + updatedDocs: 0 + failedDocs: 0 + percent: 100 + took: 0.165 + status: success + error: false + took: 0.167 + + /update/status: + get: + tags: + - job + summary: Get status + operationId: get-update-status + description: Get status + responses: + '200': + description: status + content: + No process in progress: + examples: + response: + value: false + Update in progress: + examples: + response: + value: true + + /update/unpaywall/changefiles: + get: + tags: + - job + operationId: get-update-unpaywall-changefiles + summary: Get changefiles from unpaywall. + description: Get changefiles from unpaywall. + security: + - x-api-key: [] + parameters: + - in: query + name: interval + description: interval of changefiles ("week" or "day") + required: false + schema: + type: string + responses: + '200': + description: status + content: + List of daily changefiles of unpaywall: + examples: + response: + value: + - date: '2022-10-10T00:00:00.000Z' + filename: fake1.jsonl.gz + filetype: jsonl + last_modified: '2021-10-09T13:10:50.000Z' + lines: 50 + size: 19896 + url: http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz + - date: '2022-10-09T00:00:00.000Z' + filename: fake2.jsonl.gz + filetype: jsonl + last_modified: '2022-10-09T13:10:50.000Z' + lines: 100 + size: 44137 + url: http://fakeUnpaywall:3000/daily-feed/changefiles/fake2.jsonl.gz + - date: '2022-10-08T00:00:00.000Z' + filename: fake3.jsonl.gz + filetype: jsonl + last_modified: '2022-10-08T13:10:50.000Z' + lines: 2000 + size: 877494 + url: http://fakeUnpaywall:3000/daily-feed/changefiles/fake3.jsonl.gz + List of weekly changefiles of unpaywall: + examples: + response: + value: + - date: '2022-10-10T00:00:00.000Z' + filename: fake1.jsonl.gz + filetype: jsonl + last_modified: '2021-10-09T13:10:50.000Z' + lines: 50 + size: 19896 + url: http://fakeUnpaywall:3000/feed/changefiles/fake1.jsonl.gz + - date: '2022-10-09T00:00:00.000Z' + filename: fake2.jsonl.gz + filetype: jsonl + last_modified: '2022-10-09T13:10:50.000Z' + lines: 100 + size: 44137 + url: http://fakeUnpaywall:3000/feed/changefiles/fake2.jsonl.gz + - date: '2022-10-08T00:00:00.000Z' + filename: fake3.jsonl.gz + filetype: jsonl + last_modified: '2022-10-08T13:10:50.000Z' + lines: 2000 + size: 877494 + url: http://fakeUnpaywall:3000/feed/changefiles/fake3.jsonl.gz + '401': + $ref: '#/components/responses/Not-authorized' + + /update/cron/${type}/start: + post: + tags: + - cron + operationId: post-cron-start + summary: Start cron. + description: Start update cron. + security: + - x-api-key: [] + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + responses: + '202': + $ref: '#/components/responses/Accepted' + '401': + $ref: '#/components/responses/Not-authorized' + + + + /update/cron/${type}/stop: + post: + tags: + - cron + operationId: post-cron-stop + description: Stop cron. + summary: Stop cron. + security: + - x-api-key: [] + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + responses: + '202': + $ref: '#/components/responses/Accepted' + '401': + $ref: '#/components/responses/Not-authorized' + + /update/cron/${type}: + patch: + tags: + - cron + operationId: patch-cron + summary: update cron. + description: update cron. + security: + - x-api-key: [] + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + config: + type: object + properties: + time: + type: string + status: + type: boolean + index: + type: string + interval: + type: string + x-examples: + example-1: + config: + time: '* * * * * *' + status: false + index: unpaywall + interval: day + examples: + updated: + value: + config: + time: '* 30 12-15 * * *' + status: true + index: unpaywall + interval: day + '401': + $ref: '#/components/responses/Not-authorized' + requestBody: + content: + application/json: + schema: + type: object + properties: + time: + type: string + index: + type: string + interval: + type: string + x-examples: + example-1: + time: '' + index: '' + interval: '' + examples: + daily: + value: + time: 0 0 0 * * * + index: unpaywall + interval: day + weekly: + value: + time: 0 0 0 * * 0 + index: unpaywall + interval: weekly + + get: + tags: + - cron + operationId: get-cron + summary: Get config of cron. + description: Get config of cron. + parameters: + - in: path + name: type + description: type of report (unpaywall or unpaywallHistory) + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + config: + type: object + properties: + time: + type: string + status: + type: boolean + index: + type: string + interval: + type: string + x-examples: + example-1: + config: + time: '* * * * * *' + status: false + index: unpaywall + interval: day + examples: + day: + value: + config: + time: 0 0 0 * * * + status: true + index: unpaywall + interval: day + week: + value: + config: + time: 0 0 0 * * * + status: true + index: unpaywall + interval: day + off: + value: + config: + time: 0 0 0 * * * + status: false + index: unpaywall + interval: day + +components: + responses: + Accepted: + description: Accepted + headers: {} + Not-authorized: + description: Not authorized + headers: {} + content: + application/json: + examples: + response: + value: + message: Not authorized + Conflict: + description: Conflict + headers: {} + content: + application/json: + examples: + response: + value: + message: Update in progress. + File-not-found: + description: File not found + headers: {} + content: + application/json: + examples: + response: + value: + message: File not found. + Health: + description: Example response + content: + application/json: + schema: + type: object + properties: + name: + type: string + status: + type: boolean + elapsedTime: + type: integer + x-examples: + Example 1: + name: redis + status: true + elapsedTime: 1 + examples: + Success: + value: + name: name of service + status: true + elapsedTime: 1 + Error redis: + value: + name: redis + elapsedTime: 3002 + error: time out + status: false + securitySchemes: + x-api-key: + type: apiKey + in: header + name: API Key + schemas: {} diff --git a/src/update/package-lock.json b/services/update/package-lock.json similarity index 99% rename from src/update/package-lock.json rename to services/update/package-lock.json index 50da37d0..6e36b3d9 100644 --- a/src/update/package-lock.json +++ b/services/update/package-lock.json @@ -1,12 +1,12 @@ { "name": "ezunpaywall-update", - "version": "1.3.0", + "version": "1.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ezunpaywall-update", - "version": "1.3.0", + "version": "1.3.5", "license": "CeCILL", "dependencies": { "@elastic/elasticsearch": "^7.13.0", @@ -4819,8 +4819,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", diff --git a/src/update/package.json b/services/update/package.json similarity index 100% rename from src/update/package.json rename to services/update/package.json diff --git a/src/update/lib/config.js b/services/update/src/config.js similarity index 95% rename from src/update/lib/config.js rename to services/update/src/config.js index ea9ab281..e6432d86 100644 --- a/src/update/lib/config.js +++ b/services/update/src/config.js @@ -1,6 +1,6 @@ const config = require('config'); -const logger = require('./logger'); +const logger = require('./logger/appLogger'); const defaultConfig = require('../config/default.json'); const copyConfig = JSON.parse(JSON.stringify(config)); diff --git a/services/update/src/controllers/changefile.js b/services/update/src/controllers/changefile.js new file mode 100644 index 00000000..35d39de0 --- /dev/null +++ b/services/update/src/controllers/changefile.js @@ -0,0 +1,69 @@ +const fs = require('fs-extra'); +const path = require('path'); +const { paths } = require('config'); + +const { getMostRecentFile, deleteFile } = require('../lib/files'); + +/** + * Controller to start list of files or latest file downloaded on update service. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function getChangefiles(req, res, next) { + const { latest } = req.data; + + if (latest) { + let latestChangefile; + try { + latestChangefile = await getMostRecentFile(paths.data.changefilesDir); + } catch (err) { + return next({ message: 'Cannot get the latest changefile' }); + } + return res.status(200).json(latestChangefile?.filename); + } + const files = await fs.readdir(paths.data.changefilesDir); + return res.status(200).json(files); +} + +/** + * Controller to upload a file with unpaywall data. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function uploadChangefile(req, res, next) { + if (!req?.file) return next({ message: 'File not sent' }); + return res.status(202).json(); +} + +/** + * Controller to delete file that content unpaywall data. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function deleteChangefile(req, res, next) { + const { filename } = req.data; + + if (!await fs.pathExists(path.resolve(paths.data.changefilesDir, filename))) { + return res.status(404).json({ message: `File [${filename}] not found` }); + } + + try { + await deleteFile(path.resolve(paths.data.changefilesDir, filename)); + } catch (err) { + return next({ message: err.message }); + } + + return res.status(202).json(); +} + +module.exports = { + getChangefiles, + uploadChangefile, + deleteChangefile, +}; diff --git a/services/update/src/controllers/cron.js b/services/update/src/controllers/cron.js new file mode 100644 index 00000000..6dbed3ca --- /dev/null +++ b/services/update/src/controllers/cron.js @@ -0,0 +1,130 @@ +const cronValidator = require('cron-validator'); +const dataUpdate = require('../cron/dataUpdate'); +const dataUpdateHistoryCron = require('../cron/dataUpdateHistory'); + +/** + * Controller to start update cron. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function startCron(req, res, next) { + const { type } = req.data; + + if (type === 'dataUpdate') { + try { + dataUpdate.cron.start(); + } catch (err) { + return next(err); + } + } + + if (type === 'dataUpdateHistory') { + try { + dataUpdateHistoryCron.cron.start(); + } catch (err) { + return next(err); + } + } + + return res.status(202).json(); +} + +/** + * Controller to stop update cron. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function stopCron(req, res, next) { + const { type } = req.data; + + if (type === 'dataUpdate') { + try { + dataUpdate.cron.stop(); + } catch (err) { + return next(err); + } + } + + if (type === 'dataUpdateHistory') { + try { + dataUpdateHistoryCron.cron.stop(); + } catch (err) { + return next(err); + } + } + + return res.status(202).json(); +} + +/** + * Controller to update config of update cron. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function patchCron(req, res, next) { + const { cronConfig, type } = req.data; + const { schedule } = cronConfig; + + if (schedule) { + const validCron = cronValidator.isValidCron(schedule, { seconds: true }); + if (!validCron) { return res.status(400).json('schedule is invalid'); } + } + + let config; + + if (type === 'dataUpdate') { + try { + dataUpdate.update(cronConfig); + } catch (err) { + return next(err); + } + + config = dataUpdate.getGlobalConfig(); + } + + if (type === 'dataUpdateHistory') { + try { + dataUpdateHistoryCron.update(cronConfig); + } catch (err) { + return next(err); + } + config = dataUpdateHistoryCron.getGlobalConfig(); + } + + return res.status(200).json(config); +} + +/** + * Controller to get config of update cron. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function getConfigCron(req, res) { + const { type } = req.data; + + let config; + + if (type === 'dataUpdate') { + config = dataUpdate.getGlobalConfig(); + } + + if (type === 'dataUpdateHistory') { + config = dataUpdateHistoryCron.getGlobalConfig(); + } + + return res.status(200).json(config); +} +module.exports = { + startCron, + stopCron, + patchCron, + getConfigCron, +}; diff --git a/services/update/src/controllers/elastic.js b/services/update/src/controllers/elastic.js new file mode 100644 index 00000000..402ef2d9 --- /dev/null +++ b/services/update/src/controllers/elastic.js @@ -0,0 +1,61 @@ +const elastic = require('../services/elastic'); +const unpaywallMapping = require('../../mapping/unpaywall.json'); + +/** + * Controller to create alias unpaywall on elastic. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function createAlias(req, res, next) { + try { + await elastic.initAlias('unpaywall', unpaywallMapping, 'upw'); + } catch (err) { + return next(err); + } + + return res.status(202).end(); +} + +/** + * Controller to get indices on elastic. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function getIndices(req, res, next) { + let indices; + try { + indices = await elastic.getIndices(); + } catch (err) { + return next(err); + } + + return res.status(200).json(indices); +} + +/** + * Controller to get alias on elastic. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function getAlias(req, res, next) { + let alias; + try { + alias = await elastic.getAlias(); + } catch (err) { + return next(err); + } + + return res.status(200).json(alias); +} + +module.exports = { + createAlias, + getIndices, + getAlias, +}; diff --git a/src/update/lib/controllers/health.js b/services/update/src/controllers/health.js similarity index 82% rename from src/update/lib/controllers/health.js rename to services/update/src/controllers/health.js index 1960ff3f..09ce8c8b 100644 --- a/src/update/lib/controllers/health.js +++ b/services/update/src/controllers/health.js @@ -1,5 +1,7 @@ const promiseWithTimeout = require('../ping'); const { pingElastic } = require('../services/elastic'); +const { pingMail } = require('../services/mail'); +const { pingUnpaywall } = require('../services/unpaywall'); /** * Controller to get health of all services connected to update service. @@ -12,8 +14,10 @@ async function health(req, res, next) { const start = Date.now(); const p1 = promiseWithTimeout(pingElastic(), 'elastic'); + const p2 = promiseWithTimeout(pingMail(), 'mail'); + const p3 = promiseWithTimeout(pingUnpaywall(), 'unpaywall'); - let resultPing = await Promise.allSettled([p1]); + let resultPing = await Promise.allSettled([p1, p2, p3]); resultPing = resultPing.map((e) => e.value); const result = {}; diff --git a/services/update/src/controllers/job.js b/services/update/src/controllers/job.js new file mode 100644 index 00000000..38c7b73c --- /dev/null +++ b/services/update/src/controllers/job.js @@ -0,0 +1,206 @@ +const fs = require('fs-extra'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths } = require('config'); + +const { + downloadSnapshotProcess, + downloadAndInsertSnapshotProcess, + insertChangefilesOnPeriodProcess, + insertChangefileProcess, + insertWithOaHistoryProcess, +} = require('../process'); + +const { rollBack } = require('../process/history'); + +/** + * Controller to start job that download snapshot. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function downloadSnapshotJob(req, res, next) { + downloadSnapshotProcess(); + return res.status(202).json(); +} + +/** + * Controller to start job that download and insert snapshot. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function downloadAndInsertSnapshotJob(req, res, next) { + const { index } = req.data; + + const jobConfig = { + type: 'snapshot', + index, + offset: 0, + limit: -1, + }; + + downloadAndInsertSnapshotProcess(jobConfig); + return res.status(202).json(); +} + +/** + * Controller to start job that download ans insert changefiles on period. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function insertChangefilesOnPeriodJob(req, res, next) { + const { jobConfig } = req.data; + + const { + startDate, + endDate, + interval, + } = jobConfig; + + if (new Date(startDate).getTime() > Date.now()) { + return res.status(400).json({ message: 'startDate cannot be in the future' }); + } + + if (startDate && endDate) { + if (new Date(endDate).getTime() < new Date(startDate).getTime()) { + return res.status(400).json({ message: 'endDate cannot be lower than startDate' }); + } + } + + jobConfig.type = 'changefile'; + jobConfig.offset = 0; + jobConfig.limit = -1; + + if (!startDate && !endDate) { + jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); + if (interval === 'week') jobConfig.startDate = format(new Date() - (7 * 24 * 60 * 60 * 1000), 'yyyy-MM-dd'); + if (interval === 'day') jobConfig.startDate = format(new Date(), 'yyyy-MM-dd'); + + insertChangefilesOnPeriodProcess(jobConfig); + return res.status(202).json(); + } + + if (startDate && !endDate) jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); + + insertChangefilesOnPeriodProcess(jobConfig); + return res.status(202).json(); +} + +/** + * Controller to start job that insert changefile already installed. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function insertChangefileJob(req, res, next) { + const { jobConfig } = req.data; + + const { filename } = jobConfig; + if (!await fs.pathExists(path.resolve(paths.data.changefilesDir, filename))) { + return res.status(404).json({ message: `File [${filename}] not found` }); + } + + jobConfig.type = 'changefile'; + + insertChangefileProcess(jobConfig); + + return res.status(202).json(); +} + +/** + * Controller to start job that insert snapshot already installed. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function insertSnapshotJob(req, res, next) { + const { jobConfig } = req.data; + + const { filename } = jobConfig; + + if (!await fs.pathExists(path.resolve(paths.data.snapshotsDir, filename))) { + return res.status(404).json({ message: `File [${filename}] not found` }); + } + + jobConfig.type = 'snapshot'; + + insertChangefileProcess(jobConfig); + + return res.status(202).json(); +} + +/** + * Controller to start job that download ans insert changefiles on period. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function insertWithOaHistory(req, res, next) { + const { jobConfig } = req.data; + + const { + startDate, + endDate, + interval, + } = jobConfig; + + if (new Date(startDate).getTime() > Date.now()) { + return res.status(400).json({ message: 'startDate cannot be in the future' }); + } + + if (startDate && endDate) { + if (new Date(endDate).getTime() < new Date(startDate).getTime()) { + return res.status(400).json({ message: 'endDate cannot be lower than startDate' }); + } + } + + jobConfig.type = 'changefile'; + jobConfig.offset = 0; + jobConfig.limit = -1; + + if (!startDate && !endDate) { + jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); + if (interval === 'week') jobConfig.startDate = format(new Date() - (7 * 24 * 60 * 60 * 1000), 'yyyy-MM-dd'); + if (interval === 'day') jobConfig.startDate = format(new Date(), 'yyyy-MM-dd'); + + insertWithOaHistoryProcess(jobConfig); + return res.status(202).json(); + } + + if (startDate && !endDate) jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); + + insertWithOaHistoryProcess(jobConfig); + return res.status(202).json(); +} + +/** + * Controller to start job that download ans insert changefiles on period. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function historyRollBack(req, res, next) { + const { startDate, indexBase, indexHistory } = req.data.rollBackConfig; + + await rollBack(startDate, indexBase, indexHistory); + return res.status(202).json(); +} + +module.exports = { + downloadSnapshotJob, + downloadAndInsertSnapshotJob, + insertChangefilesOnPeriodJob, + insertChangefileJob, + insertSnapshotJob, + insertWithOaHistory, + historyRollBack, +}; diff --git a/src/update/lib/controllers/report.js b/services/update/src/controllers/report.js similarity index 74% rename from src/update/lib/controllers/report.js rename to services/update/src/controllers/report.js index c8a0f83e..19c63529 100644 --- a/src/update/lib/controllers/report.js +++ b/services/update/src/controllers/report.js @@ -1,10 +1,9 @@ const path = require('path'); const fs = require('fs-extra'); +const { paths } = require('config'); -const { getMostRecentFile } = require('../file'); -const { getReport } = require('../report'); - -const reportsDir = path.resolve(__dirname, '..', '..', 'data', 'reports'); +const { getMostRecentFile } = require('../lib/files'); +const { getReport } = require('../lib/report'); /** * Controller to get list of reports or latest report. @@ -14,12 +13,12 @@ const reportsDir = path.resolve(__dirname, '..', '..', 'data', 'reports'); * @param {import('express').NextFunction} next - Do the following. */ async function getReports(req, res, next) { - const latest = req.data; + const { latest, type } = req.data; if (latest) { let latestFile; try { - latestFile = await getMostRecentFile(reportsDir); + latestFile = await getMostRecentFile(paths.data.reportsDir); } catch (err) { return next({ message: err.message }); } @@ -37,14 +36,18 @@ async function getReports(req, res, next) { return res.status(200).json(report); } - let reports = await fs.readdir(reportsDir); + let reports = await fs.readdir(paths.data.reportsDir); reports = reports.sort((a, b) => { - const [date1] = a.split('.'); - const [date2] = b.split('.'); + const [date1] = a.split('_'); + const [date2] = b.split('_'); return new Date(date2).getTime() - new Date(date1).getTime(); }); + if (type) { + reports = reports.filter((report) => report.includes(`${type}.`)); + } + return res.status(200).json(reports); } @@ -56,10 +59,10 @@ async function getReports(req, res, next) { * @param {import('express').NextFunction} next - Do the following. */ async function getReportByFilename(req, res, next) { - const filename = req.data; + const { filename } = req.data; try { - await fs.stat(path.resolve(reportsDir, filename)); + await fs.stat(path.resolve(paths.data.reportsDir, filename)); } catch (err) { return next({ message: `File [${filename}] not found` }); } diff --git a/src/update/lib/controllers/file.js b/services/update/src/controllers/snapshot.js similarity index 62% rename from src/update/lib/controllers/file.js rename to services/update/src/controllers/snapshot.js index a6a04027..3cccd166 100644 --- a/src/update/lib/controllers/file.js +++ b/services/update/src/controllers/snapshot.js @@ -1,12 +1,8 @@ const fs = require('fs-extra'); const path = require('path'); +const { paths } = require('config'); -const snapshotsDir = path.resolve(__dirname, '..', '..', 'data', 'snapshots'); - -const { - getMostRecentFile, - deleteFile, -} = require('../file'); +const { getMostRecentFile, deleteFile } = require('../lib/files'); /** * Controller to start list of files or latest file downloaded on update service. @@ -15,19 +11,19 @@ const { * @param {import('express').Response} res - HTTP response. * @param {import('express').NextFunction} next - Do the following. */ -async function getFiles(req, res, next) { - const latest = req.data; +async function getSnapshots(req, res, next) { + const { latest } = req.data; if (latest) { let latestSnapshot; try { - latestSnapshot = await getMostRecentFile(snapshotsDir); + latestSnapshot = await getMostRecentFile(paths.data.snapshotsDir); } catch (err) { - return next({ message: 'Cannot get the lastest snapshot' }); + return next({ message: 'Cannot get the latest snapshot' }); } return res.status(200).json(latestSnapshot?.filename); } - const files = await fs.readdir(snapshotsDir); + const files = await fs.readdir(paths.data.snapshotsDir); return res.status(200).json(files); } @@ -38,8 +34,8 @@ async function getFiles(req, res, next) { * @param {import('express').Response} res - HTTP response. * @param {import('express').NextFunction} next - Do the following. */ -async function uploadFile(req, res, next) { - if (!req?.file) return next({ messsage: 'File not sent' }); +async function uploadSnapshot(req, res, next) { + if (!req?.file) return next({ message: 'File not sent' }); return res.status(202).json(); } @@ -50,15 +46,15 @@ async function uploadFile(req, res, next) { * @param {import('express').Response} res - HTTP response. * @param {import('express').NextFunction} next - Do the following. */ -async function deleteFileInstalled(req, res, next) { - const filename = req.data; +async function deleteSnapshot(req, res, next) { + const { filename } = req.data; - if (!await fs.pathExists(path.resolve(snapshotsDir, filename))) { + if (!await fs.pathExists(path.resolve(paths.data.snapshotsDir, filename))) { return res.status(404).json({ message: `File [${filename}] not found` }); } try { - await deleteFile(path.resolve(snapshotsDir, filename)); + await deleteFile(path.resolve(paths.data.snapshotsDir, filename)); } catch (err) { return next({ message: err.message }); } @@ -67,7 +63,7 @@ async function deleteFileInstalled(req, res, next) { } module.exports = { - getFiles, - uploadFile, - deleteFileInstalled, + getSnapshots, + uploadSnapshot, + deleteSnapshot, }; diff --git a/src/update/lib/controllers/state.js b/services/update/src/controllers/state.js similarity index 90% rename from src/update/lib/controllers/state.js rename to services/update/src/controllers/state.js index 72b8ce75..cabfd50a 100644 --- a/src/update/lib/controllers/state.js +++ b/services/update/src/controllers/state.js @@ -1,4 +1,4 @@ -const { getState } = require('../models/state'); +const { getState } = require('../lib/state'); /** * Controller to get the state of update. diff --git a/src/update/lib/controllers/status.js b/services/update/src/controllers/status.js similarity index 92% rename from src/update/lib/controllers/status.js rename to services/update/src/controllers/status.js index d129db5b..2b44b68b 100644 --- a/src/update/lib/controllers/status.js +++ b/services/update/src/controllers/status.js @@ -1,4 +1,4 @@ -const { getStatus, setInUpdate } = require('../status'); +const { getStatus, setInUpdate } = require('../lib/status'); /** * Controller to get status of update. diff --git a/src/update/lib/controllers/unpaywall.js b/services/update/src/controllers/unpaywall.js similarity index 96% rename from src/update/lib/controllers/unpaywall.js rename to services/update/src/controllers/unpaywall.js index 11357e92..250be05c 100644 --- a/src/update/lib/controllers/unpaywall.js +++ b/services/update/src/controllers/unpaywall.js @@ -8,7 +8,7 @@ const { getChangefiles } = require('../services/unpaywall'); * @param {import('express').NextFunction} next - Do the following. */ async function getChangefilesOfUnpaywall(req, res, next) { - const interval = req.data; + const { interval } = req.data; let snapshotsInfo; diff --git a/services/update/src/cron/cleanFile.js b/services/update/src/cron/cleanFile.js new file mode 100644 index 00000000..08290161 --- /dev/null +++ b/services/update/src/cron/cleanFile.js @@ -0,0 +1,42 @@ +const { paths, cron } = require('config'); + +const logger = require('../logger/appLogger'); +const Cron = require('./cron'); + +const { deleteFilesInDir } = require('../lib/files'); + +const cronConfig = cron.cleanFile; + +let { active } = cronConfig; +if (active === 'true' || active) active = true; +else active = false; + +/** + * Removes files generated by an update process that are older than 30 days. + * + * @returns {Promise} + */ +async function task() { + const deletedChangefiles = await deleteFilesInDir( + paths.data.changefilesDir, + cronConfig.changefileThreshold, + ); + logger.info(`[cron][${this.name}]: ${deletedChangefiles?.join(',')} (${deletedChangefiles.length}) changefiles are deleted`); + + const deletedReportFiles = await deleteFilesInDir( + paths.data.reportsDir, + cronConfig.reportThreshold, + ); + logger.info(`[cron][${this.name}]: ${deletedReportFiles?.join(',')} (${deletedReportFiles.length}) reports are deleted`); + + const deletedSnapshotFiles = await deleteFilesInDir( + paths.data.snapshotsDir, + cronConfig.snapshotsDir, + ); + + logger.info(`[cron][${this.name}]: ${deletedSnapshotFiles?.join(',')} (${deletedSnapshotFiles.length}) snapshots are deleted`); +} + +const deleteFileCron = new Cron('Clean file', cronConfig.schedule, task, active); + +module.exports = deleteFileCron; diff --git a/src/update/lib/models/cron.js b/services/update/src/cron/cron.js similarity index 69% rename from src/update/lib/models/cron.js rename to services/update/src/cron/cron.js index 70436084..5fbcf297 100644 --- a/src/update/lib/models/cron.js +++ b/services/update/src/cron/cron.js @@ -1,6 +1,7 @@ const { CronJob } = require('cron'); +const { timezone } = require('config'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); class Cron { /** @@ -16,18 +17,10 @@ class Cron { this.schedule = schedule; this.task = task; this.active = active; - this.process = new CronJob(schedule, this.task, null, false, 'Europe/Paris'); - if (active) { - this.start(); - } + this.process = new CronJob(schedule, this.task, null, false, timezone); } - /** - * Getter of config of cron. - * - * @returns {Object} config of cron. - */ - getConfig() { + get config() { return { name: this.name, schedule: this.schedule, @@ -43,8 +36,8 @@ class Cron { setTask(task) { this.process.stop(); this.task = task; - logger.info(`[cron: ${this.name}] config - task updated`); - this.process = new CronJob(this.schedule, this.task, null, false, 'Europe/Paris'); + logger.info(`[cron][${this.name}]: task updated`); + this.process = new CronJob(this.schedule, this.task, null, false, timezone); if (this.active) this.process.start(); } @@ -56,10 +49,10 @@ class Cron { setSchedule(schedule) { this.process.stop(); this.schedule = schedule; - logger.info(`[cron: ${this.name}] config - schedule is updated [${this.schedule}]`); + logger.info(`[cron][${this.name}]: schedule is updated [${this.schedule}]`); this.process = new CronJob(this.schedule, async () => { await this.task(); - }, null, false, 'Europe/Paris'); + }, null, false, timezone); if (this.active) this.process.start(); } @@ -69,10 +62,10 @@ class Cron { start() { try { this.process.start(); - logger.info(`[cron: ${this.name}] - started`); - logger.info(`[cron: ${this.name}] config - schedule: [${this.schedule}]`); + logger.info(`[cron][${this.name}]: started`); + logger.info(`[cron][${this.name}]: schedule [${this.schedule}]`); } catch (err) { - logger.error(`[cron ${this.name}] - error in start`, err); + logger.error(`[cron][${this.name}]: Cannot start`, err); return; } this.active = true; @@ -84,9 +77,9 @@ class Cron { stop() { try { this.process.stop(); - logger.info(`[cron: ${this.name}] - stopped`); + logger.info(`[cron][${this.name}]: stopped`); } catch (err) { - logger.error(`[cron ${this.name}] - error in stop`, err); + logger.error(`[cron][${this.name}]: Cannot stop`, err); return; } this.active = false; diff --git a/services/update/src/cron/dataUpdate.js b/services/update/src/cron/dataUpdate.js new file mode 100644 index 00000000..01653f3e --- /dev/null +++ b/services/update/src/cron/dataUpdate.js @@ -0,0 +1,72 @@ +const { format, subDays } = require('date-fns'); +const { cron } = require('config'); +const logger = require('../logger/appLogger'); + +const Cron = require('./cron'); +const { getStatus } = require('../lib/status'); + +const { insertChangefilesOnPeriodJob } = require('../process'); + +const { ...cronConfig } = cron.dataUpdate; +let { active } = cronConfig; + +if (active === 'true' || active) active = true; +else active = false; + +/** + * Starts an update daily process if no update process is started. + * + * @returns {Promise} + */ +async function task() { + const status = getStatus(); + if (status) { + logger.info(`[cron][${this.name}]: conflict: an update is already in progress`); + return; + } + const week = (cronConfig.interval === 'week'); + const startDate = format(subDays(new Date(), week ? 7 : 0), 'yyyy-MM-dd'); + const endDate = format(new Date(), 'yyyy-MM-dd'); + await insertChangefilesOnPeriodJob({ + index: cronConfig.index, + interval: cronConfig.interval, + startDate, + endDate, + offset: 0, + limit: -1, + }); +} + +const unpaywallCron = new Cron('Data update', cronConfig.schedule, task, active); + +/** + * Update config of update process and config of cron. + * + * @param {Object} newConfig - Global config. + */ +function update(newConfig) { + if (newConfig.schedule) { + cronConfig.schedule = newConfig.schedule; + unpaywallCron.setSchedule(newConfig.schedule); + } + if (newConfig.index) cronConfig.index = newConfig.index; + if (newConfig.interval) cronConfig.interval = newConfig.interval; + if (newConfig.index || newConfig.interval) { + unpaywallCron.setTask(task); + } +} + +/** + * Get config of update process and config of cron. + * + * @returns {Object} Config of update process and config of cron. + */ +function getGlobalConfig() { + return { ...cronConfig, ...unpaywallCron.config }; +} + +module.exports = { + getGlobalConfig, + update, + cron: unpaywallCron, +}; diff --git a/services/update/src/cron/dataUpdateHistory.js b/services/update/src/cron/dataUpdateHistory.js new file mode 100644 index 00000000..7f4153b1 --- /dev/null +++ b/services/update/src/cron/dataUpdateHistory.js @@ -0,0 +1,68 @@ +const { format, subDays } = require('date-fns'); +const { cron } = require('config'); +const logger = require('../logger/appLogger'); + +const Cron = require('./cron'); +const { getStatus } = require('../lib/status'); + +const { insertWithOaHistoryProcess } = require('../process'); + +const { ...cronConfig } = cron.dataUpdateHistory; +let { active } = cron.dataUpdateHistory; + +if (active === 'true' || active) active = true; +else active = false; + +/** + * Starts an update daily process if no update process is started. + * + * @returns {Promise} + */ +async function task() { + const status = getStatus(); + if (status) { + logger.info(`[cron][${this.name}]: conflict: an update is already in progress`); + return; + } + const isWeek = (cronConfig.interval === 'week'); + const startDate = format(subDays(new Date(), isWeek ? 7 : 0), 'yyyy-MM-dd'); + await insertWithOaHistoryProcess({ + indexBase: cronConfig.indexBase, + indexHistory: cronConfig.indexHistory, + interval: cronConfig.interval, + startDate, + }); +} + +const dataUpdateHistoryCron = new Cron('Data update history', cronConfig.schedule, task, active); + +/** + * Update config of update process and config of cron. + * + * @param {Object} newConfig - Global config. + */ +function update(newConfig) { + if (newConfig.schedule) { + cronConfig.schedule = newConfig.schedule; + dataUpdateHistoryCron.setSchedule(newConfig.schedule); + } + if (newConfig.indexBase) cronConfig.indexBase = newConfig.indexBase; + if (newConfig.indexHistory) cronConfig.indexHistory = newConfig.indexHistory; + if (newConfig.interval) cronConfig.interval = newConfig.interval; + if (newConfig.index || newConfig.interval) dataUpdateHistoryCron.setTask(task); +} + +/** + * Get config of update process and config of cron. + * + * @returns {Object} Config of update process and config of cron. + */ +function getGlobalConfig() { + return { ...cronConfig, ...dataUpdateHistoryCron.config }; +} + +module.exports = { + getGlobalConfig, + update, + cron: dataUpdateHistoryCron, +}; diff --git a/services/update/src/cron/downloadSnapshot.js b/services/update/src/cron/downloadSnapshot.js new file mode 100644 index 00000000..898f1a8b --- /dev/null +++ b/services/update/src/cron/downloadSnapshot.js @@ -0,0 +1,31 @@ +const { cron } = require('config'); +const logger = require('../logger/appLogger'); + +const Cron = require('./cron'); +const { getStatus } = require('../lib/status'); + +const { downloadSnapshot } = require('../process/download'); + +let { active } = cron.downloadSnapshot; + +if (active === 'true' || active) active = true; +else active = false; + +/** + * Starts regular download snapshot. + * + * @returns {Promise} + */ +async function task() { + const status = getStatus(); + if (status) { + logger.info(`[cron][${this.name}]: conflict: an update is already in progress`); + return; + } + + await downloadSnapshot(); +} + +const downloadSnapshotCron = new Cron('Download snapshot', cron.downloadSnapshot.schedule, task, active); + +module.exports = downloadSnapshotCron; diff --git a/src/update/lib/file.js b/services/update/src/lib/files.js similarity index 93% rename from src/update/lib/file.js rename to services/update/src/lib/files.js index 471a3bae..2b84b134 100644 --- a/src/update/lib/file.js +++ b/services/update/src/lib/files.js @@ -1,7 +1,7 @@ /* eslint-disable no-restricted-syntax */ const fs = require('fs-extra'); const path = require('path'); -const logger = require('./logger'); +const logger = require('../logger/appLogger'); /** * Get the files in a directory in order by date. @@ -41,6 +41,23 @@ async function getMostRecentFile(dir) { return files.length ? files[0] : undefined; } +/** + * Delete file installed on ezunpaywall on "/data/snapshots". + * + * @param {string} filepath - Filepath. + * + * @returns {Promise} + */ +async function deleteFile(filepath) { + try { + await fs.remove(filepath); + } catch (err) { + logger.error(`[file] Cannot remove [${filepath}]`, err); + throw err; + } + logger.info(`[file]: [${filepath}] deleted`); +} + /** * Deletes files in a directory that are older than n time. * @@ -61,29 +78,13 @@ async function deleteFilesInDir(directory, numberOfDays) { const stat = await fs.stat(path.join(directory, file)); if (stat.mtime < threshold) { deletedFiles.push(file); - await fs.unlink(path.join(directory, file)); + await deleteFile(path.join(directory, file)); } } return deletedFiles; } -/** - * Delete file installed on ezunpaywall on "/data/snapshots". - * - * @param {string} filepath - Filepath. - * - * @returns {Promise} - */ -async function deleteFile(filepath) { - try { - await fs.remove(filepath); - } catch (err) { - logger.error(`[file] Cannot remove [${filepath}]`, err); - throw err; - } -} - module.exports = { getMostRecentFile, deleteFilesInDir, diff --git a/services/update/src/lib/report.js b/services/update/src/lib/report.js new file mode 100644 index 00000000..f4d8b02a --- /dev/null +++ b/services/update/src/lib/report.js @@ -0,0 +1,56 @@ +const path = require('path'); +const fs = require('fs-extra'); +const { format } = require('date-fns'); +const { paths } = require('config'); +const logger = require('../logger/appLogger'); + +/** + * Create report on the folder as name the date of process. + * + * @param {Object} state - State of process. + * + * @returns {Promise} + */ +async function createReport(state) { + const { type } = state; + logger.info(`[report]: create new report for [${type}]`); + const filepath = path.resolve(paths.data.reportsDir, `${format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")}_${type}.json`); + try { + await fs.writeFile(filepath, JSON.stringify(state, null, 2)); + } catch (err) { + logger.error(`[report] Cannot write [${JSON.stringify(state, null, 2)}] in ${filepath}`, err); + throw err; + } + logger.debug('[report]: report created'); +} + +/** + * Get report from the folder data depending on type. + * + * @param {string} type - Type of report (unpaywall or unpaywallHistory). + * @param {string} filename - Report filename. + * + * @returns {Promise} Report in json format. + */ +async function getReport(filename) { + let report; + const pathfile = path.resolve(paths.data.reportsDir, filename); + try { + report = await fs.readFile(pathfile); + } catch (err) { + logger.error(`[report] Cannot read [${pathfile}]`, err); + throw err; + } + try { + report = JSON.parse(report); + } catch (err) { + logger.error(`[report] Cannot parse [${report}] at json format`, err); + throw err; + } + return report; +} + +module.exports = { + createReport, + getReport, +}; diff --git a/services/update/src/lib/state.js b/services/update/src/lib/state.js new file mode 100644 index 00000000..a270db0d --- /dev/null +++ b/services/update/src/lib/state.js @@ -0,0 +1,227 @@ +/* eslint-disable no-restricted-syntax */ +const { + createReport, +} = require('./report'); + +const { + sendMailUpdateReport, +} = require('../services/mail'); + +const { + setInUpdate, +} = require('./status'); + +const logger = require('../logger/appLogger'); + +let state = {}; + +function getState() { + return state; +} + +function setState(key, value) { + state[key] = value; +} + +/** + * Create a new file on folder "data/update/state" containing the update state + * + * @return {Promise} name of the file where the state is saved. + * + * @param {string} config.type - Type of job process. + * @param {string} config.index - index where are inserted data. + * @param {string} config.indexBase - index where are inserted base data. + * @param {string} config.indexHistory - index where are inserted history data. + */ +async function createState(config) { + logger.info(`[state]: create new state for [${config.type}] process`); + state = { + done: false, + createdAt: new Date(), + endAt: null, + steps: [], + error: false, + type: config.type, + index: config?.index || '', + indexBase: config?.indexBase || '', + indexHistory: config?.indexHistory || '', + }; + logger.debug('[state]: state is created'); +} + +/** + * Add step "getChangefiles" in steps attributes of state. + */ +function addStepGetChangefiles() { + logger.info('[state]: add step of check unpaywall update file registry'); + const step = { + task: 'getChangefiles', + took: 0, + status: 'inProgress', + }; + state.steps.push(step); + logger.debug('[state]: get changefile step is added'); +} + +/** + * Add step "download" in steps attributes of state. + * + * @param {string} downloadFile - Unpaywall data update filename. + */ +function addStepDownload(downloadFile) { + logger.info('[state] add step of download update file from unpaywall'); + const step = { + task: 'download', + file: downloadFile, + percent: 0, + took: 0, + status: 'inProgress', + }; + state.steps.push(step); + logger.debug('[state]: download step is added'); +} + +/** + * Add step "download" in steps attributes of state. + * + * @param {string} downloadFile - Unpaywall data update file name. + */ +function addStepInsert(downloadFile) { + logger.info('[state]: add step of insert the content of update file from unpaywall'); + const step = { + task: 'insert', + file: downloadFile, + linesRead: 0, + addedDocs: 0, + updatedDocs: 0, + failedDocs: 0, + percent: 0, + took: 0, + status: 'inProgress', + }; + state.steps.push(step); + logger.debug('[state]: insert step is added'); +} + +/** + * Get the latest step in state. + */ +function getLatestStep() { + return state.steps[state.steps.length - 1]; +} + +/** + * Update latest step in state. + * + * @param {Object} step - Latest step. + */ +function updateLatestStep(step) { + state.steps[state.steps.length - 1] = step; + logger.debug('[state]: step is updated'); +} + +/** + * Enrich the state by adding the end of treatment attributes. + */ +function end() { + state.done = true; + state.endAt = new Date(); + state.took = (new Date(state.endAt) - new Date(state.createdAt)) / 1000; + + if (state.type === 'dataUpdate') { + const indices = []; + + const insertSteps = state.steps.filter((e) => e.task === 'insert'); + + let totalAddedDocs = 0; + let totalUpdatedDocs = 0; + + insertSteps.forEach((step) => { + totalAddedDocs += step?.addedDocs || 0; + totalUpdatedDocs += step?.updatedDocs || 0; + }); + + indices.push({ + index: state.index, + added: totalAddedDocs, + updated: totalUpdatedDocs, + }); + state.indices = indices; + } + + if (state.type === 'dataUpdateHistory') { + const indices = []; + + const insertSteps = state.steps.filter((e) => e.task === 'insert'); + + let totalAddedBase = 0; + let totalUpdatedBase = 0; + let totalAddedHistory = 0; + let totalUpdatedHistory = 0; + + insertSteps.forEach((step) => { + const keys = Object.keys(step.indices); + totalAddedBase += step.indices[keys[0]].addedDocs; + totalUpdatedBase += step.indices[keys[0]].updatedDocs; + totalAddedHistory += step.indices[keys[1]].addedDocs; + totalUpdatedHistory += step.indices[keys[1]].updatedDocs; + }); + + indices.push({ + index: state.indexBase, + added: totalAddedBase, + updated: totalUpdatedBase, + }); + indices.push({ + index: state.indexHistory, + added: totalAddedHistory, + updated: totalUpdatedHistory, + }); + state.indices = indices; + } + delete state.index; + delete state.indexBase; + delete state.indexHistory; +} + +/** + * Update the state when there is an error. + * + * @param {Promise>} stackTrace - Log of error. + */ +async function fail(stackTrace) { + logger.error('[state]: fail'); + end(); + state.error = true; + state.stackTrace = stackTrace; + await createReport(state); + sendMailUpdateReport(state).catch((err) => { + logger.errorRequest(err); + }); + setInUpdate(false); +} + +/** + * Update the state when the process is finished successfully. + * + * @returns {Promise} + */ +async function endState() { + logger.info('[state]: end process'); + end(); + await createReport(state); + setInUpdate(false); +} + +module.exports = { + getState, + setState, + createState, + addStepGetChangefiles, + addStepDownload, + addStepInsert, + getLatestStep, + updateLatestStep, + fail, + endState, +}; diff --git a/src/update/lib/status.js b/services/update/src/lib/status.js similarity index 75% rename from src/update/lib/status.js rename to services/update/src/lib/status.js index f1fa29af..f9abcaa6 100644 --- a/src/update/lib/status.js +++ b/services/update/src/lib/status.js @@ -1,3 +1,5 @@ +const logger = require('../logger/appLogger'); + let inUpdate = false; /** @@ -6,6 +8,7 @@ let inUpdate = false; * @param {boolean} status - indicates if a job is in progress. */ const setInUpdate = (status) => { + logger.info(`[status]: status is updated to [${status}]`); inUpdate = status; }; diff --git a/src/mail/lib/morgan.js b/services/update/src/logger/access.js similarity index 53% rename from src/mail/lib/morgan.js rename to services/update/src/logger/access.js index 9e16d039..67689dc2 100644 --- a/src/mail/lib/morgan.js +++ b/services/update/src/logger/access.js @@ -3,16 +3,16 @@ const fs = require('fs-extra'); const rfs = require('rotating-file-stream'); const path = require('path'); const { format } = require('date-fns'); -const { accessLogRotate } = require('config'); +const { nodeEnv, paths, accessLogRotate } = require('config'); -const accessLogDir = path.resolve(__dirname, '..', 'log', 'access'); +const isProd = (nodeEnv === 'production'); /** - * Get the name of access file. + * Get the name of access log file. * - * @param {number} date - Date in minisecond + * @param {number} date - Date in milliseconds * - * @returns {string} Name of access file. + * @returns {string} Name of access log file. */ function logFilename(date) { if (!date) return 'access.log'; @@ -24,10 +24,10 @@ let accessLogStream; if (accessLogRotate) { accessLogStream = rfs.createStream(logFilename, { interval: '1d', // rotate daily - path: accessLogDir, + path: paths.log.accessDir, }); } else { - accessLogStream = fs.createWriteStream(path.resolve(accessLogDir, 'access.log'), { flags: 'a+' }); + accessLogStream = fs.createWriteStream(path.resolve(paths.log.accessDir, 'access.log'), { flags: 'a+' }); } morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); @@ -37,4 +37,7 @@ morgan.token('user', (req) => { return '-'; }); -module.exports = morgan(':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ', { stream: accessLogStream }); +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: isProd ? accessLogStream : process.stdout }, +); diff --git a/src/update/lib/logger.js b/services/update/src/logger/appLogger.js similarity index 94% rename from src/update/lib/logger.js rename to services/update/src/logger/appLogger.js index 9712083c..5a365be7 100644 --- a/src/update/lib/logger.js +++ b/services/update/src/logger/appLogger.js @@ -1,5 +1,5 @@ const path = require('path'); -const { nodeEnv } = require('config'); +const { nodeEnv, paths } = require('config'); const isProd = (nodeEnv === 'production'); @@ -22,7 +22,7 @@ const { const processConfiguration = [ new transports.DailyRotateFile({ name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), + filename: path.resolve(paths.log.applicationDir, '%DATE%.log'), datePattern: 'yyyy-MM-DD', level: 'info', }), diff --git a/services/update/src/logger/healthcheck.js b/services/update/src/logger/healthcheck.js new file mode 100644 index 00000000..f56e9d9f --- /dev/null +++ b/services/update/src/logger/healthcheck.js @@ -0,0 +1,41 @@ +const morgan = require('morgan'); +const fs = require('fs-extra'); +const rfs = require('rotating-file-stream'); +const path = require('path'); +const { format } = require('date-fns'); +const { paths, healthcheckLogRotate } = require('config'); + +/** + * Get the name of healthcheck log file. + * + * @param {number} date - Date in milliseconds + * + * @returns {string} Name of healthcheck log file. + */ +function logFilename(date) { + if (!date) return 'healthcheck.log'; + return `${format(new Date(date) - 1000 * 60 * 60 * 24, 'yyyy-MM-dd')}-healthcheck.log`; +} + +let healthCheckLogStream; + +if (healthcheckLogRotate) { + healthCheckLogStream = rfs.createStream(logFilename, { + interval: '1d', // rotate daily + path: paths.log.healthCheckDir, + }); +} else { + healthCheckLogStream = fs.createWriteStream(path.resolve(paths.log.healthCheckDir, 'healthcheck.log'), { flags: 'a+' }); +} + +morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress); + +morgan.token('user', (req) => { + if (req.user) return req.user; + return '-'; +}); + +module.exports = morgan( + ':ip ":user" [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"', + { stream: healthCheckLogStream }, +); diff --git a/src/update/lib/middlewares/auth.js b/services/update/src/middlewares/auth.js similarity index 100% rename from src/update/lib/middlewares/auth.js rename to services/update/src/middlewares/auth.js diff --git a/src/apikey/lib/middlewares/dev.js b/services/update/src/middlewares/dev.js similarity index 81% rename from src/apikey/lib/middlewares/dev.js rename to services/update/src/middlewares/dev.js index 70cf93af..450a61ab 100644 --- a/src/apikey/lib/middlewares/dev.js +++ b/services/update/src/middlewares/dev.js @@ -1,4 +1,4 @@ -const config = require('config'); +const { nodeEnv } = require('config'); /** * dev middleware that checks if NODE_ENV is equal to development @@ -10,9 +10,7 @@ const config = require('config'); * This middleware need a header that contains the apikey. */ async function dev(req, res, next) { - const env = config.get('nodeEnv'); - - if (env !== 'development') { + if (nodeEnv !== 'development') { return res.status(404).json({ message: 'Not found' }); } diff --git a/services/update/src/middlewares/format/cron.js b/services/update/src/middlewares/format/cron.js new file mode 100644 index 00000000..fd882675 --- /dev/null +++ b/services/update/src/middlewares/format/cron.js @@ -0,0 +1,55 @@ +const joi = require('joi').extend(require('@hapi/joi-date')); + +/** + * Validate cron config according to type. + * + * @param {string} type - Type of cron. + * @param {Object} body - Body of express request. + * + * @returns {Object} return value or error. + */ +function checkCronConfig(type, body) { + switch (type) { + case 'dataUpdate': + return joi.object({ + schedule: joi.string().trim(), + index: joi.string().trim(), + interval: joi.string().trim().valid('day', 'week'), + }).validate(body); + + case 'dataUpdateHistory': + return joi.object({ + schedule: joi.string().trim(), + indexBase: joi.string().trim(), + indexHistory: joi.string().trim(), + interval: joi.string().trim().valid('day', 'week'), + }).validate(body); + default: + } + return false; +} + +/** + * Joi middleware to check if cron config is correct. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function validateCronConfig(req, res, next) { + const { type } = req.params; + + const { error, value } = checkCronConfig(type, req.body); + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data.cronConfig = value; + + return next(); +} + +module.exports = validateCronConfig; diff --git a/src/update/lib/middlewares/filename.js b/services/update/src/middlewares/format/filename.js similarity index 89% rename from src/update/lib/middlewares/filename.js rename to services/update/src/middlewares/format/filename.js index 35b85c88..7effee60 100644 --- a/src/update/lib/middlewares/filename.js +++ b/services/update/src/middlewares/format/filename.js @@ -13,7 +13,11 @@ async function validateFilename(req, res, next) { const { error, value } = joi.string().trim().required().validate(filename); if (error) return res.status(400).json({ message: error.details[0].message }); - req.data = value; + if (!req.data) { + req.data = {}; + } + + req.data.filename = value; return next(); } diff --git a/services/update/src/middlewares/format/interval.js b/services/update/src/middlewares/format/interval.js new file mode 100644 index 00000000..80700f44 --- /dev/null +++ b/services/update/src/middlewares/format/interval.js @@ -0,0 +1,39 @@ +const joi = require('joi'); + +/** + * Joi middleware to check if interval in body is correct. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function validateInterval(req, res, next) { + let error; + let value; + + if (req.body.interval) { + const result = joi.string().trim().valid('week', 'day').default('day') + .validate(req.body.interval); + error = result?.error; + value = result?.value; + } + + if (req.query.interval) { + const result = joi.string().trim().valid('week', 'day').default('day') + .validate(req.query.interval); + error = result?.error; + value = result?.value; + } + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data.interval = value; + + return next(); +} + +module.exports = validateInterval; diff --git a/src/update/lib/middlewares/job.js b/services/update/src/middlewares/format/job.js similarity index 51% rename from src/update/lib/middlewares/job.js rename to services/update/src/middlewares/format/job.js index 03baad5c..d4674ccf 100644 --- a/src/update/lib/middlewares/job.js +++ b/services/update/src/middlewares/format/job.js @@ -12,7 +12,11 @@ function validateSnapshotJob(req, res, next) { if (error) return res.status(400).json({ message: error.details[0].message }); - req.data = value; + if (!req.data) { + req.data = {}; + } + + req.data.index = value; return next(); } @@ -30,11 +34,17 @@ async function validateJobChangefilesConfig(req, res, next) { interval: joi.string().trim().valid('day', 'week').default('day'), startDate: joi.date().format('YYYY-MM-DD'), endDate: joi.date().format('YYYY-MM-DD').min(joi.ref('startDate')), + ignoreError: joi.boolean().default(false), + cleanFile: joi.boolean().default(false), }).with('endDate', 'startDate').validate(req.body); if (error) return res.status(400).json({ message: error.details[0].message }); - req.data = value; + if (!req.data) { + req.data = {}; + } + + req.data.jobConfig = value; return next(); } @@ -60,20 +70,81 @@ async function validateInsertFile(req, res, next) { index: joi.string().trim().default('unpaywall'), offset: joi.number().greater(-1).default(0), limit: joi.number().greater(joi.ref('offset')).default(-1), + ignoreError: joi.boolean().default(false), + cleanFile: joi.boolean().default(false), }).validate(req.body); if (checkBody.error) return res.status(400).json({ message: checkBody.error.details[0].message }); - const { index, offset, limit } = checkBody.value; - req.data = { - filename, index, offset, limit, + if (!req.data) { + req.data = {}; + } + + req.data.jobConfig = { + filename, ...checkBody.value, }; return next(); } +/** + * Joi middleware to check if job config for insert history of open access. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function validateHistoryJob(req, res, next) { + const { error, value } = joi.object({ + indexBase: joi.string().trim().default('unpaywall-base'), + indexHistory: joi.string().trim().default('unpaywall-history'), + interval: joi.string().trim().valid('day', 'week').default('day'), + startDate: joi.date().format('YYYY-MM-DD'), + endDate: joi.date().format('YYYY-MM-DD').min(joi.ref('startDate')), + ignoreError: joi.boolean().default(false), + cleanFile: joi.boolean().default(false), + }).with('endDate', 'startDate').validate(req.body); + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data.jobConfig = value; + + return next(); +} + +/** + * Joi middleware to check if job config for insert history of open access. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +async function validateHistoryReset(req, res, next) { + const { error, value } = joi.object({ + indexBase: joi.string().trim().default('unpaywall-base'), + indexHistory: joi.string().trim().default('unpaywall-history'), + startDate: joi.date(), + }).with('endDate', 'startDate').validate(req.body); + + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data.rollBackConfig = value; + + return next(); +} + module.exports = { validateSnapshotJob, validateJobChangefilesConfig, validateInsertFile, + validateHistoryJob, + validateHistoryReset, }; diff --git a/src/update/lib/middlewares/latest.js b/services/update/src/middlewares/format/latest.js similarity index 88% rename from src/update/lib/middlewares/latest.js rename to services/update/src/middlewares/format/latest.js index 01aac6ab..dd68cf7a 100644 --- a/src/update/lib/middlewares/latest.js +++ b/services/update/src/middlewares/format/latest.js @@ -11,7 +11,11 @@ async function validateLatest(req, res, next) { const { error, value } = joi.boolean().default(false).validate(req?.query?.latest); if (error) return res.status(400).json({ message: error.details[0].message }); - req.data = value; + if (!req.data) { + req.data = {}; + } + + req.data.latest = value; return next(); } diff --git a/services/update/src/middlewares/format/type.js b/services/update/src/middlewares/format/type.js new file mode 100644 index 00000000..4846677e --- /dev/null +++ b/services/update/src/middlewares/format/type.js @@ -0,0 +1,53 @@ +const joi = require('joi'); + +/** + * Check if type is correct. + * + * @param {*} type - type of job + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + * + * @returns + */ +function validateType(type, req, res, next) { + const { error, value } = joi.string().trim().valid('dataUpdate', 'dataUpdateHistory').validate(type); + if (error) return res.status(400).json({ message: error.details[0].message }); + + if (!req.data) { + req.data = {}; + } + + req.data.type = value; + + return next(); +} + +/** + * Joi middleware to check if type in param is correct. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function validateParamsType(req, res, next) { + const { type } = req.params; + return validateType(type, req, res, next); +} + +/** + * Joi middleware to check if type in query is correct. + * + * @param {import('express').Request} req - HTTP request. + * @param {import('express').Response} res - HTTP response. + * @param {import('express').NextFunction} next - Do the following. + */ +function validateQueryType(req, res, next) { + const { type } = req.query; + return validateType(type, req, res, next); +} + +module.exports = { + validateParamsType, + validateQueryType, +}; diff --git a/src/update/lib/middlewares/status.js b/services/update/src/middlewares/status.js similarity index 91% rename from src/update/lib/middlewares/status.js rename to services/update/src/middlewares/status.js index 99337736..59265756 100644 --- a/src/update/lib/middlewares/status.js +++ b/services/update/src/middlewares/status.js @@ -1,6 +1,6 @@ const { getStatus, -} = require('../status'); +} = require('../lib/status'); /** * Middleware that blocks simultaneous updates of unpaywall data. diff --git a/src/update/lib/middlewares/multer.js b/services/update/src/middlewares/uploadChangefile.js similarity index 61% rename from src/update/lib/middlewares/multer.js rename to services/update/src/middlewares/uploadChangefile.js index 0a52fefe..90060f91 100644 --- a/src/update/lib/middlewares/multer.js +++ b/services/update/src/middlewares/uploadChangefile.js @@ -1,11 +1,10 @@ -const path = require('path'); const multer = require('multer'); -const snapshotsDir = path.resolve(__dirname, '..', '..', 'data', 'snapshots'); +const { paths } = require('config'); const storage = multer.diskStorage( { - destination: snapshotsDir, + destination: paths.data.changefilesDir, filename: (req, file, cb) => { cb(null, file.originalname); }, diff --git a/services/update/src/middlewares/uploadSnapshot.js b/services/update/src/middlewares/uploadSnapshot.js new file mode 100644 index 00000000..d582d37b --- /dev/null +++ b/services/update/src/middlewares/uploadSnapshot.js @@ -0,0 +1,16 @@ +const multer = require('multer'); + +const { paths } = require('config'); + +const storage = multer.diskStorage( + { + destination: paths.data.snapshotsDir, + filename: (req, file, cb) => { + cb(null, file.originalname); + }, + }, +); + +const upload = multer({ storage }); + +module.exports = upload; diff --git a/src/update/lib/ping.js b/services/update/src/ping.js similarity index 100% rename from src/update/lib/ping.js rename to services/update/src/ping.js diff --git a/src/update/lib/download.js b/services/update/src/process/download.js similarity index 74% rename from src/update/lib/download.js rename to services/update/src/process/download.js index 9dc29541..3a126131 100644 --- a/src/update/lib/download.js +++ b/services/update/src/process/download.js @@ -2,7 +2,10 @@ const path = require('path'); const fs = require('fs-extra'); const { Readable } = require('stream'); const { format } = require('date-fns'); -const logger = require('./logger'); +const { setTimeout } = require('node:timers/promises'); +const { paths } = require('config'); + +const logger = require('../logger/appLogger'); const { getState, @@ -10,14 +13,12 @@ const { addStepDownload, fail, updateLatestStep, -} = require('./models/state'); +} = require('../lib/state'); const { getSnapshot, getChangefile, -} = require('./services/unpaywall'); - -const snapshotsDir = path.resolve(__dirname, '..', 'data', 'snapshots'); +} = require('../services/unpaywall'); /** * Update the step the percentage in download regularly until the download is complete. @@ -34,11 +35,12 @@ async function updatePercentStepDownload(filepath, size, start) { return; } const step = getLatestStep(); + logger.debug(`[job][download]: Percent of step: ${step.percent}`); let bytes; try { bytes = await fs.stat(filepath); } catch (err) { - logger.error(`[job: download] Cannot stat [${filepath}]`, err); + logger.error(`[job][download]: Cannot stat [${filepath}]`, err); return; } if (bytes?.size >= size) { @@ -47,7 +49,7 @@ async function updatePercentStepDownload(filepath, size, start) { step.took = (new Date() - start) / 1000; step.percent = ((bytes.size / size) * 100).toFixed(2); updateLatestStep(step); - await new Promise((resolve) => setTimeout(resolve, 1000)); + await setTimeout(1000); updatePercentStepDownload(filepath, size, start); } @@ -68,20 +70,22 @@ async function download(file, filepath, size) { const writeStream = file.pipe(fs.createWriteStream(filepath)); const start = new Date(); - // update the percentage of the download step in parallel - updatePercentStepDownload(filepath, size, start); + writeStream.on('ready', async () => { + // update the percentage of the download step in parallel + updatePercentStepDownload(filepath, size, start); + }); writeStream.on('finish', async () => { step.status = 'success'; step.took = (new Date() - start) / 1000; step.percent = 100; updateLatestStep(step); - logger.info('[job: download] File download completed'); + logger.info('[job][download]: File download completed'); return resolve(); }); writeStream.on('error', async (err) => { - logger.error('[job: download] Error on stream', err); + logger.error('[job][download]: Error on stream', err); await fail(err); return reject(err); }); @@ -104,12 +108,12 @@ async function download(file, filepath, size) { async function downloadChangefile(info, interval) { let stats; - const filepath = path.resolve(snapshotsDir, info.filename); + const filePath = path.resolve(paths.data.changefilesDir, info.filename); - const alreadyInstalled = await fs.pathExists(filepath); - if (alreadyInstalled) stats = await fs.stat(filepath); + const alreadyInstalled = await fs.pathExists(filePath); + if (alreadyInstalled) stats = await fs.stat(filePath); if (alreadyInstalled && stats.size === info.size) { - logger.info(`[job: download] File [${info.filename}] is already installed`); + logger.info(`[job][download]: File [${info.filename}] is already installed`); return true; } @@ -130,7 +134,7 @@ async function downloadChangefile(info, interval) { const changefile = res.data; const { size } = info; - await download(changefile, filepath, size); + await download(changefile, filePath, size); return true; } @@ -139,9 +143,9 @@ async function downloadChangefile(info, interval) { * * @returns {Promise} filename of snapshot */ -async function downloadBigSnapshot() { +async function downloadSnapshot() { const filename = `snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`; - const filepath = path.resolve(snapshotsDir, filename); + const filepath = path.resolve(paths.data.snapshotsDir, filename); addStepDownload(); const step = getLatestStep(); @@ -160,5 +164,5 @@ async function downloadBigSnapshot() { module.exports = { downloadChangefile, - downloadBigSnapshot, + downloadSnapshot, }; diff --git a/services/update/src/process/history.js b/services/update/src/process/history.js new file mode 100644 index 00000000..844e204e --- /dev/null +++ b/services/update/src/process/history.js @@ -0,0 +1,440 @@ +/* eslint-disable consistent-return */ +/* eslint-disable no-param-reassign */ +/* eslint-disable no-restricted-syntax */ + +const path = require('path'); +const fs = require('fs-extra'); +const readline = require('readline'); +const { elasticsearch } = require('config'); +const zlib = require('zlib'); +const { format } = require('date-fns'); +const { paths } = require('config'); + +const logger = require('../logger/appLogger'); +const unpaywallEnrichedMapping = require('../../mapping/unpaywall.json'); +const unpaywallHistoryMapping = require('../../mapping/unpaywall-history.json'); + +const { + addStepInsert, + getLatestStep, + updateLatestStep, + fail, +} = require('../lib/state'); + +const { + refreshIndex, + searchByDOI, + bulk, + createIndex, + searchWithRange, +} = require('../services/elastic'); + +const { maxBulkSize } = elasticsearch; + +/** + * Insert data on elastic with elastic bulk request. + * + * @param {Array} data - Array of unpaywall data. + * + * @returns {Promise} Success or not. + */ +async function insertUnpaywallDataInElastic(data, index) { + const step = getLatestStep(); + let res; + try { + res = await bulk(data); + } catch (err) { + logger.error(`[elastic]: Cannot bulk on index [${index}]`, err); + await fail(err?.[0]?.reason); + return false; + } + + const errors = []; + const items = Array.isArray(res?.body?.items) ? res?.body?.items : []; + + items.forEach((i) => { + if (i?.index?.result === 'created') { + step.indices[index].addedDocs += 1; + return; + } + if (i?.index?.result === 'updated') { + step.indices[index].updatedDocs += 1; + return; + } + + if (i?.index?.error !== undefined) { + step.indices[index].failedDocs += 1; + errors.push(i?.index?.error); + } + }); + + if (errors.length > 0) { + logger.error('[elastic]: Error in bulk insertion'); + errors.forEach((error) => { + logger.error(`[elastic]: ${JSON.stringify(error, null, 2)}`); + }); + step.status = 'error'; + updateLatestStep(step); + await fail(errors); + return false; + } + + updateLatestStep(step); + + return true; +} +/** + * Insert data in unpaywall index base and history index. + * that insert normally in the index base and for the history, if doi is present in + * index base, that will create a new entry on history index. + * + * @param {Array} listOfDoi - Array of DOI that will be inserted + * @param {Array} newDocuments - Array of document that will be inserted + * @param {string} indexBase - name of base index + * @param {string} indexHistory - name of history base + * + * @returns {Promise} Success or not. + */ +async function insertData(listOfDoi, newDocuments, indexBase, indexHistory) { + logger.debug(`[job][insert]: try to get [${listOfDoi.length}] documents in [${indexBase}]`); + const existingDataInBaseIndex = await searchByDOI(listOfDoi, indexBase); + logger.debug(`[job][insert]: get [${existingDataInBaseIndex.length}] documents in [${indexBase}]`); + const bulkHistoryDocuments = []; + const bulkDocuments = []; + + const existingUnpaywallDataMap = new Map( + existingDataInBaseIndex.map((data) => { + const copyData = { ...data }; + return [data.doi, copyData]; + }), + ); + + newDocuments.forEach(async (el) => { + const document = el; + document.referencedAt = document.updated; + const existingDocumentUnpaywall = existingUnpaywallDataMap.get(document.doi); + + if (existingDocumentUnpaywall) { + const copyDocumentTime = new Date(document.updated).getTime(); + const existingDocumentTime = new Date(existingDocumentUnpaywall.updated).getTime(); + // if the document in changefile is older than the existence, don't insert it + if (copyDocumentTime > existingDocumentTime) { + const newEntryInHistory = existingDocumentUnpaywall; + newEntryInHistory.endValidity = document.updated; + + bulkHistoryDocuments.push({ index: { _index: indexHistory, _id: `${document.updated}-${document.doi}` } }); + bulkHistoryDocuments.push(newEntryInHistory); + + // get the existing referencedAt to apply it for the new entry in history + document.referencedAt = existingDocumentUnpaywall.referencedAt; + } + if (copyDocumentTime === existingDocumentTime) { + document.referencedAt = existingDocumentUnpaywall.referencedAt; + } + } else { + // If new data, add referencedAt to new data + document.referencedAt = document.updated; + } + + bulkDocuments.push({ index: { _index: indexBase, _id: document.doi } }); + bulkDocuments.push(document); + }); + + let success = false; + + logger.debug(`[job][insert]: try to insert [${bulkDocuments.length / 2}] documents in [${indexBase}]`); + success = await insertUnpaywallDataInElastic(bulkDocuments, indexBase); + if (!success) return false; + + if (bulkHistoryDocuments.length > 0) { + logger.debug(`[job][insert]: try to insert [${bulkHistoryDocuments.length / 2}] documents in [${indexHistory}]`); + success = await insertUnpaywallDataInElastic(bulkHistoryDocuments, indexHistory); + if (!success) return false; + } + + return true; +} + +/** + * Inserts the contents of an unpaywall data update file with history. + * + * @param {Object} insertConfig - Config of insertion. + * @param {string} insertConfig.filename - Name of the snapshot file from which the data will + * be retrieved to be inserted into elastic. + * @param {string} insertConfig.date - Date of file. + * @param {string} insertConfig.index - Name of the index to which the data will be inserted. + * @param {number} insertConfig.offset - Line of the snapshot at which the data insertion starts. + * @param {number} insertConfig.limit - Line in the file where the insertion stops. + * + * @returns {Promise} Success or not. + */ +async function insertHistoryDataUnpaywall(insertConfig) { + const { + filename, indexBase, indexHistory, offset, limit, + } = insertConfig; + + try { + await createIndex(indexBase, unpaywallEnrichedMapping); + } catch (err) { + logger.error(`[elastic]: Cannot create index [${indexBase}]`, err); + await fail(err); + return false; + } + + try { + await createIndex(indexHistory, unpaywallHistoryMapping); + } catch (err) { + logger.error(`[elastic]: Cannot create index [${indexHistory}]`, err); + await fail(err); + return false; + } + + // step insertion in the state + const start = new Date(); + addStepInsert(filename); + const step = getLatestStep(); + step.file = filename; + step.indices = { + [indexBase]: { + addedDocs: 0, + updatedDocs: 0, + failedDocs: 0, + }, + [indexHistory]: { + addedDocs: 0, + updatedDocs: 0, + failedDocs: 0, + }, + }; + updateLatestStep(step); + + const filePath = path.resolve(paths.data.changefilesDir, filename); + + // get information bytes for state + let bytes; + try { + bytes = await fs.stat(filePath); + } catch (err) { + logger.error(`[job][insert]: Cannot get bytes [${filePath}]`, err); + await fail(err); + return false; + } + + // read file with stream + let readStream; + try { + readStream = fs.createReadStream(filePath); + } catch (err) { + logger.error(`[job][insert]: Cannot read [${filePath}]`, err); + await fail(err); + return false; + } + + // get information "loaded" for state + let loaded = 0; + readStream.on('data', (chunk) => { + loaded += chunk.length; + }); + + let decompressedStream; + try { + decompressedStream = readStream.pipe(zlib.createGunzip()); + } catch (err) { + logger.error(`[job][insert]: Cannot pipe [${readStream?.filename}]`, err); + await fail(err); + return false; + } + + const rl = readline.createInterface({ + input: decompressedStream, + crlfDelay: Infinity, + }); + + let newData = []; + let listOfDoi = []; + + let success; + + logger.info(`[job][insert]: Start insert with [${filename}]`); + + // Reads line by line the output of the decompression stream to make packets of 1000 + // to insert them in bulk in an elastic + for await (const line of rl) { + // limit + if (step.linesRead === limit) { + break; + } + + step.linesRead += 1; + + // offset + if (step.linesRead >= offset + 1) { + // fill the array + try { + const doc = JSON.parse(line); + // history + listOfDoi.push(doc.doi); + newData.push(doc); + } catch (err) { + logger.error(`[job][insert]: Cannot parse [${line}] in json format`, err); + await fail(err); + return false; + } + } + // bulk insertion + if (newData.length >= maxBulkSize) { + success = await insertData(listOfDoi, newData, indexBase, indexHistory); + listOfDoi = []; + newData = []; + + if (!success) return false; + step.percent = ((loaded / bytes.size) * 100).toFixed(2); + step.took = (new Date() - start) / 1000; + updateLatestStep(step); + } + if (step.linesRead % 100000 === 0) { + logger.info(`[job][insert]: ${step.linesRead} Lines reads`); + updateLatestStep(step); + } + } + // last insertion if there is data left + if (newData.length > 0) { + // history + success = await insertData(listOfDoi, newData, indexBase, indexHistory); + listOfDoi = []; + newData = []; + if (!success) return false; + } + + logger.info('[job][insert]: insertion completed'); + + try { + await refreshIndex(); + } catch (err) { + logger.warn('[elastic]: Cannot refresh the index', err); + } + + // last update of step + step.status = 'success'; + step.took = (new Date() - start) / 1000; + step.percent = 100; + updateLatestStep(step); + return true; +} + +async function step1(startDate, indexBase, indexHistory) { + logger.debug('----------------------------------'); + logger.debug('STEP 1'); + logger.debug(`startDate: ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + logger.debug(`Should DELETE greater or equal than ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + const toRecentDataInHistoryBulk = []; + const toRecentDataInHistory = await searchWithRange(startDate, 'updated', 'gte', indexHistory); + + toRecentDataInHistory.forEach((data) => { + toRecentDataInHistoryBulk.push({ delete: { _index: indexHistory, _id: data._id } }); + logger.debug(`HISTORY: DELETE: doi: ${data._source.doi}, genre: ${data._source.genre}, updated: ${data._source.updated}`); + }); + + await bulk(toRecentDataInHistoryBulk, true); + logger.debug(`DELETE ${toRecentDataInHistoryBulk.length} lines`); + logger.debug('UNPAYWALL: REFRESH'); + await refreshIndex(indexBase); +} + +async function step2(startDate, indexBase, indexHistory) { + logger.debug('----------------------------------'); + logger.debug('STEP 2'); + logger.debug(`startDate: ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + logger.debug(`Should UPDATE data less than ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + const nearestDataBulk = []; + const nearestDataDeleteBulk = []; + logger.debug('searchWithRange'); + const oldData = await searchWithRange(startDate, 'updated', 'lt', indexHistory); + logger.debug(`oldDoc.length: ${oldData?.length}`); + + const listOfDoi = oldData.map((e) => e._source.doi); + const listOfDoiFiltered = new Set(listOfDoi); + + for (const doi of listOfDoiFiltered) { + const docs = oldData.filter((e) => doi === e._source.doi); + let nearestData; + docs.forEach((doc) => { + if (!nearestData) { + nearestData = doc; + } + const date1 = new Date(startDate) - new Date(doc._source.updated); + const date2 = new Date(startDate) - new Date(nearestData._source.updated); + + if (date1 < date2) { + nearestData = doc; + } + }); + + logger.debug('step2'); + const oldDoc = await searchByDOI([nearestData._source.doi], indexBase); + logger.debug(`oldDoc.length: ${oldDoc.length}`); + + logger.info(`oldData: ${format(new Date(oldDoc[0].updated), 'yyyy-MM-dd/hh:mm:ss')} < startDate: ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + + if (new Date(startDate) < new Date(oldDoc[0].updated)) { + // UPDATE + delete nearestData._source.endValidity; + nearestDataBulk.push({ index: { _index: indexBase, _id: nearestData._source.doi } }); + nearestDataBulk.push(nearestData._source); + logger.debug(`UNPAYWALL: UPDATE: doi: ${nearestData._source.doi}, genre: ${nearestData._source.genre}, updated: ${nearestData._source.updated}`); + + // DELETE + nearestDataDeleteBulk.push({ delete: { _index: indexHistory, _id: nearestData._id } }); + logger.debug(`HISTORY: DELETE: doi: ${nearestData._source.doi}, genre: ${nearestData._source.genre}, updated: ${nearestData._source.updated}`); + } + } + + // UPDATE + await bulk(nearestDataBulk, true); + logger.debug(`UPDATE ${nearestDataBulk.length / 2} lines`); + logger.debug('UNPAYWALL: REFRESH'); + await refreshIndex(indexBase); + + // DELETE + await bulk(nearestDataDeleteBulk, true); + logger.debug(`DELETE ${nearestDataDeleteBulk.length} lines`); + logger.debug('HISTORY: REFRESH'); + await refreshIndex(indexHistory); +} + +async function step3(startDate, indexBase) { + logger.debug('----------------------------------'); + logger.debug('STEP 3'); + + const toRecentDataBulk = []; + const toRecentData = await searchWithRange(startDate, 'updated', 'gte', indexBase); + logger.debug(`startDate: ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + logger.debug(`Should DELETE data greater or equal than ${format(new Date(startDate), 'yyyy-MM-dd/hh:mm:ss')}`); + toRecentData.forEach((data) => { + toRecentDataBulk.push({ delete: { _index: indexBase, _id: data._id } }); + logger.debug(`UNPAYWALL: DELETE: doi: ${data._source.doi}, genre: ${data._source.genre}, updated: ${format(new Date(data._source.updated), 'yyyy-MM-dd/hh:mm:ss')}`); + }); + + await bulk(toRecentDataBulk, true); + logger.debug(`DELETE ${toRecentDataBulk.length} lines`); + logger.debug('UNPAYWALL: REFRESH'); + await refreshIndex(indexBase); +} + +/** + * Resets the unpaywall index according to a date and deletes the data in the history. + * @param {string} startDate - The date you wish to return to + */ +async function rollBack(startDate, indexBase, indexHistory) { + await step1(startDate, indexBase, indexHistory); + await step2(startDate, indexBase, indexHistory); + await step3(startDate, indexBase); +} + +module.exports = { + insertHistoryDataUnpaywall, + rollBack, + step1, + step2, + step3, +}; diff --git a/services/update/src/process/index.js b/services/update/src/process/index.js new file mode 100644 index 00000000..eaff11eb --- /dev/null +++ b/services/update/src/process/index.js @@ -0,0 +1,245 @@ +/* eslint-disable no-param-reassign */ +const path = require('path'); +const { format } = require('date-fns'); +const { paths } = require('config'); + +const logger = require('../logger/appLogger'); + +const { setInUpdate } = require('../lib/status'); + +const { downloadSnapshot, downloadChangefile } = require('./download'); + +const { + endState, + fail, + createState, + addStepGetChangefiles, + updateLatestStep, + getLatestStep, +} = require('../lib/state'); + +const insertDataUnpaywall = require('./insert'); + +const { deleteFile } = require('../lib/files'); + +const { insertHistoryDataUnpaywall } = require('./history'); + +const { getChangefiles } = require('../services/unpaywall'); + +const { sendMailNoChangefile } = require('../services/mail'); + +/** + * Download the current snapshot of unpaywall and insert his content. + * + * @param {Object} jobConfig - Config of job. + * @param {string} jobConfig.index - Name of the index to which the data will be inserted. + * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. + * @param {number} jobConfig.limit - Line in the file where the insertion stops. + * + * @returns {Promise} + */ +async function downloadSnapshotProcess() { + setInUpdate(true); + logger.info('[job][snapshot]: Start download snapshot job'); + await createState({ type: 'download' }); + const filename = await downloadSnapshot(); + if (!filename) { + await fail(); + return; + } + await endState(); +} + +/** + * Download the current snapshot of unpaywall and insert his content. + * + * @param {Object} jobConfig - Config of job. + * @param {string} jobConfig.index - Name of the index to which the data will be inserted. + * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. + * @param {number} jobConfig.limit - Line in the file where the insertion stops. + * + * @returns {Promise} + */ +async function downloadAndInsertSnapshotProcess(jobConfig) { + setInUpdate(true); + logger.info('[job][snapshot]: Start snapshot job'); + logger.info(`[job][snapshot]: index: [${jobConfig.index}]`); + logger.info(`[job][snapshot]: offset: [${jobConfig.offset}]`); + logger.info(`[job][snapshot]: limit: [${jobConfig.limit}]`); + await createState({ type: 'dataUpdate', index: jobConfig.index }); + const filename = await downloadSnapshot(); + if (!filename) { + await fail(); + return; + } + jobConfig.filetype = 'snapshot'; + jobConfig.filename = filename; + await insertDataUnpaywall(jobConfig); + await endState(); +} + +/** + * Download and insert on elastic the changefiles from unpaywall between a period. + * + * @param {Object} jobConfig - Config of job. + * @param {string} jobConfig.index - Name of the index to which the data will be inserted. + * @param {string} jobConfig.interval - Interval of changefile, day or week are available. + * @param {string} jobConfig.startDate - Start date for the changefile period. + * @param {string} jobConfig.endDate - End date for the changefile period. + * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. + * @param {number} jobConfig.limit - Line in the file where the insertion stops. + * @param {boolean} jobConfig.cleanFile - Delete file after job. + * @param {boolean} jobConfig.ignoreError - Ignore error in file. + * + * @returns {Promise} + */ +async function insertChangefilesOnPeriodProcess(jobConfig) { + setInUpdate(true); + const { interval, startDate, endDate } = jobConfig; + logger.info('[job][period]: Start period job'); + logger.info(`[job][period]: index: [${jobConfig.index}]`); + logger.info(`[job][period]: interval: [${jobConfig.interval}]`); + logger.info(`[job][period]: startDate: [${jobConfig.startDate}]`); + logger.info(`[job][period]: endDate: [${jobConfig.endDate}]`); + logger.info(`[job][period]: offset: [${jobConfig.offset}]`); + logger.info(`[job][period]: limit: [${jobConfig.limit}]`); + logger.info(`[job][period]: cleanFile: [${jobConfig.cleanFile}]`); + logger.info(`[job][period]: ignoreError: [${jobConfig.ignoreError}]`); + await createState({ type: 'dataUpdate', index: jobConfig.index }); + const start = new Date(); + addStepGetChangefiles(); + const step = getLatestStep(); + const changefilesInfo = await getChangefiles(interval, startDate, endDate); + + if (!changefilesInfo) { + step.status = 'error'; + updateLatestStep(step); + await fail(); + return; + } + + step.took = (new Date() - start) / 1000; + step.status = 'success'; + updateLatestStep(step); + + if (changefilesInfo.length === 0) { + sendMailNoChangefile(format(startDate, 'yyyy-MM-dd'), format(endDate, 'yyyy-MM-dd')).catch((err) => { + logger.errorRequest(err); + }); + await endState(); + return; + } + + let success = true; + for (let i = 0; i < changefilesInfo.length; i += 1) { + success = await downloadChangefile(changefilesInfo[i], interval); + if (!success) return; + jobConfig.filename = changefilesInfo[i].filename; + success = await insertDataUnpaywall(jobConfig); + if (!success) return; + } + await endState(); +} + +/** + * Insert on elastic the content of file installed on ezunpaywall. + * + * @param {Object} jobConfig - Config of job. + * @param {string} jobConfig.index - Name of the index to which the data will be inserted. + * @param {string} jobConfig.filename - Filename. + * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. + * @param {number} jobConfig.limit - Line in the file where the insertion stops. + * @param {boolean} jobConfig.cleanFile - Delete file after job. + * @param {boolean} jobConfig.ignoreError - Ignore error in file. + * + * @returns {Promise} + */ +async function insertChangefileProcess(jobConfig) { + setInUpdate(true); + logger.info(`[job][${jobConfig.type}]: Start file job`); + logger.info(`[job][${jobConfig.type}]: index: [${jobConfig.index}]`); + logger.info(`[job][${jobConfig.type}]: filename: [${jobConfig.filename}]`); + logger.info(`[job][${jobConfig.type}]: offset: [${jobConfig.offset}]`); + logger.info(`[job][${jobConfig.type}]: limit: [${jobConfig.limit}]`); + logger.info(`[job][${jobConfig.type}]: cleanFile: [${jobConfig.cleanFile}]`); + logger.info(`[job][${jobConfig.type}]: ignoreError: [${jobConfig.ignoreError}]`); + await createState({ type: 'dataUpdate', index: jobConfig.index }); + const success = await insertDataUnpaywall(jobConfig); + if (success) { + await endState(); + } +} + +/** + * Download and insert on elastic the changefiles from unpaywall between a period with history. + * + * @param {Object} jobConfig - Config of job. + * @param {string} jobConfig.indexBase - Name of the index to which the data will be inserted. + * @param {string} jobConfig.indexHistory - Name of the index to which the data will be inserted. + * @param {string} jobConfig.interval - Interval of changefile, day or week are available. + * @param {string} jobConfig.startDate - Start date for the changefile period. + * @param {string} jobConfig.endDate - End date for the changefile period. + * @param {boolean} jobConfig.cleanFile - Delete file after job. + * @param {boolean} jobConfig.ignoreError - Ignore error in file. + * + * @returns {Promise} + */ +async function insertWithOaHistoryProcess(jobConfig) { + setInUpdate(true); + const { + interval, startDate, endDate, cleanFile, + } = jobConfig; + logger.info('[job][history]: Start history job'); + logger.info(`[job][history]: indexBase: [${jobConfig.indexBase}]`); + logger.info(`[job][history]: indexHistory: [${jobConfig.indexHistory}]`); + logger.info(`[job][history]: interval: [${jobConfig.interval}]`); + logger.info(`[job][history]: startDate: [${jobConfig.startDate}]`); + logger.info(`[job][history]: endDate: [${jobConfig.endDate}]`); + logger.info(`[job][history]: cleanFile: [${jobConfig.cleanFile}]`); + logger.info(`[job][history]: ignoreError: [${jobConfig.ignoreError}]`); + await createState({ type: 'dataUpdateHistory', indexBase: jobConfig.indexBase, indexHistory: jobConfig.indexHistory }); + const start = new Date(); + addStepGetChangefiles(); + const step = getLatestStep(); + const changefilesInfo = await getChangefiles(interval, startDate, endDate); + + if (!changefilesInfo) { + step.status = 'error'; + updateLatestStep(step); + await fail(); + return; + } + + step.took = (new Date() - start) / 1000; + step.status = 'success'; + updateLatestStep(step); + + if (changefilesInfo.length === 0) { + sendMailNoChangefile(startDate, endDate).catch((err) => { + logger.errorRequest(err); + }); + await endState(); + return; + } + + let success = true; + for (let i = 0; i < changefilesInfo.length; i += 1) { + success = await downloadChangefile(changefilesInfo[i], interval); + if (!success) return; + jobConfig.filename = changefilesInfo[i].filename; + success = await insertHistoryDataUnpaywall(jobConfig); + if (cleanFile) { + await deleteFile(path.resolve(paths.data.changefilesDir, changefilesInfo[i].filename)); + } + if (!success) return; + } + await endState(); +} + +module.exports = { + downloadSnapshotProcess, + downloadAndInsertSnapshotProcess, + insertChangefilesOnPeriodProcess, + insertChangefileProcess, + insertWithOaHistoryProcess, +}; diff --git a/src/update/lib/insert.js b/services/update/src/process/insert.js similarity index 65% rename from src/update/lib/insert.js rename to services/update/src/process/insert.js index b76a1f2a..9a8ecc19 100644 --- a/src/update/lib/insert.js +++ b/services/update/src/process/insert.js @@ -5,28 +5,29 @@ const path = require('path'); const fs = require('fs-extra'); const readline = require('readline'); -const config = require('config'); +const { elasticsearch } = require('config'); const zlib = require('zlib'); +const { paths } = require('config'); -const logger = require('./logger'); -const unpaywallMapping = require('../mapping/unpaywall.json'); +const logger = require('../logger/appLogger'); +const unpaywallMapping = require('../../mapping/unpaywall.json'); const { addStepInsert, getLatestStep, updateLatestStep, fail, -} = require('./models/state'); +} = require('../lib/state'); const { - elasticClient, + refreshIndex, + bulk, + initAlias, createIndex, -} = require('./services/elastic'); +} = require('../services/elastic'); -const indexAlias = config.get('elasticsearch.indexAlias'); -const maxBulkSize = config.get('elasticsearch.maxBulkSize'); - -const snapshotsDir = path.resolve(__dirname, '..', 'data', 'snapshots'); +const { indexAlias } = elasticsearch; +const { maxBulkSize } = elasticsearch; /** * Insert data on elastic with elastic bulk request. @@ -35,13 +36,13 @@ const snapshotsDir = path.resolve(__dirname, '..', 'data', 'snapshots'); * * @returns {Promise} Success or not. */ -async function insertDataInElastic(data) { +async function insertUnpaywallDataInElastic(data) { const step = getLatestStep(); let res; try { - res = await elasticClient.bulk({ body: data }); + res = await bulk(data); } catch (err) { - logger.error('[elastic] Cannot bulk', err); + logger.error('[elastic]: Cannot bulk', err); await fail(err?.[0]?.reason); return false; } @@ -51,7 +52,7 @@ async function insertDataInElastic(data) { items.forEach((i) => { if (i?.index?.result === 'created') { - step.insertedDocs += 1; + step.addedDocs += 1; return; } if (i?.index?.result === 'updated') { @@ -66,9 +67,9 @@ async function insertDataInElastic(data) { }); if (errors.length > 0) { - logger.error('[elastic] Error in bulk insertion'); + logger.error('[elastic]: Error in bulk insertion'); errors.forEach((error) => { - logger.error(`[elastic] ${JSON.stringify(error, null, 2)}`); + logger.error(`[elastic]: ${JSON.stringify(error, null, 2)}`); }); step.status = 'error'; updateLatestStep(step); @@ -95,7 +96,7 @@ async function insertDataInElastic(data) { */ async function insertDataUnpaywall(insertConfig) { const { - filename, index, offset, limit, + filename, index, offset, limit, ignoreError, type, } = insertConfig; // step insertion in the state @@ -109,34 +110,29 @@ async function insertDataUnpaywall(insertConfig) { try { await createIndex(index, unpaywallMapping); } catch (err) { - logger.error(`[elastic] Cannot create index [${index}]`, err); + logger.error(`[elastic]: Cannot create index [${index}]`, err); await fail(err); return false; } - try { - const { body: aliasExists } = await elasticClient.indices.existsAlias({ name: indexAlias }); + await initAlias(index, unpaywallMapping, indexAlias); - if (aliasExists) { - logger.info(`[elastic] Alias [${indexAlias}] pointing to index [${index}] already exists`); - } else { - logger.info(`[elastic] Creating alias [${indexAlias}] pointing to index [${index}]`); - await elasticClient.indices.putAlias({ index, name: indexAlias }); - } - } catch (err) { - logger.error(`[elastic] Cannot create alias [${indexAlias}] pointing to index [${index}]`, err); - await fail(err); - return false; + let filePath; + + if (type === 'changefile') { + filePath = path.resolve(paths.data.changefilesDir, filename); } - const filePath = path.resolve(snapshotsDir, filename); + if (type === 'snapshot') { + filePath = path.resolve(paths.data.snapshotsDir, filename); + } // get information "bytes" for state let bytes; try { bytes = await fs.stat(filePath); } catch (err) { - logger.error(`[job: insert] Cannot stat [${filePath}]`, err); + logger.error(`[job][insert]: Cannot get bytes [${filePath}]`, err); await fail(err); return false; } @@ -146,7 +142,7 @@ async function insertDataUnpaywall(insertConfig) { try { readStream = fs.createReadStream(filePath); } catch (err) { - logger.error(`[job: insert] Cannot read [${filePath}]`, err); + logger.error(`[job][insert]: Cannot read [${filePath}]`, err); await fail(err); return false; } @@ -161,7 +157,7 @@ async function insertDataUnpaywall(insertConfig) { try { decompressedStream = readStream.pipe(zlib.createGunzip()); } catch (err) { - logger.error(`[job: insert] Cannot pipe [${readStream?.filename}]`, err); + logger.error(`[job][insert]: Cannot pipe [${readStream?.filename}]`, err); await fail(err); return false; } @@ -176,7 +172,7 @@ async function insertDataUnpaywall(insertConfig) { let success; - logger.info(`[job: insert] Start insert with [${filename}]`); + logger.info(`[job][insert]: Start insert with [${filename}]`); // Reads line by line the output of the decompression stream to make packets of 1000 // to insert them in bulk in an elastic @@ -193,42 +189,45 @@ async function insertDataUnpaywall(insertConfig) { // fill the array try { const doc = JSON.parse(line); + doc.referencedAt = doc.updated; + if (!doc.updated) { logger.error('[job][insert]: no update is send'); } bulkOps.push({ index: { _index: index, _id: doc.doi } }); bulkOps.push(doc); } catch (err) { - logger.error(`[job: insert] Cannot parse [${line}] in json format`, err); - await fail(err); - return false; + logger.error(`[job][insert]: Cannot parse [${line}] in json format`, err); + if (!ignoreError) { + await fail(err); + return false; + } } } // bulk insertion if (bulkOps.length >= maxBulkSize) { - const dataToInsert = bulkOps.slice(); + success = await insertUnpaywallDataInElastic(bulkOps, step); bulkOps = []; - success = await insertDataInElastic(dataToInsert, step); if (!success) return false; step.percent = ((loaded / bytes.size) * 100).toFixed(2); step.took = (new Date() - start) / 1000; updateLatestStep(step); } if (step.linesRead % 100000 === 0) { - logger.info(`[job: insert] ${step.linesRead} Lines reads`); + logger.info(`[job][insert]: ${step.linesRead} Lines reads`); updateLatestStep(step); } } // last insertion if there is data left if (bulkOps.length > 0) { - success = await insertDataInElastic(bulkOps, step); - if (!success) return false; + success = await insertUnpaywallDataInElastic(bulkOps, step); bulkOps = []; + if (!success) return false; } - logger.info('[job: insert] insertion completed'); + logger.info('[job][insert]: insertion completed'); try { - await elasticClient.indices.refresh({ index }); + await refreshIndex(); } catch (err) { - logger.warn('[elastic] Cannot refresh the index', err); + logger.warn('[elastic]: Cannot refresh the index', err); } // last update of step diff --git a/services/update/src/routers/changefile.js b/services/update/src/routers/changefile.js new file mode 100644 index 00000000..0ec79227 --- /dev/null +++ b/services/update/src/routers/changefile.js @@ -0,0 +1,35 @@ +const router = require('express').Router(); + +const upload = require('../middlewares/uploadChangefile'); +const checkAuth = require('../middlewares/auth'); +const dev = require('../middlewares/dev'); + +const validateLatest = require('../middlewares/format/latest'); +const validateFilename = require('../middlewares/format/filename'); + +const { getChangefiles, uploadChangefile, deleteChangefile } = require('../controllers/changefile'); + +/** + * Route that give the list of changefiles installed on ezunpaywall or the most recent file. + * Auth required. + * + * This route can take in query latest. + */ +router.get('/changefiles', checkAuth, validateLatest, getChangefiles); + +/** + * Route that upload a changefile on ezunpaywall. + * Auth required. + * Using for test. + * + * This route need a body that contains the file to upload. + */ +router.post('/changefiles', dev, checkAuth, upload.single('file'), uploadChangefile); + +/** + * Route that delete a changefile on ezunpaywall. + * Auth required. + */ +router.delete('/changefiles/:filename', dev, checkAuth, validateFilename, deleteChangefile); + +module.exports = router; diff --git a/services/update/src/routers/cron.js b/services/update/src/routers/cron.js new file mode 100644 index 00000000..23e25772 --- /dev/null +++ b/services/update/src/routers/cron.js @@ -0,0 +1,39 @@ +const router = require('express').Router(); + +const checkAuth = require('../middlewares/auth'); +const validateCronConfig = require('../middlewares/format/cron'); +const { validateParamsType } = require('../middlewares/format/type'); + +const { + startCron, + stopCron, + patchCron, + getConfigCron, +} = require('../controllers/cron'); + +/** + * Route that start the update cron. + * Auth required. + */ +router.post('/cron/:type/start', checkAuth, validateParamsType, startCron); + +/** + * Route that stop the update cron. + * Auth required. + */ +router.post('/cron/:type/stop', checkAuth, validateParamsType, stopCron); + +/** + * Route that update the update cron. + * Auth required. + * + * This route need a body that contains a config of cron. + */ +router.patch('/cron/:type', checkAuth, validateParamsType, validateCronConfig, patchCron); + +/** + * Route that get the config of update cron. + */ +router.get('/cron/:type', validateParamsType, getConfigCron); + +module.exports = router; diff --git a/services/update/src/routers/elastic.js b/services/update/src/routers/elastic.js new file mode 100644 index 00000000..13423f11 --- /dev/null +++ b/services/update/src/routers/elastic.js @@ -0,0 +1,27 @@ +const router = require('express').Router(); + +const checkAuth = require('../middlewares/auth'); +const { createAlias, getIndices, getAlias } = require('../controllers/elastic'); + +/** + * Route that init unpaywall elastic alias with local mapping. + * + * Auth required. + */ +router.post('/elastic/alias', checkAuth, createAlias); + +/** + * Route that get indices on elastic. + * + * Auth required. + */ +router.get('/elastic/indices', checkAuth, getIndices); + +/** + * Route that get alias on elastic. + * + * Auth required. + */ +router.get('/elastic/aliases', checkAuth, getAlias); + +module.exports = router; diff --git a/services/update/src/routers/healthcheck.js b/services/update/src/routers/healthcheck.js new file mode 100644 index 00000000..5eb10fe8 --- /dev/null +++ b/services/update/src/routers/healthcheck.js @@ -0,0 +1,10 @@ +const router = require('express').Router(); + +const healthCheckLogger = require('../logger/healthcheck'); + +/** + * Route use for healthcheck. + */ +router.get('/healthcheck', healthCheckLogger, (req, res, next) => res.status(204).end()); + +module.exports = router; diff --git a/services/update/src/routers/job.js b/services/update/src/routers/job.js new file mode 100644 index 00000000..8464ef1c --- /dev/null +++ b/services/update/src/routers/job.js @@ -0,0 +1,122 @@ +const router = require('express').Router(); + +const { + downloadSnapshotJob, + downloadAndInsertSnapshotJob, + insertChangefilesOnPeriodJob, + insertChangefileJob, + insertSnapshotJob, +} = require('../controllers/job'); + +const { + validateSnapshotJob, + validateJobChangefilesConfig, + validateInsertFile, +} = require('../middlewares/format/job'); + +const { insertWithOaHistory, historyRollBack } = require('../controllers/job'); + +const { step1, step2, step3 } = require('../process/history'); + +const { validateHistoryJob, validateHistoryReset } = require('../middlewares/format/job'); +const checkStatus = require('../middlewares/status'); +const checkAuth = require('../middlewares/auth'); + +/** + * Route that download the current snapshot of unpaywall. + * Auth required. + * No update process should be in progress. + */ +router.post('/job/download/snapshot', checkStatus, checkAuth, downloadSnapshotJob); + +/** + * Route that download the current snapshot of unpaywall and insert his content. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job. + */ +router.post('/job/download/insert/snapshot', checkStatus, checkAuth, validateSnapshotJob, downloadAndInsertSnapshotJob); + +/** + * Route that download and insert on elastic the changefiles from unpaywall between a period. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job. + */ +router.post('/job/download/insert/changefile/period', checkStatus, checkAuth, validateJobChangefilesConfig, insertChangefilesOnPeriodJob); + +/** + * Route that download and insert on elastic the changefiles from unpaywall between a period + * and feed the history. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job. + */ +router.post('/job/download/insert/history/period', checkStatus, checkAuth, validateHistoryJob, insertWithOaHistory); + +/** + * Route that insert on elastic the content of changefile installed on ezunpaywall. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job + * and a param which corresponds to the filename. + */ +router.post('/job/insert/changefile/:filename', checkStatus, checkAuth, validateInsertFile, insertChangefileJob); + +/** + * Route that insert on elastic the content of file changefile on ezunpaywall + * and feed the history. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job + * and a param which corresponds to the filename. + */ +router.post('/job/insert/history/changefile/:filename', checkStatus, checkAuth, validateInsertFile, insertChangefileJob); + +/** + * Route that insert on elastic the content of snapshot installed on ezunpaywall. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job + * and a param which corresponds to the filename. + */ +router.post('/job/insert/snapshot/:filename', checkStatus, checkAuth, validateInsertFile, insertSnapshotJob); + +/** + * Route that roll back the current and the history index according to a date. + * Auth required. + * No update process should be in progress. + * + * This route need a body that contains a config of job. + */ +router.post('/job/download/insert/history/period/reset', checkStatus, checkAuth, validateHistoryReset, historyRollBack); + +// Dev +router.post('/job/download/insert/history/period/reset/step1', checkStatus, checkAuth, validateHistoryReset, async (req, res, next) => { + const { startDate } = req.data; + + await step1(startDate); + return res.status(202).json(); +}); + +router.post('/job/download/insert/history/period/reset/step2', checkStatus, checkAuth, validateHistoryReset, async (req, res, next) => { + const { startDate } = req.data; + + await step2(startDate); + return res.status(202).json(); +}); + +router.post('/job/download/insert/history/period/reset/step3', checkStatus, checkAuth, validateHistoryReset, async (req, res, next) => { + const { startDate } = req.data; + + await step3(startDate); + return res.status(202).json(); +}); + +module.exports = router; diff --git a/services/update/src/routers/openapi.js b/services/update/src/routers/openapi.js new file mode 100644 index 00000000..bdf85c7d --- /dev/null +++ b/services/update/src/routers/openapi.js @@ -0,0 +1,9 @@ +const router = require('express').Router(); +const path = require('path'); + +/** + * Route that give the openapi.json file. + */ +router.get('/openapi.yml', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'openapi.yml'))); + +module.exports = router; diff --git a/src/update/lib/routers/ping.js b/services/update/src/routers/ping.js similarity index 100% rename from src/update/lib/routers/ping.js rename to services/update/src/routers/ping.js diff --git a/services/update/src/routers/report.js b/services/update/src/routers/report.js new file mode 100644 index 00000000..6b5f4ae7 --- /dev/null +++ b/services/update/src/routers/report.js @@ -0,0 +1,23 @@ +const router = require('express').Router(); + +const { getReports, getReportByFilename } = require('../controllers/report'); + +const validateLatest = require('../middlewares/format/latest'); +const validateFilename = require('../middlewares/format/filename'); +const { validateQueryType } = require('../middlewares/format/type'); + +/** + * Route that give the list of reports or the content of most recent report in JSON format. + * + * This route can take in query latest and type. + */ +router.get('/reports', validateQueryType, validateLatest, getReports); + +/** + * Route that give the content of report in JSON format. + * + * This route takes a param which corresponds to the filename of report. + */ +router.get('/reports/:filename', validateFilename, getReportByFilename); + +module.exports = router; diff --git a/src/update/lib/routers/snapshot.js b/services/update/src/routers/snapshot.js similarity index 52% rename from src/update/lib/routers/snapshot.js rename to services/update/src/routers/snapshot.js index f9c45939..b9105068 100644 --- a/src/update/lib/routers/snapshot.js +++ b/services/update/src/routers/snapshot.js @@ -1,39 +1,35 @@ const router = require('express').Router(); -const upload = require('../middlewares/multer'); +const upload = require('../middlewares/uploadSnapshot'); const checkAuth = require('../middlewares/auth'); const dev = require('../middlewares/dev'); -const validateLatest = require('../middlewares/latest'); -const validateFilename = require('../middlewares/filename'); +const validateLatest = require('../middlewares/format/latest'); +const validateFilename = require('../middlewares/format/filename'); -const { - getFiles, - uploadFile, - deleteFileInstalled, -} = require('../controllers/file'); +const { getSnapshots, uploadSnapshot, deleteSnapshot } = require('../controllers/snapshot'); /** - * Route that give the list of snapshots installed on ezunpaywall of the most recent file. + * Route that give the list of snapshots installed on ezunpaywall or the most recent file. * Auth required. * * This route can take in query latest. */ -router.get('/snapshots', checkAuth, validateLatest, getFiles); +router.get('/snapshots', checkAuth, validateLatest, getSnapshots); /** - * Route that upload a file on ezunpaywall. + * Route that upload a snapshot on ezunpaywall. * Auth required. * Using for test. * * This route need a body that contains the file to upload. */ -router.post('/snapshots', dev, checkAuth, upload.single('file'), uploadFile); +router.post('/snapshots', dev, checkAuth, upload.single('file'), uploadSnapshot); /** - * Route that delete a file on ezunpaywall. + * Route that delete a snapshot on ezunpaywall. * Auth required. */ -router.delete('/snapshots/:filename', dev, checkAuth, validateFilename, deleteFileInstalled); +router.delete('/snapshots/:filename', dev, checkAuth, validateFilename, deleteSnapshot); module.exports = router; diff --git a/src/update/lib/routers/state.js b/services/update/src/routers/state.js similarity index 100% rename from src/update/lib/routers/state.js rename to services/update/src/routers/state.js diff --git a/src/update/lib/routers/status.js b/services/update/src/routers/status.js similarity index 100% rename from src/update/lib/routers/status.js rename to services/update/src/routers/status.js diff --git a/src/update/lib/routers/unpaywall.js b/services/update/src/routers/unpaywall.js similarity index 67% rename from src/update/lib/routers/unpaywall.js rename to services/update/src/routers/unpaywall.js index 9f39047b..0ffe4798 100644 --- a/src/update/lib/routers/unpaywall.js +++ b/services/update/src/routers/unpaywall.js @@ -1,6 +1,6 @@ const router = require('express').Router(); -const validateIntervale = require('../middlewares/interval'); +const validateInterval = require('../middlewares/format/interval'); const getChangefilesOfUnpaywall = require('../controllers/unpaywall'); /** @@ -8,6 +8,6 @@ const getChangefilesOfUnpaywall = require('../controllers/unpaywall'); * * This route can take a body which corresponds to the intervale of changefile. */ -router.get('/unpaywall/changefiles', validateIntervale, getChangefilesOfUnpaywall); +router.get('/unpaywall/changefiles', validateInterval, getChangefilesOfUnpaywall); module.exports = router; diff --git a/services/update/src/services/elastic.js b/services/update/src/services/elastic.js new file mode 100644 index 00000000..afcb43a0 --- /dev/null +++ b/services/update/src/services/elastic.js @@ -0,0 +1,227 @@ +const fs = require('fs-extra'); +const path = require('path'); + +const { Client } = require('@elastic/elasticsearch'); +const { URL } = require('url'); +const { elasticsearch } = require('config'); +const { nodeEnv } = require('config'); +const logger = require('../logger/appLogger'); + +const isProd = (nodeEnv === 'production'); + +let ssl; + +if (isProd) { + let ca; + const caPath = path.resolve(__dirname, '..', '..', 'certs', 'ca.crt'); + try { + ca = fs.readFileSync(caPath, 'utf8'); + } catch (err) { + logger.error(`[elastic]: Cannot read elastic certificate file in [${caPath}]`, err); + } + ssl = { + ca, + rejectUnauthorized: true, + }; +} + +const elasticClient = new Client({ + node: { + url: new URL(`${elasticsearch.host}:${elasticsearch.port}`), + auth: { + username: elasticsearch.user, + password: elasticsearch.password, + }, + ssl, + }, + requestTimeout: elasticsearch.timeout, +}); + +/** + * Ping elastic service. + * + * @returns {Promise} ping. + */ +async function pingElastic() { + let elasticStatus; + try { + elasticStatus = await elasticClient.ping(); + } catch (err) { + logger.error(`[elastic]: Cannot ping ${elasticsearch.host}:${elasticsearch.port}`, err); + return err.message; + } + if (elasticStatus?.statusCode !== 200) { + logger.error(`[elastic]: Cannot ping ${elasticsearch.host}:${elasticsearch.port} - ${elasticStatus?.statusCode}`); + return false; + } + return true; +} + +/** + * Check if index exit. + * + * @param {string} index - Name of index. + * + * @returns {Promise} If index exist. + */ +async function checkIfIndexExist(index) { + const { body } = await elasticClient.indices.exists({ index }); + return body; +} + +/** + * Create index if it doesn't exist. + * + * @param {string} index - Name of index. + * @param {Object} mapping mapping in JSON format. + * + * @returns {Promise} + */ +async function createIndex(index, mapping) { + const exist = await checkIfIndexExist(index); + if (!exist) { + await elasticClient.indices.create({ + index, + body: mapping, + }); + } +} + +/** + * Create alias on elastic. + * + * @param {string} indexName - Name of index. + * @param {Object} mapping - Mapping of index. + * @param {string} aliasName - Name of alias. + * + * @returns {Promise} + */ +async function initAlias(indexName, mapping, aliasName) { + try { + await createIndex(indexName, mapping); + } catch (err) { + logger.error(`[elastic]: Cannot create index [${indexName}]`, err); + return; + } + + try { + const { body: aliasExists } = await elasticClient.indices.existsAlias({ name: aliasName }); + + if (aliasExists) { + logger.info(`[elastic]: Alias [${aliasName}] already exists`); + } else { + logger.info(`[elastic]: Creating alias [${aliasName}] pointing to index [${indexName}]`); + await elasticClient.indices.putAlias({ index: indexName, name: aliasName }); + } + } catch (err) { + logger.error(`[elastic]: Cannot create alias [${aliasName}] pointing to index [${indexName}]`, err); + } +} + +async function searchByDOI(dois, index) { + if (!dois) { return []; } + // Normalize request + const normalizeDOI = dois.map((doi) => doi.toLowerCase()); + + const filter = [{ terms: { doi: normalizeDOI } }]; + + const query = { + bool: { + filter, + }, + }; + + let res; + try { + res = await elasticClient.search({ + index, + size: normalizeDOI.length || 1000, + body: { + query, + }, + + }); + } catch (err) { + logger.error('[elastic]: Cannot search documents with DOI as ID', err); + return []; + } + // eslint-disable-next-line no-underscore-dangle + return res.body.hits.hits.map((hit) => hit._source); +} + +/** + * Search data with range + * @param {string} date - The date on which you want to obtain all the changes + * @param {string} index - Elastic index name + * @returns {Promise} + */ +async function searchWithRange(date, param, rangeParam, index) { + const query = { + bool: { + filter: [ + { + range: { + [param]: { + [rangeParam]: date, + }, + }, + }, + ], + }, + }; + + let res; + try { + res = await elasticClient.search({ + index, + body: { + query, + }, + }); + } catch (err) { + logger.error('[elastic]: Cannot request elastic', err); + return null; + } + // eslint-disable-next-line no-underscore-dangle + return res.body.hits.hits; +} + +async function refreshIndex(index) { + return elasticClient.indices.refresh({ index }); +} + +async function bulk(data, refresh = false) { + if (data.length === 0) { + // logger.warn('[elastic]: No data is send for bulk'); + return []; + } + return elasticClient.bulk({ body: data, refresh }); +} + +async function getIndices() { + const res = await elasticClient.cat.indices({ format: 'json' }); + let indices = res.body; + indices = indices.filter((index) => index.index.charAt(0) !== '.'); + return indices; +} + +async function getAlias() { + const regexILM = /^ilm-history-[0-9]$/; + const res = await elasticClient.cat.aliases({ format: 'json' }); + let alias = res.body; + alias = alias.filter((index) => index.index.charAt(0) !== '.').filter((index) => !regexILM.test(index.alias)); + return alias; +} + +module.exports = { + elasticClient, + pingElastic, + createIndex, + initAlias, + searchByDOI, + refreshIndex, + bulk, + searchWithRange, + getIndices, + getAlias, +}; diff --git a/src/update/lib/services/mail.js b/services/update/src/services/mail.js similarity index 75% rename from src/update/lib/services/mail.js rename to services/update/src/services/mail.js index 64a119f4..56daf253 100644 --- a/src/update/lib/services/mail.js +++ b/services/update/src/services/mail.js @@ -1,12 +1,34 @@ const axios = require('axios'); const config = require('config'); -const apikey = config.get('mail.apikey'); +const logger = require('../logger/appLogger'); + +const { apikey } = config.mail; const mail = axios.create({ - baseURL: config.get('mail.host'), + baseURL: config.mail.host, }); -mail.host = config.get('mail.host'); +mail.host = config.mail.host; + +/** + * Ping mail service. + * + * @returns {Promise} healthy or not. + */ +async function pingMail() { + let res; + try { + res = await mail({ + method: 'GET', + url: '/ping', + }); + } catch (err) { + logger.error('[mail] Cannot ping mail', err); + return err?.message; + } + if (res?.status === 204) return true; + return false; +} /** * Send update mail report. @@ -67,6 +89,7 @@ function sendMailNoChangefile(startDate, endDate) { } module.exports = { + pingMail, sendMailUpdateReport, sendMailUpdateStarted, sendMailNoChangefile, diff --git a/src/update/lib/services/unpaywall.js b/services/update/src/services/unpaywall.js similarity index 82% rename from src/update/lib/services/unpaywall.js rename to services/update/src/services/unpaywall.js index c793d72c..8f96f14e 100644 --- a/src/update/lib/services/unpaywall.js +++ b/services/update/src/services/unpaywall.js @@ -1,13 +1,33 @@ const axios = require('axios'); const config = require('config'); -const logger = require('../logger'); +const logger = require('../logger/appLogger'); + +const { apikey } = config.unpaywall; const unpaywall = axios.create({ - baseURL: config.get('unpaywall.host'), + baseURL: config.unpaywall.host, }); -unpaywall.baseURL = config.get('unpaywall.host'); +unpaywall.baseURL = config.unpaywall.host; -const apikey = config.get('unpaywall.apikey'); +/** + * Ping unpaywall. + * + * @returns {Promise} healthy or not. + */ +async function pingUnpaywall() { + let res; + try { + res = await unpaywall({ + method: 'GET', + url: '/ping', + }); + } catch (err) { + logger.error('[unpaywall] Cannot ping unpaywall', err); + return err?.message; + } + if (res?.status === 204) return true; + return false; +} /** * Get the current snapshot. @@ -115,6 +135,7 @@ async function getChangefile(filename, interval) { } module.exports = { + pingUnpaywall, getSnapshot, getChangefiles, getChangefile, diff --git a/src/update/test/auth.js b/services/update/test/auth.js similarity index 75% rename from src/update/test/auth.js rename to services/update/test/auth.js index a721c82f..9578a799 100644 --- a/src/update/test/auth.js +++ b/services/update/test/auth.js @@ -3,9 +3,9 @@ const chai = require('chai'); const chaiHttp = require('chai-http'); const { - deleteFile, - updateChangeFile, -} = require('./utils/snapshot'); + deleteChangefile, + updateChangefile, +} = require('./utils/changefile'); const { deleteIndex, @@ -23,17 +23,17 @@ describe('Test: auth service in update service', () => { before(async function () { this.timeout(30000); await ping(); - await updateChangeFile('week'); - await deleteFile('fake1.jsonl.gz'); - await deleteFile('fake2.jsonl.gz'); - await deleteFile('fake3.jsonl.gz'); + await updateChangefile('week'); + await deleteChangefile('fake1.jsonl.gz'); + await deleteChangefile('fake2.jsonl.gz'); + await deleteChangefile('fake3.jsonl.gz'); await deleteIndex('unpaywall-test'); }); describe('Test with admin API key', () => { it('Should return status code 202', async () => { const res = await chai.request(updateURL) - .post('/job/period') + .post('/job/download/insert/changefile/period') .send({ index: 'unpaywall-test', }) @@ -43,7 +43,7 @@ describe('Test: auth service in update service', () => { let isUpdate = true; while (isUpdate) { - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { setTimeout(resolve, 100); }); isUpdate = await checkIfInUpdate(); } expect(res).have.status(202); @@ -53,7 +53,7 @@ describe('Test: auth service in update service', () => { describe('Test without API key', () => { it('Should return a status code 401', async () => { const res = await chai.request(updateURL) - .post('/job/period') + .post('/job/download/insert/changefile/period') .send({ index: 'unpaywall-test', }) @@ -67,7 +67,7 @@ describe('Test: auth service in update service', () => { describe('Test with wrong API key', () => { it('Should return a status code 401', async () => { const res = await chai.request(updateURL) - .post('/job/period') + .post('/job/download/insert/changefile/period') .send({ index: 'unpaywall-test', }) @@ -82,8 +82,8 @@ describe('Test: auth service in update service', () => { after(async () => { await deleteIndex('unpaywall-test'); - await deleteFile('fake1.jsonl.gz'); - await deleteFile('fake2.jsonl.gz'); - await deleteFile('fake3.jsonl.gz'); + await deleteChangefile('fake1.jsonl.gz'); + await deleteChangefile('fake2.jsonl.gz'); + await deleteChangefile('fake3.jsonl.gz'); }); }); diff --git a/src/update/test/cron.js b/services/update/test/dataUpdateCron.js similarity index 89% rename from src/update/test/cron.js rename to services/update/test/dataUpdateCron.js index a785c27e..92f48637 100644 --- a/src/update/test/cron.js +++ b/services/update/test/dataUpdateCron.js @@ -11,7 +11,7 @@ chai.use(chaiHttp); const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; -describe('Test: cron manage', () => { +describe('Test: manage dataUpdate cron', () => { before(async function () { this.timeout(30000); await ping(); @@ -24,7 +24,7 @@ describe('Test: cron manage', () => { it('Should return config of cron', async () => { const res = await chai.request(updateURL) - .get('/cron'); + .get('/cron/dataUpdate'); expect(res).have.status(200); @@ -42,8 +42,8 @@ describe('Test: cron manage', () => { it('Should return updated config of cron', async () => { const res = await chai.request(updateURL) - .patch('/cron') - .send({ time: '0 0 0 1 * *' }) + .patch('/cron/dataUpdate') + .send({ schedule: '0 0 0 1 * *' }) .set('x-api-key', 'changeme'); expect(res).have.status(200); @@ -62,7 +62,7 @@ describe('Test: cron manage', () => { it('Should return updated config of cron', async () => { const res = await chai.request(updateURL) - .patch('/cron') + .patch('/cron/dataUpdate') .send({ index: 'unpaywall2' }) .set('x-api-key', 'changeme'); @@ -82,7 +82,7 @@ describe('Test: cron manage', () => { it('Should return updated config of cron', async () => { const res = await chai.request(updateURL) - .patch('/cron') + .patch('/cron/dataUpdate') .send({ interval: 'week' }) .set('x-api-key', 'changeme'); @@ -102,7 +102,7 @@ describe('Test: cron manage', () => { it('Should return a status code 401', async () => { const res = await chai.request(updateURL) - .patch('/cron') + .patch('/cron/dataUpdate') .send({ interval: 'week' }); expect(res).have.status(401); @@ -117,7 +117,7 @@ describe('Test: cron manage', () => { it('Should return a status code 401', async () => { const res = await chai.request(updateURL) - .patch('/cron') + .patch('/cron/dataUpdate') .send({ interval: 'week' }) .set('x-api-key', 'wrong apikey'); @@ -125,14 +125,14 @@ describe('Test: cron manage', () => { }); }); - describe('Test: update start update cron', () => { + describe('Test: start update cron', () => { before(async () => { await reset(); }); it('Should return a status code 202', async () => { const res = await chai.request(updateURL) - .post('/cron/start') + .post('/cron/dataUpdate/start') .set('x-api-key', 'changeme'); expect(res).have.status(202); @@ -140,7 +140,7 @@ describe('Test: cron manage', () => { it('Should return updated config of cron', async () => { const res = await chai.request(updateURL) - .get('/cron'); + .get('/cron/dataUpdate'); expect(res).have.status(200); @@ -151,14 +151,14 @@ describe('Test: cron manage', () => { }); }); - describe('Test: update start update cron', () => { + describe('Test: stop update cron', () => { before(async () => { await reset(); }); it('Should return a status code 202', async () => { const res = await chai.request(updateURL) - .post('/cron/stop') + .post('/cron/dataUpdate/stop') .set('x-api-key', 'changeme'); expect(res).have.status(202); @@ -166,7 +166,7 @@ describe('Test: cron manage', () => { it('Should return updated config of cron', async () => { const res = await chai.request(updateURL) - .get('/cron'); + .get('/cron/dataUpdate'); expect(res).have.status(200); diff --git a/services/update/test/dataUpdateHistoryCron.js b/services/update/test/dataUpdateHistoryCron.js new file mode 100644 index 00000000..f2323e60 --- /dev/null +++ b/services/update/test/dataUpdateHistoryCron.js @@ -0,0 +1,191 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const reset = require('./utils/reset'); + +const ping = require('./utils/ping'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Test: manage unpaywall history cron', () => { + before(async function () { + this.timeout(30000); + await ping(); + }); + + describe('Test: get config of cron', () => { + before(async () => { + await reset(); + }); + + it('Should return config of cron', async () => { + const res = await chai.request(updateURL) + .get('/cron/dataUpdateHistory'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 * * *'); + expect(res.body).have.property('active').equal(true); + expect(res.body).have.property('indexBase').equal('unpaywall-base'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('day'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); + + describe('Test: update time config of cron', () => { + before(async () => { + await reset(); + }); + + it('Should return updated config of cron', async () => { + const res = await chai.request(updateURL) + .patch('/cron/dataUpdateHistory') + .send({ schedule: '0 0 0 1 * *' }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 1 * *'); + expect(res.body).have.property('active').equal(true); + expect(res.body).have.property('indexBase').equal('unpaywall-base'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('day'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); + + describe('Test: update status config of cron', () => { + before(async () => { + await reset(); + }); + + it('Should return updated config of cron', async () => { + const res = await chai.request(updateURL) + .patch('/cron/dataUpdateHistory') + .send({ indexBase: 'unpaywall-base2' }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 * * *'); + expect(res.body).have.property('active').equal(true); + expect(res.body).have.property('indexBase').equal('unpaywall-base2'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('day'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); + + describe('Test: update status config of cron', () => { + before(async () => { + await reset(); + }); + + it('Should return updated config of cron', async () => { + const res = await chai.request(updateURL) + .patch('/cron/dataUpdateHistory') + .send({ interval: 'week' }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 * * *'); + expect(res.body).have.property('active').equal(true); + expect(res.body).have.property('indexBase').equal('unpaywall-base'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('week'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); + + describe('Test: update time config of cron without admin apikey', () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 401', async () => { + const res = await chai.request(updateURL) + .patch('/cron/dataUpdateHistory') + .send({ interval: 'week' }); + + expect(res).have.status(401); + }); + }); + + describe('Test: update time config of cron with wrong admin apikey', () => { + before(async function () { + this.timeout(30000); + await reset(); + }); + + it('Should return a status code 401', async () => { + const res = await chai.request(updateURL) + .patch('/cron/dataUpdateHistory') + .send({ interval: 'week' }) + .set('x-api-key', 'wrong apikey'); + + expect(res).have.status(401); + }); + }); + + describe('Test: stop update cron', () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/cron/dataUpdateHistory/stop') + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should return updated config of cron', async () => { + const res = await chai.request(updateURL) + .get('/cron/dataUpdateHistory'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 * * *'); + expect(res.body).have.property('active').equal(false); + expect(res.body).have.property('indexBase').equal('unpaywall-base'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('day'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); + + describe('Test: start update cron', () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/cron/dataUpdateHistory/start') + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should return updated config of cron', async () => { + const res = await chai.request(updateURL) + .get('/cron/dataUpdateHistory'); + + expect(res).have.status(200); + + expect(res.body).have.property('schedule').equal('0 0 0 * * *'); + expect(res.body).have.property('active').equal(true); + expect(res.body).have.property('indexBase').equal('unpaywall-base'); + expect(res.body).have.property('indexHistory').equal('unpaywall-history'); + expect(res.body).have.property('interval').equal('day'); + expect(res.body).have.property('name').equal('Data update history'); + }); + }); +}); diff --git a/services/update/test/history.js b/services/update/test/history.js new file mode 100644 index 00000000..70fce9ed --- /dev/null +++ b/services/update/test/history.js @@ -0,0 +1,884 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +const { countDocuments } = require('./utils/elastic'); +const { addSnapshot, insertSnapshot } = require('./utils/snapshot'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); +const { searchByDOI } = require('./utils/elastic'); + +const date2 = '2020-01-02'; +const date3 = '2020-01-03'; +const date4 = '2019-01-04'; +const date5 = '2020-01-05'; + +describe('Test: daily update route test with history', () => { + before(async function () { + this.timeout(1000); + await ping(); + await reset(); + await addSnapshot('2020-01-01-snapshot.jsonl.gz'); + await insertSnapshot('2020-01-01-snapshot.jsonl.gz', 'unpaywall-base'); + }); + + describe('insert changefile 2020-01-02', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date2, + endDate: date2, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 3 data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(3); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(2); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(2); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(2); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + const historyRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-history'); + + historyRes.sort(compare); + + expect(historyRes[0]).have.property('doi').equal('1'); + expect(historyRes[0]).have.property('version').equal(1); + expect(historyRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[1]).have.property('doi').equal('2'); + expect(historyRes[1]).have.property('version').equal(1); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[2]).have.property('doi').equal('3'); + expect(historyRes[2]).have.property('version').equal(1); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('type').equal('dataUpdateHistory'); + expect(result).have.property('took').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('indices').to.be.an('array'); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-base'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(3); + + expect(indices[1]).have.property('index').equal('unpaywall-history'); + expect(indices[1]).have.property('added').equal(3); + expect(indices[1]).have.property('updated').equal(0); + + const stepChangefile = result.steps[0]; + + expect(stepChangefile).have.property('task').equal('getChangefiles'); + expect(stepChangefile).have.property('took').to.not.equal(undefined); + expect(stepChangefile).have.property('status').equal('success'); + + const stepDownload = result.steps[1]; + + expect(stepDownload).have.property('task').equal('download'); + expect(stepDownload).have.property('file').equal('2020-01-02-history.jsonl.gz'); + expect(stepDownload).have.property('percent').equal(100); + expect(stepDownload).have.property('took').to.not.equal(undefined); + expect(stepDownload).have.property('status').equal('success'); + + const stepInsert = result.steps[2]; + + expect(stepInsert).have.property('task').equal('insert'); + expect(stepInsert).have.property('file').equal('2020-01-02-history.jsonl.gz'); + expect(stepInsert).have.property('percent').equal(100); + expect(stepInsert).have.property('linesRead').equal(3); + expect(stepInsert).have.property('addedDocs').equal(0); + expect(stepInsert).have.property('updatedDocs').equal(0); + expect(stepInsert).have.property('failedDocs').equal(0); + expect(stepInsert).have.property('took').to.not.equal(undefined); + expect(stepInsert).have.property('status').equal('success'); + + const indexBase = stepInsert.indices['unpaywall-base']; + expect(indexBase).have.property('addedDocs').equal(0); + expect(indexBase).have.property('updatedDocs').equal(3); + expect(indexBase).have.property('failedDocs').equal(0); + + const indexHistory = stepInsert.indices['unpaywall-history']; + expect(indexHistory).have.property('addedDocs').equal(3); + expect(indexHistory).have.property('updatedDocs').equal(0); + expect(indexHistory).have.property('failedDocs').equal(0); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdateHistory'); + testResult(report); + }); + }); + + describe('insert changefile 2020-01-03', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date3, + endDate: date3, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 2 data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(5); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(3); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-03T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(3); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-03T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(2); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + const historyRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-history'); + + historyRes.sort(compare); + + expect(historyRes[0]).have.property('doi').equal('1'); + expect(historyRes[0]).have.property('version').equal(1); + expect(historyRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[1]).have.property('doi').equal('1'); + expect(historyRes[1]).have.property('version').equal(2); + expect(historyRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + expect(historyRes[1]).have.property('endValidity').equal('2020-01-03T01:00:00.000000'); + + expect(historyRes[2]).have.property('doi').equal('2'); + expect(historyRes[2]).have.property('version').equal(1); + expect(historyRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[3]).have.property('doi').equal('2'); + expect(historyRes[3]).have.property('version').equal(2); + expect(historyRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[3]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + expect(historyRes[3]).have.property('endValidity').equal('2020-01-03T01:00:00.000000'); + + expect(historyRes[4]).have.property('doi').equal('3'); + expect(historyRes[4]).have.property('version').equal(1); + expect(historyRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[4]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('type').equal('dataUpdateHistory'); + expect(result).have.property('took').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-base'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(2); + + expect(indices[1]).have.property('index').equal('unpaywall-history'); + expect(indices[1]).have.property('added').equal(2); + expect(indices[1]).have.property('updated').equal(0); + + const stepChangefile = result.steps[0]; + + expect(stepChangefile).have.property('task').equal('getChangefiles'); + expect(stepChangefile).have.property('took').to.not.equal(undefined); + expect(stepChangefile).have.property('status').equal('success'); + + const stepDownload = result.steps[1]; + + expect(stepDownload).have.property('task').equal('download'); + expect(stepDownload).have.property('file').equal('2020-01-03-history.jsonl.gz'); + expect(stepDownload).have.property('percent').equal(100); + expect(stepDownload).have.property('took').to.not.equal(undefined); + expect(stepDownload).have.property('status').equal('success'); + + const stepInsert = result.steps[2]; + + expect(stepInsert).have.property('task').equal('insert'); + expect(stepInsert).have.property('file').equal('2020-01-03-history.jsonl.gz'); + expect(stepInsert).have.property('percent').equal(100); + expect(stepInsert).have.property('linesRead').equal(2); + expect(stepInsert).have.property('addedDocs').equal(0); + expect(stepInsert).have.property('updatedDocs').equal(0); + expect(stepInsert).have.property('failedDocs').equal(0); + expect(stepInsert).have.property('took').to.not.equal(undefined); + expect(stepInsert).have.property('status').equal('success'); + + const indexBase = stepInsert.indices['unpaywall-base']; + expect(indexBase).have.property('addedDocs').equal(0); + expect(indexBase).have.property('updatedDocs').equal(2); + expect(indexBase).have.property('failedDocs').equal(0); + + const indexHistory = stepInsert.indices['unpaywall-history']; + expect(indexHistory).have.property('addedDocs').equal(2); + expect(indexHistory).have.property('updatedDocs').equal(0); + expect(indexHistory).have.property('failedDocs').equal(0); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdateHistory'); + testResult(report); + }); + }); + + describe('insert changefile 2020-01-03 again', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date3, + endDate: date3, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should not insert new data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(5); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(3); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-03T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(3); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-03T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(2); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + const historyRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-history'); + + historyRes.sort(compare); + + expect(historyRes[0]).have.property('doi').equal('1'); + expect(historyRes[0]).have.property('version').equal(1); + expect(historyRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[1]).have.property('doi').equal('1'); + expect(historyRes[1]).have.property('version').equal(2); + expect(historyRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + expect(historyRes[1]).have.property('endValidity').equal('2020-01-03T01:00:00.000000'); + + expect(historyRes[2]).have.property('doi').equal('2'); + expect(historyRes[2]).have.property('version').equal(1); + expect(historyRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[3]).have.property('doi').equal('2'); + expect(historyRes[3]).have.property('version').equal(2); + expect(historyRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[3]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + expect(historyRes[3]).have.property('endValidity').equal('2020-01-03T01:00:00.000000'); + + expect(historyRes[4]).have.property('doi').equal('3'); + expect(historyRes[4]).have.property('version').equal(1); + expect(historyRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[4]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('type').equal('dataUpdateHistory'); + expect(result).have.property('took').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-base'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(2); + + expect(indices[1]).have.property('index').equal('unpaywall-history'); + expect(indices[1]).have.property('added').equal(0); + expect(indices[1]).have.property('updated').equal(0); + + const stepChangefile = result.steps[0]; + + expect(stepChangefile).have.property('task').equal('getChangefiles'); + expect(stepChangefile).have.property('took').to.not.equal(undefined); + expect(stepChangefile).have.property('status').equal('success'); + + const stepDownload = result.steps[1]; + + expect(stepDownload).have.property('task').equal('download'); + expect(stepDownload).have.property('file').equal('2020-01-03-history.jsonl.gz'); + expect(stepDownload).have.property('percent').equal(100); + expect(stepDownload).have.property('took').to.not.equal(undefined); + expect(stepDownload).have.property('status').equal('success'); + + const stepInsert = result.steps[2]; + + expect(stepInsert).have.property('task').equal('insert'); + expect(stepInsert).have.property('file').equal('2020-01-03-history.jsonl.gz'); + expect(stepInsert).have.property('percent').equal(100); + expect(stepInsert).have.property('linesRead').equal(2); + expect(stepInsert).have.property('addedDocs').equal(0); + expect(stepInsert).have.property('updatedDocs').equal(0); + expect(stepInsert).have.property('failedDocs').equal(0); + expect(stepInsert).have.property('took').to.not.equal(undefined); + expect(stepInsert).have.property('status').equal('success'); + + const indexBase = stepInsert.indices['unpaywall-base']; + expect(indexBase).have.property('addedDocs').equal(0); + expect(indexBase).have.property('updatedDocs').equal(2); + expect(indexBase).have.property('failedDocs').equal(0); + + const indexHistory = stepInsert.indices['unpaywall-history']; + expect(indexHistory).have.property('addedDocs').equal(0); + expect(indexHistory).have.property('updatedDocs').equal(0); + expect(indexHistory).have.property('failedDocs').equal(0); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdateHistory'); + testResult(report); + }); + }); + + describe('insert changefile 2020-01-02 again', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date2, + endDate: date2, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 0 data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(5); + }); + }); +}); + +describe('Test: Insert 2 time the same file in history', () => { + before(async function () { + this.timeout(1000); + await ping(); + await reset(); + await addSnapshot('2020-01-01-snapshot.jsonl.gz'); + await insertSnapshot('2020-01-01-snapshot.jsonl.gz', 'unpaywall-base'); + }); + + describe('insert changefile 2020-01-02', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date2, + endDate: date2, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 3 data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(3); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(2); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(2); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(2); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + const historyRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-history'); + + historyRes.sort(compare); + + expect(historyRes[0]).have.property('doi').equal('1'); + expect(historyRes[0]).have.property('version').equal(1); + expect(historyRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[1]).have.property('doi').equal('2'); + expect(historyRes[1]).have.property('version').equal(1); + expect(historyRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[2]).have.property('doi').equal('3'); + expect(historyRes[2]).have.property('version').equal(1); + expect(historyRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + }); + }); + + describe('insert changefile 2020-01-02', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date2, + endDate: date2, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 3 data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(3); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(2); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(2); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(2); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-02T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + const historyRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-history'); + + historyRes.sort(compare); + + expect(historyRes[0]).have.property('doi').equal('1'); + expect(historyRes[0]).have.property('version').equal(1); + expect(historyRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[0]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[1]).have.property('doi').equal('2'); + expect(historyRes[1]).have.property('version').equal(1); + expect(historyRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[1]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + + expect(historyRes[2]).have.property('doi').equal('3'); + expect(historyRes[2]).have.property('version').equal(1); + expect(historyRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + expect(historyRes[2]).have.property('endValidity').equal('2020-01-02T01:00:00.000000'); + }); + }); +}); + +describe('Test: Insert a old file 2019-01-01', () => { + before(async function () { + this.timeout(1000); + await ping(); + await reset(); + await addSnapshot('2020-01-01-snapshot.jsonl.gz'); + await insertSnapshot('2020-01-01-snapshot.jsonl.gz', 'unpaywall-base'); + }); + describe('insert changefile 2019-01-01', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date4, + endDate: date4, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + expect(res).have.status(202); + }); + + it('Should no insert new data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(5); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(0); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(1); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(1); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(1); + // This is normal that referencedAt is erase + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + // This is normal that referencedAt is erase + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + }); + }); +}); + +describe('Test: insert changefile with only new documents', () => { + before(async function () { + this.timeout(5000); + await ping(); + await reset(); + await addSnapshot('2020-01-01-snapshot.jsonl.gz'); + await insertSnapshot('2020-01-01-snapshot.jsonl.gz', 'unpaywall-base'); + }); + describe('insert changefile 2020-01-05 with only new lines', () => { + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + startDate: date5, + endDate: date5, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should not insert new data in history', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const countUnpaywallBase = await countDocuments('unpaywall-base'); + expect(countUnpaywallBase).to.equal(7); + const countUnpaywallHistory = await countDocuments('unpaywall-history'); + expect(countUnpaywallHistory).to.equal(0); + }); + + it('Should get unpaywall document in base and history', async () => { + function compare(a, b) { + if (a.doi < b.doi) return -1; + if (a.doi > b.doi) return 1; + return 0; + } + + const baseRes = await searchByDOI(['1', '2', '3', '4', '5', '6', '7'], 'unpaywall-base'); + + baseRes.sort(compare); + + expect(baseRes[0]).have.property('doi').equal('1'); + expect(baseRes[0]).have.property('version').equal(1); + expect(baseRes[0]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[0]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[1]).have.property('doi').equal('2'); + expect(baseRes[1]).have.property('version').equal(1); + expect(baseRes[1]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[1]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[2]).have.property('doi').equal('3'); + expect(baseRes[2]).have.property('version').equal(1); + expect(baseRes[2]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[2]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[3]).have.property('doi').equal('4'); + expect(baseRes[3]).have.property('version').equal(1); + expect(baseRes[3]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[3]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[4]).have.property('doi').equal('5'); + expect(baseRes[4]).have.property('version').equal(1); + expect(baseRes[4]).have.property('referencedAt').equal('2020-01-01T01:00:00.000000'); + expect(baseRes[4]).have.property('updated').equal('2020-01-01T01:00:00.000000'); + + expect(baseRes[5]).have.property('doi').equal('6'); + expect(baseRes[5]).have.property('version').equal(1); + expect(baseRes[5]).have.property('referencedAt').equal('2020-01-05T01:00:00.000000'); + expect(baseRes[5]).have.property('updated').equal('2020-01-05T01:00:00.000000'); + + expect(baseRes[6]).have.property('doi').equal('7'); + expect(baseRes[6]).have.property('version').equal(1); + expect(baseRes[6]).have.property('referencedAt').equal('2020-01-05T01:00:00.000000'); + expect(baseRes[6]).have.property('updated').equal('2020-01-05T01:00:00.000000'); + }); + }); +}); diff --git a/services/update/test/insertionError.js b/services/update/test/insertionError.js new file mode 100644 index 00000000..218f73d4 --- /dev/null +++ b/services/update/test/insertionError.js @@ -0,0 +1,99 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { countDocuments } = require('./utils/elastic'); +const { addChangefile, updateChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Test: insert the content of a file already installed on ezunpaywall', () => { + before(async function () { + this.timeout(30000); + await ping(); + await updateChangefile('week'); + }); + + describe('Do insertion of a corrupted file already installed', () => { + before(async () => { + await reset(); + await addChangefile('fake1-error.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1-error.jsonl.gz') + .send({ + index: 'unpaywall-test', + }) + .set('Access-Control-Allow-Origin', '*') + .set('Content-Type', 'application/json') + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 0 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(0); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(true); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(49); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('insert'); + expect(result.steps[0]).have.property('index').equal('unpaywall-test'); + expect(result.steps[0]).have.property('file').equal('fake1-error.jsonl.gz'); + expect(result.steps[0]).have.property('linesRead').equal(50); + expect(result.steps[0]).have.property('addedDocs').equal(49); + expect(result.steps[0]).have.property('updatedDocs').equal(0); + expect(result.steps[0]).have.property('failedDocs').equal(1); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('error'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + after(async () => { + await reset(); + }); +}); diff --git a/services/update/test/insertionFile.js b/services/update/test/insertionFile.js new file mode 100644 index 00000000..03ebf33a --- /dev/null +++ b/services/update/test/insertionFile.js @@ -0,0 +1,359 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { countDocuments } = require('./utils/elastic'); +const { addChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Test: insert the content of a file already installed on ezunpaywall', () => { + before(async function () { + this.timeout(30000); + await ping(); + }); + + describe('Do insertion of a file already installed', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 50 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + + expect(count).to.equal(50); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('insert'); + expect(result.steps[0]).have.property('index').equal('unpaywall-test'); + expect(result.steps[0]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[0]).have.property('linesRead').equal(50); + expect(result.steps[0]).have.property('addedDocs').equal(50); + expect(result.steps[0]).have.property('updatedDocs').equal(0); + expect(result.steps[0]).have.property('failedDocs').equal(0); + expect(result.steps[0]).have.property('percent').equal(100); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Do insertion of a file already installed with parameter limit=10', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + limit: 10, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 10 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(10); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(10); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('insert'); + expect(result.steps[0]).have.property('index').equal('unpaywall-test'); + expect(result.steps[0]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[0]).have.property('percent').equal(100); + expect(result.steps[0]).have.property('linesRead').equal(10); + expect(result.steps[0]).have.property('addedDocs').equal(10); + expect(result.steps[0]).have.property('updatedDocs').equal(0); + expect(result.steps[0]).have.property('failedDocs').equal(0); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Do insertion of a file already installed with parameter offset=40', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + offset: 40, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 10 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(10); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(10); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('insert'); + expect(result.steps[0]).have.property('index').equal('unpaywall-test'); + expect(result.steps[0]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[0]).have.property('percent').equal(100); + expect(result.steps[0]).have.property('linesRead').equal(50); + expect(result.steps[0]).have.property('addedDocs').equal(10); + expect(result.steps[0]).have.property('updatedDocs').equal(0); + expect(result.steps[0]).have.property('failedDocs').equal(0); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Do insertion of a file already installed with parameter offset=10 and limit=20', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + offset: 10, + limit: 20, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 10 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(10); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(10); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('insert'); + expect(result.steps[0]).have.property('index').equal('unpaywall-test'); + expect(result.steps[0]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[0]).have.property('percent').equal(100); + expect(result.steps[0]).have.property('linesRead').equal(20); + expect(result.steps[0]).have.property('addedDocs').equal(10); + expect(result.steps[0]).have.property('updatedDocs').equal(0); + expect(result.steps[0]).have.property('failedDocs').equal(0); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Don\'t do a insertion of a file already installed because the file is in the wrong format', () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe('Don\'t do a insertion of a file already installed because the File not found on ezunpaywall', () => { + it('Should return a status code 404', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(404); + }); + }); + + describe('Don\'t do a insertion of a file already installed because the parameter limit can\t be lower than offset', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/insert/changefile/fake1.jsonl.gz') + .send({ + index: 'unpaywall-test', + offset: 100, + limit: 50, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + + after(async () => { + await reset(); + }); + }); + + after(async () => { + await reset(); + }); +}); diff --git a/services/update/test/insertionPeriodDay.js b/services/update/test/insertionPeriodDay.js new file mode 100644 index 00000000..2186611e --- /dev/null +++ b/services/update/test/insertionPeriodDay.js @@ -0,0 +1,389 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { deleteChangefile, updateChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const { countDocuments, deleteIndex } = require('./utils/elastic'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +chai.use(chaiHttp); + +describe('Test: download and insert file from unpaywall between a period', () => { + const now = Date.now(); + const oneDay = (1 * 24 * 60 * 60 * 1000); + + // create date in a format (YYYY-mm-dd) to be use by ezunpaywall + // yesterday + const date1 = new Date(now - (1 * oneDay)).toISOString().slice(0, 10); + // 2 days before + const date2 = new Date(now - (2 * oneDay)).toISOString().slice(0, 10); + + // these dates are for test with dates on which no update file has been published from unpaywall + const date3 = new Date(now - (6 * oneDay)).toISOString().slice(0, 10); + const date4 = new Date(now - (7 * oneDay)).toISOString().slice(0, 10); + const tomorrow = new Date(now + (1 * oneDay)).toISOString().slice(0, 10); + + before(async function () { + this.timeout(30000); + await ping(); + await updateChangefile('day'); + }); + + describe(`Day: Do a download and insert between ${date1} and now`, async () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date1, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 150 data', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + + expect(count).to.equal(150); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(150); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('download'); + expect(result.steps[1]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + + expect(result.steps[2]).have.property('task').equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[2]).have.property('percent').equal(100); + expect(result.steps[2]).have.property('linesRead').equal(100); + expect(result.steps[2]).have.property('addedDocs').equal(100); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').equal('success'); + + expect(result.steps[3]).have.property('task').equal('download'); + expect(result.steps[3]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[3]).have.property('percent').equal(100); + expect(result.steps[3]).have.property('took').to.not.equal(undefined); + expect(result.steps[3]).have.property('status').equal('success'); + + expect(result.steps[4]).have.property('task').equal('insert'); + expect(result.steps[4]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[4]).have.property('percent').equal(100); + expect(result.steps[4]).have.property('linesRead').equal(50); + expect(result.steps[4]).have.property('addedDocs').equal(50); + expect(result.steps[4]).have.property('updatedDocs').equal(0); + expect(result.steps[4]).have.property('failedDocs').equal(0); + expect(result.steps[4]).have.property('took').to.not.equal(undefined); + expect(result.steps[4]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe(`Day: Do a download and insert between ${date2} and ${date1}`, () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date2, + endDate: date1, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 2100 data', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(2100); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(2100); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('download'); + expect(result.steps[1]).have.property('file').equal('fake3.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + + expect(result.steps[2]).have.property('task').equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').equal('fake3.jsonl.gz'); + expect(result.steps[2]).have.property('percent').equal(100); + expect(result.steps[2]).have.property('linesRead').equal(2000); + expect(result.steps[2]).have.property('addedDocs').equal(2000); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').equal('success'); + + expect(result.steps[3]).have.property('task').equal('download'); + expect(result.steps[3]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[3]).have.property('percent').equal(100); + expect(result.steps[3]).have.property('took').to.not.equal(undefined); + expect(result.steps[3]).have.property('status').equal('success'); + + expect(result.steps[4]).have.property('task').equal('insert'); + expect(result.steps[4]).have.property('index').equal('unpaywall-test'); + expect(result.steps[4]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[4]).have.property('percent').equal(100); + expect(result.steps[4]).have.property('linesRead').equal(100); + expect(result.steps[4]).have.property('addedDocs').equal(100); + expect(result.steps[4]).have.property('updatedDocs').equal(0); + expect(result.steps[4]).have.property('failedDocs').equal(0); + expect(result.steps[4]).have.property('took').to.not.equal(undefined); + expect(result.steps[4]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + after(async () => { + await reset(); + }); + }); + + describe(`Day: Don't download and insert between ${date4} and ${date3} because there is no file between these dates in ezunpaywall`, () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date4, + endDate: date3, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert nothing', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(0); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe(`Day: Don't do a download and insert with endDate=${date1} only`, () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + endDate: date1, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe('Day: Don\'t do a download and insert with startDate in the wrong format', () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .query({ index: 'unpaywall-test', startDate: 'doen\'t exist' }) + .send({ + index: 'unpaywall-test', + startDate: 'doesn\'t exist', + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: '01-01-2000', + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: '2000-50-50', + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe(`Day: Don't download and insert between ${date2} and ${date3} because startDate=${date2} is superior than endDate=${date3}`, () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date2, + endDate: date3, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe(`Day: Don't download and insert with startDate=${tomorrow} because there can be no futuristic file`, () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: tomorrow, + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + after(async () => { + await deleteIndex('unpaywall-test'); + await deleteChangefile('fake1.jsonl.gz'); + await deleteChangefile('fake2.jsonl.gz'); + await deleteChangefile('fake3.jsonl.gz'); + }); +}); diff --git a/services/update/test/insertionPeriodWeek.js b/services/update/test/insertionPeriodWeek.js new file mode 100644 index 00000000..e5117e58 --- /dev/null +++ b/services/update/test/insertionPeriodWeek.js @@ -0,0 +1,392 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { updateChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const { countDocuments } = require('./utils/elastic'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +chai.use(chaiHttp); + +describe('Week: Test: download and insert file from unpaywall between a period', () => { + const now = Date.now(); + const oneDay = (1 * 24 * 60 * 60 * 1000); + + // create date in a format (YYYY-mm-dd) to be use by ezunpaywall + // yesterday + const date1 = new Date(now - (1 * oneDay)).toISOString().slice(0, 10); + // yesterday - one week + const date2 = new Date(now - (8 * oneDay)).toISOString().slice(0, 10); + // yesterday - two weeks + const date3 = new Date(now - (15 * oneDay)).toISOString().slice(0, 10); + // these dates are for test between a short period + const date4 = new Date(now - (4 * oneDay)).toISOString().slice(0, 10); + const date5 = new Date(now - (5 * oneDay)).toISOString().slice(0, 10); + const tomorrow = new Date(now + (1 * oneDay)).toISOString().slice(0, 10); + + before(async function () { + this.timeout(30000); + await ping(); + await updateChangefile('week'); + }); + + describe(`Week: Do a download and insert between ${date2} and now`, async () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date2, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 150 data', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(150); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(150); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('download'); + expect(result.steps[1]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + + expect(result.steps[2]).have.property('task').equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[2]).have.property('percent').equal(100); + expect(result.steps[2]).have.property('linesRead').equal(100); + expect(result.steps[2]).have.property('addedDocs').equal(100); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').equal('success'); + + expect(result.steps[3]).have.property('task').equal('download'); + expect(result.steps[3]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[3]).have.property('percent').equal(100); + expect(result.steps[3]).have.property('took').to.not.equal(undefined); + expect(result.steps[3]).have.property('status').equal('success'); + + expect(result.steps[4]).have.property('task').equal('insert'); + expect(result.steps[4]).have.property('index').equal('unpaywall-test'); + expect(result.steps[4]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[4]).have.property('percent').equal(100); + expect(result.steps[4]).have.property('linesRead').equal(50); + expect(result.steps[4]).have.property('addedDocs').equal(50); + expect(result.steps[4]).have.property('updatedDocs').equal(0); + expect(result.steps[4]).have.property('failedDocs').equal(0); + expect(result.steps[4]).have.property('took').to.not.equal(undefined); + expect(result.steps[4]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe(`Week: Do a download and insert between ${date3} and ${date2}`, () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date3, + endDate: date2, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 2100 data', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(2100); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(2100); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('download'); + expect(result.steps[1]).have.property('file').equal('fake3.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + + expect(result.steps[2]).have.property('task').equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').equal('fake3.jsonl.gz'); + expect(result.steps[2]).have.property('percent').equal(100); + expect(result.steps[2]).have.property('linesRead').equal(2000); + expect(result.steps[2]).have.property('addedDocs').equal(2000); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').equal('success'); + + expect(result.steps[3]).have.property('task').equal('download'); + expect(result.steps[3]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[3]).have.property('percent').equal(100); + expect(result.steps[3]).have.property('took').to.not.equal(undefined); + expect(result.steps[3]).have.property('status').equal('success'); + + expect(result.steps[4]).have.property('task').equal('insert'); + expect(result.steps[4]).have.property('index').equal('unpaywall-test'); + expect(result.steps[4]).have.property('file').equal('fake2.jsonl.gz'); + expect(result.steps[4]).have.property('percent').equal(100); + expect(result.steps[4]).have.property('linesRead').equal(100); + expect(result.steps[4]).have.property('addedDocs').equal(100); + expect(result.steps[4]).have.property('updatedDocs').equal(0); + expect(result.steps[4]).have.property('failedDocs').equal(0); + expect(result.steps[4]).have.property('took').to.not.equal(undefined); + expect(result.steps[4]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe(`Week: Don't download and insert between ${date5} and ${date4} because there is no file between these dates in ezunpaywall`, () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date5, + endDate: date4, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert nothing', async () => { + // wait for the update to finish + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(0); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + } + + it('Should get state with all information from the download and insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the download and insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe(`Week: Don't do a download and insert with endDate=${date1} only`, () => { + it('Should return status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: + 'unpaywall-test', + endDate: date1, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe('Week: Don\'t do a download and insert with startDate in the wrong format', () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .query({ + index: 'unpaywall-test', + startDate: 'doen\'t exist', + interval: 'week', + }) + .send({ + index: 'unpaywall-test', + startDate: 'doen\'t exist', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: '01-01-2000', + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: '2000-50-50', + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe(`Week: Don't download and insert between ${date2} and ${date3} because startDate=${date2} is superior than endDate=${date3}`, () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: date2, + endDate: date3, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + describe(`Week: Don't download and insert with startDate=${tomorrow} because there can be no futuristic file`, () => { + it('Should return a status code 400', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + startDate: tomorrow, + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(400); + }); + }); + + after(async () => { + await reset(); + }); +}); diff --git a/services/update/test/insertionSnapshot.js b/services/update/test/insertionSnapshot.js new file mode 100644 index 00000000..142d284a --- /dev/null +++ b/services/update/test/insertionSnapshot.js @@ -0,0 +1,98 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); +const { format } = require('date-fns'); + +const { countDocuments } = require('./utils/elastic'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Test: download and insert snapshot from unpaywall', () => { + before(async function () { + this.timeout(30000); + await ping(); + }); + + describe('Do a download and a insertion of snapshot', () => { + before(async () => { + await reset(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/snapshot') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 2150 data', async () => { + // wait for the update to finish + let isUpdate = true; + do { + isUpdate = await checkIfInUpdate(); + await new Promise((resolve) => { setTimeout(resolve, 100); }); + } while (isUpdate); + + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(2150); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(2150); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('download'); + expect(result.steps[0]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + expect(result.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); + + expect(result.steps[1]).have.property('task').equal('insert'); + expect(result.steps[1]).have.property('index').equal('unpaywall-test'); + expect(result.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('linesRead').equal(2150); + expect(result.steps[1]).have.property('addedDocs').equal(2150); + expect(result.steps[1]).have.property('updatedDocs').equal(0); + expect(result.steps[1]).have.property('failedDocs').equal(0); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + } + + it('Should get state with all information from the insertion', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the insertion', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); +}); diff --git a/services/update/test/rollback.js b/services/update/test/rollback.js new file mode 100644 index 00000000..8ff888fa --- /dev/null +++ b/services/update/test/rollback.js @@ -0,0 +1,201 @@ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const unpaywallEnrichedMapping = require('../mapping/unpaywall.json'); +const unpaywallHistoryMapping = require('../mapping/unpaywall-history.json'); + +const { + countDocuments, + insertHistoryDataUnpaywall, + deleteIndex, + getAllData, + createIndex, +} = require('./utils/elastic'); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +chai.use(chaiHttp); + +describe('Test: rollback history test', () => { + const date1 = '2020-01-04T01:00:00.000'; + const date2 = '2020-01-03T01:00:00.000'; + const date3 = '2020-01-02T01:00:00.000'; + const date4 = '2020-01-01T01:00:00.000'; + + describe(`Rollback: history rollback at ${date1}`, () => { + before(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + await createIndex('unpaywall-base', unpaywallEnrichedMapping); + await createIndex('unpaywall-history', unpaywallHistoryMapping); + await insertHistoryDataUnpaywall(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date1, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get state with all information', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date1, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get report with all information', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date1, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get unpaywall data', async () => { + const count1 = await countDocuments('unpaywall-base'); + expect(count1).to.equal(2); + + const count2 = await countDocuments('unpaywall-history'); + expect(count2).to.equal(4); + + const data = await getAllData('unpaywall-base'); + + data.forEach((e) => { + expect(e.genre).to.equal('v3'); + }); + }); + + after(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + }); + }); + + describe(`Rollback: history rollback at ${date2}`, () => { + before(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + await createIndex('unpaywall-base', unpaywallEnrichedMapping); + await createIndex('unpaywall-history', unpaywallHistoryMapping); + await insertHistoryDataUnpaywall(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date2, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get unpaywall data', async () => { + const count1 = await countDocuments('unpaywall-base'); + expect(count1).to.equal(2); + + const count2 = await countDocuments('unpaywall-history'); + expect(count2).to.equal(2); + + const data = await getAllData('unpaywall-base'); + + data.forEach((e) => { + expect(e.genre).to.equal('v2'); + }); + }); + + after(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + }); + }); + + describe(`Rollback: history rollback at ${date3}`, () => { + before(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + await createIndex('unpaywall-base', unpaywallEnrichedMapping); + await createIndex('unpaywall-history', unpaywallHistoryMapping); + await insertHistoryDataUnpaywall(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date3, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get unpaywall data', async () => { + const count1 = await countDocuments('unpaywall-base'); + expect(count1).to.equal(2); + + const count2 = await countDocuments('unpaywall-history'); + expect(count2).to.equal(0); + + const data = await getAllData('unpaywall-base'); + + data.forEach((e) => { + expect(e.genre).to.equal('v1'); + }); + }); + + after(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + }); + }); + + describe(`Rollback: history rollback at ${date4}`, () => { + before(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + await createIndex('unpaywall-base', unpaywallEnrichedMapping); + await createIndex('unpaywall-history', unpaywallHistoryMapping); + await insertHistoryDataUnpaywall(); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/history/period/reset') + .send({ + startDate: date4, + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should get unpaywall data', async () => { + const count1 = await countDocuments('unpaywall-base'); + expect(count1).to.equal(0); + + const count2 = await countDocuments('unpaywall-history'); + expect(count2).to.equal(0); + }); + + after(async () => { + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + }); + }); +}); diff --git a/services/update/test/sources/changefiles/2019-01-02-history.jsonl.gz b/services/update/test/sources/changefiles/2019-01-02-history.jsonl.gz new file mode 100644 index 00000000..289d6452 Binary files /dev/null and b/services/update/test/sources/changefiles/2019-01-02-history.jsonl.gz differ diff --git a/services/update/test/sources/changefiles/2020-01-02-history.jsonl.gz b/services/update/test/sources/changefiles/2020-01-02-history.jsonl.gz new file mode 100644 index 00000000..a4b457b9 Binary files /dev/null and b/services/update/test/sources/changefiles/2020-01-02-history.jsonl.gz differ diff --git a/services/update/test/sources/changefiles/2020-01-03-history.jsonl.gz b/services/update/test/sources/changefiles/2020-01-03-history.jsonl.gz new file mode 100644 index 00000000..abc75879 Binary files /dev/null and b/services/update/test/sources/changefiles/2020-01-03-history.jsonl.gz differ diff --git a/services/update/test/sources/changefiles/2020-01-04-history.jsonl.gz b/services/update/test/sources/changefiles/2020-01-04-history.jsonl.gz new file mode 100644 index 00000000..3aea9a3c Binary files /dev/null and b/services/update/test/sources/changefiles/2020-01-04-history.jsonl.gz differ diff --git a/src/update/test/sources/fake1-error.jsonl.gz b/services/update/test/sources/changefiles/fake1-error.jsonl.gz similarity index 100% rename from src/update/test/sources/fake1-error.jsonl.gz rename to services/update/test/sources/changefiles/fake1-error.jsonl.gz diff --git a/src/fakeUnpaywall/snapshots/fake1.jsonl.gz b/services/update/test/sources/changefiles/fake1.jsonl.gz similarity index 100% rename from src/fakeUnpaywall/snapshots/fake1.jsonl.gz rename to services/update/test/sources/changefiles/fake1.jsonl.gz diff --git a/src/update/test/sources/fake2.jsonl.gz b/services/update/test/sources/changefiles/fake2.jsonl.gz similarity index 100% rename from src/update/test/sources/fake2.jsonl.gz rename to services/update/test/sources/changefiles/fake2.jsonl.gz diff --git a/src/fakeUnpaywall/snapshots/fake3.jsonl.gz b/services/update/test/sources/changefiles/fake3.jsonl.gz similarity index 100% rename from src/fakeUnpaywall/snapshots/fake3.jsonl.gz rename to services/update/test/sources/changefiles/fake3.jsonl.gz diff --git a/services/update/test/sources/snapshots/2019-01-01-snapshot.jsonl.gz b/services/update/test/sources/snapshots/2019-01-01-snapshot.jsonl.gz new file mode 100644 index 00000000..038d727d Binary files /dev/null and b/services/update/test/sources/snapshots/2019-01-01-snapshot.jsonl.gz differ diff --git a/services/update/test/sources/snapshots/2020-01-01-snapshot.jsonl.gz b/services/update/test/sources/snapshots/2020-01-01-snapshot.jsonl.gz new file mode 100644 index 00000000..f0792233 Binary files /dev/null and b/services/update/test/sources/snapshots/2020-01-01-snapshot.jsonl.gz differ diff --git a/services/update/test/sources/unpaywall-history.jsonl b/services/update/test/sources/unpaywall-history.jsonl new file mode 100644 index 00000000..130669f0 --- /dev/null +++ b/services/update/test/sources/unpaywall-history.jsonl @@ -0,0 +1,4 @@ +{"doi":"10.000/00.00.01","year":2000,"genre":"v1","is_oa":false,"title":"Title","doi_url":"https://doi.org/10.000/00.00.01","updated":"2020-01-01T12:00:00.000000","oa_status":"gold","publisher":"Publisher","z_authors":[{"given":"John","family":"Doe","sequence":"first"}],"is_paratext":false,"journal_name":"Journal Name","oa_locations":[{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"0000-0001","journal_issn_l":"0000-0001","published_date":"2000-01-01","best_oa_location":{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true,"referencedAt":"2020-01-01","date":"2020-01-02","endValidity":"2020-01-02T12:00:00.000000"} +{"doi":"10.000/00.00.00","year":2000,"genre":"v1","is_oa":true,"title":"Title","doi_url":"https://doi.org/10.000/00.00.00","updated":"2020-01-01T12:00:00.000000","oa_status":"gold","publisher":"Publisher","z_authors":[{"given":"John","family":"Doe","sequence":"first"}],"is_paratext":false,"journal_name":"Journal Name","oa_locations":[{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"0000-0001","journal_issn_l":"0000-0001","published_date":"2000-01-01","best_oa_location":{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true,"referencedAt":"2020-01-01","date":"2020-01-02","endValidity":"2020-01-02T12:00:00.000000"} +{"doi":"10.000/00.00.00","year":2000,"genre":"v2","is_oa":false,"title":"Title","doi_url":"https://doi.org/10.000/00.00.00","updated":"2020-01-02T12:00:00.000000","oa_status":"gold","publisher":"Publisher","z_authors":[{"given":"John","family":"Doe","sequence":"first"}],"is_paratext":false,"journal_name":"Journal Name","oa_locations":[{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"0000-0001","journal_issn_l":"0000-0001","published_date":"2000-01-01","best_oa_location":{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.000/00.00.00","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.00","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true,"referencedAt":"2020-01-01","date":"2020-01-03","endValidity":"2020-01-03T12:00:00.000000"} +{"doi":"10.000/00.00.01","year":2000,"genre":"v2","is_oa":true,"title":"Title","doi_url":"https://doi.org/10.000/00.00.01","updated":"2020-01-02T12:00:00.000000","oa_status":"gold","publisher":"Publisher","z_authors":[{"given":"John","family":"Doe","sequence":"first"}],"is_paratext":false,"journal_name":"Journal Name","oa_locations":[{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"0000-0001","journal_issn_l":"0000-0001","published_date":"2000-01-01","best_oa_location":{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.000/00.00.01","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-01-01","updated":"2020-01-01T12:00:00.000000","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.000/00.00.01","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true,"referencedAt":"2020-01-01","date":"2020-01-03","endValidity":"2020-01-03T12:00:00.000000"} diff --git a/services/update/test/sources/unpaywall.jsonl b/services/update/test/sources/unpaywall.jsonl new file mode 100644 index 00000000..65d07a90 --- /dev/null +++ b/services/update/test/sources/unpaywall.jsonl @@ -0,0 +1,2 @@ +{"doi": "10.000/00.00.00","year": 2000,"genre": "v3","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.00","updated": "2020-01-03T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.00","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.00","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} +{"doi": "10.000/00.00.01","year": 2000,"genre": "v3","is_oa": true,"title": "Title","doi_url": "https://doi.org/10.000/00.00.01","updated": "2020-01-03T12:00:00.000000","oa_status": "gold","publisher": "Publisher","z_authors": [{"given": "John","family": "Doe","sequence": "first"}],"is_paratext": false,"journal_name": "Journal Name","oa_locations": [{"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null}],"data_standard": 2,"journal_is_oa": true,"journal_issns": "0000-0001","journal_issn_l": "0000-0001","published_date": "2000-01-01","best_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"first_oa_location": {"url": "https://doi.org/10.000/00.00.01","pmh_id": null,"is_best": true,"license": "cc-by","oa_date": "2010-01-01","updated": "2020-01-01T12:00:00.000000","version": "publishedVersion","evidence": "oa journal (via doaj)","host_type": "publisher","endpoint_id": null,"url_for_pdf": null,"url_for_landing_page": "https://doi.org/10.000/00.00.01","repository_institution": null},"journal_is_in_doaj": true,"has_repository_copy": true} \ No newline at end of file diff --git a/services/update/test/updateDay.js b/services/update/test/updateDay.js new file mode 100644 index 00000000..8e25ad21 --- /dev/null +++ b/services/update/test/updateDay.js @@ -0,0 +1,317 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { countDocuments } = require('./utils/elastic'); +const { addChangefile, updateChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Test: daily update route test', () => { + before(async function () { + this.timeout(30000); + await ping(); + await updateChangefile('day'); + }); + + describe('Day: Do daily update', () => { + before(async () => { + await reset(); + }); + + // test response + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').be.equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').be.equal('success'); + + expect(result.steps[1]).have.property('task').be.equal('download'); + expect(result.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').be.equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').be.equal('success'); + + expect(result.steps[2]).have.property('task').be.equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[2]).have.property('percent').be.equal(100); + expect(result.steps[2]).have.property('linesRead').be.equal(50); + expect(result.steps[2]).have.property('addedDocs').equal(50); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').be.equal('success'); + } + + it('Should get state with all information from the daily update', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the daily update', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Day: daily update 2 times', () => { + before(async () => { + await reset(); + }); + + // test response + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult1(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').be.equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').be.equal('success'); + + expect(result.steps[1]).have.property('task').be.equal('download'); + expect(result.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').be.equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').be.equal('success'); + + expect(result.steps[2]).have.property('task').be.equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[2]).have.property('percent').be.equal(100); + expect(result.steps[2]).have.property('linesRead').be.equal(50); + expect(result.steps[2]).have.property('addedDocs').equal(50); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').be.equal('success'); + } + + it('Should get state with all information from the weekly update', async () => { + const state = await getState(); + testResult1(state); + }); + + it('Should get report with all information from the weekly update', async () => { + const report = await getReport('dataUpdate'); + testResult1(report); + }); + + // test response + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult2(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(0); + expect(indices[0]).have.property('updated').equal(50); + + expect(result.steps[0]).have.property('task').be.equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').be.equal('success'); + + expect(result.steps[1]).have.property('task').be.equal('insert'); + expect(result.steps[1]).have.property('index').equal('unpaywall-test'); + expect(result.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').be.equal(100); + expect(result.steps[1]).have.property('linesRead').be.equal(50); + expect(result.steps[1]).have.property('addedDocs').equal(0); + expect(result.steps[1]).have.property('updatedDocs').equal(50); + expect(result.steps[1]).have.property('failedDocs').equal(0); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').be.equal('success'); + } + + it('Should get state with all information from the weekly update', async () => { + const state = await getState(); + testResult2(state); + }); + + it('Should get report with all information from the weekly update', async () => { + const report = await getReport('dataUpdate'); + testResult2(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Day: Do a daily update but the file is already installed', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + interval: 'day', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('insert'); + expect(result.steps[1]).have.property('index').equal('unpaywall-test'); + expect(result.steps[1]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('linesRead').equal(50); + expect(result.steps[1]).have.property('addedDocs').equal(50); + expect(result.steps[1]).have.property('updatedDocs').equal(0); + expect(result.steps[1]).have.property('failedDocs').equal(0); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + } + + it('Should get state with all information from the daily update', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the daily update', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + after(async () => { + await reset(); + }); +}); diff --git a/services/update/test/updateWeek.js b/services/update/test/updateWeek.js new file mode 100644 index 00000000..164abd61 --- /dev/null +++ b/services/update/test/updateWeek.js @@ -0,0 +1,179 @@ +/* eslint-disable no-await-in-loop */ +const { expect } = require('chai'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +const { countDocuments } = require('./utils/elastic'); +const { addChangefile, updateChangefile } = require('./utils/changefile'); +const { getState } = require('./utils/state'); +const getReport = require('./utils/report'); +const checkIfInUpdate = require('./utils/status'); + +const ping = require('./utils/ping'); +const reset = require('./utils/reset'); + +chai.use(chaiHttp); + +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; + +describe('Week: Test: weekly update route test', () => { + before(async function () { + this.timeout(30000); + await ping(); + await updateChangefile('week'); + }); + + describe('Do weekly update', () => { + before(async () => { + await reset(); + }); + + // test response + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('Should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult(result) { + expect(result).have.property('done'); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').be.equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').be.equal('success'); + + expect(result.steps[1]).have.property('task').be.equal('download'); + expect(result.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').be.equal(100); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').be.equal('success'); + + expect(result.steps[2]).have.property('task').be.equal('insert'); + expect(result.steps[2]).have.property('index').equal('unpaywall-test'); + expect(result.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); + expect(result.steps[2]).have.property('percent').be.equal(100); + expect(result.steps[2]).have.property('linesRead').be.equal(50); + expect(result.steps[2]).have.property('addedDocs').equal(50); + expect(result.steps[2]).have.property('updatedDocs').equal(0); + expect(result.steps[2]).have.property('failedDocs').equal(0); + expect(result.steps[2]).have.property('took').to.not.equal(undefined); + expect(result.steps[2]).have.property('status').be.equal('success'); + } + + it('Should get state with all information from the weekly update', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the weekly update', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + describe('Week: Do a weekly update but the file is already installed', () => { + before(async () => { + await reset(); + await addChangefile('fake1.jsonl.gz'); + }); + + it('Should return a status code 202', async () => { + const res = await chai.request(updateURL) + .post('/job/download/insert/changefile/period') + .send({ + index: 'unpaywall-test', + interval: 'week', + }) + .set('x-api-key', 'changeme'); + + expect(res).have.status(202); + }); + + it('should insert 50 data', async () => { + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } + const count = await countDocuments('unpaywall-test'); + expect(count).to.equal(50); + }); + + function testResult(result) { + expect(result).have.property('done').equal(true); + expect(result).have.property('steps').to.be.an('array'); + expect(result).have.property('createdAt').to.not.equal(undefined); + expect(result).have.property('endAt').to.not.equal(undefined); + expect(result).have.property('error').equal(false); + expect(result).have.property('took').to.not.equal(undefined); + + const { indices } = result; + expect(indices[0]).have.property('index').equal('unpaywall-test'); + expect(indices[0]).have.property('added').equal(50); + expect(indices[0]).have.property('updated').equal(0); + + expect(result.steps[0]).have.property('task').equal('getChangefiles'); + expect(result.steps[0]).have.property('took').to.not.equal(undefined); + expect(result.steps[0]).have.property('status').equal('success'); + + expect(result.steps[1]).have.property('task').equal('insert'); + expect(result.steps[1]).have.property('index').equal('unpaywall-test'); + expect(result.steps[1]).have.property('file').equal('fake1.jsonl.gz'); + expect(result.steps[1]).have.property('percent').equal(100); + expect(result.steps[1]).have.property('linesRead').equal(50); + expect(result.steps[1]).have.property('addedDocs').equal(50); + expect(result.steps[1]).have.property('updatedDocs').equal(0); + expect(result.steps[1]).have.property('failedDocs').equal(0); + expect(result.steps[1]).have.property('took').to.not.equal(undefined); + expect(result.steps[1]).have.property('status').equal('success'); + } + + it('Should get state with all information from the weekly update', async () => { + const state = await getState(); + testResult(state); + }); + + it('Should get report with all information from the weekly update', async () => { + const report = await getReport('dataUpdate'); + testResult(report); + }); + + after(async () => { + await reset(); + }); + }); + + after(async () => { + await reset(); + }); +}); diff --git a/services/update/test/utils/changefile.js b/services/update/test/utils/changefile.js new file mode 100644 index 00000000..3e202b37 --- /dev/null +++ b/services/update/test/utils/changefile.js @@ -0,0 +1,128 @@ +const chai = require('chai'); +const chaiHttp = require('chai-http'); +const path = require('path'); + +chai.use(chaiHttp); + +const checkIfInUpdate = require('./status'); + +const changefilesDir = path.resolve(__dirname, '..', 'sources', 'changefiles'); + +// TODO put it in config +const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; +const fakeUnpaywall = process.env.FAKEUNPAYWALL_URL || 'http://localhost:59799'; + +/** + * Delete a snapshot in ezunpaywall. + * + * @param {Promise} filename - Name of file needed to be delete on ezunpaywall. + */ +async function deleteChangefile(filename) { + try { + await chai.request(updateURL) + .delete(`/changefiles/${filename}`) + .set('x-api-key', 'changeme'); + } catch (err) { + console.error(`Cannot DELETE ${updateURL}/snapshot/${filename}`); + process.exit(1); + } +} + +/** + * Add a snapshot in ezunpaywall. + * + * @param {string} filename - Filename needed to be add on ezunpaywall. + * + * @returns {Promise} + */ +async function addChangefile(filename) { + try { + await chai.request(updateURL) + .post('/changefiles') + .attach('file', path.resolve(changefilesDir, filename), filename) + .set('x-api-key', 'changeme'); + } catch (err) { + console.error(`Cannot POST ${updateURL}/snapshot ${err}`); + process.exit(1); + } +} + +/** + * Update the registry of changefiles of fakeUnpaywall. + * + * @param {string} interval - Interval of registry. + * + * @returns {Promise} + */ +async function updateChangefile(interval) { + try { + await chai.request(fakeUnpaywall) + .patch('/changefiles') + .query({ interval }); + } catch (err) { + console.error(`Cannot PATCH ${updateURL}/changefiles ${err}`); + process.exit(1); + } +} + +/** + * insert file in ezunpaywall. + * + * @param {string} filename - Filename needed to be insert on ezunpaywall. + * + * @returns {Promise} + */ +async function insertChangefile(filename, index) { + try { + await chai.request(updateURL) + .post(`/job/insert/changefile/${filename}`) + .send({ + index, + }) + .set('x-api-key', 'changeme'); + } catch (err) { + console.error(`Cannot POST ${updateURL}/snapshot ${err}`); + process.exit(1); + } + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } +} + +/** + * insert file in ezunpaywall. + * + * @param {string} filename - Filename needed to be insert on ezunpaywall. + * + * @returns {Promise} + */ +async function insertInHistory(startDate, endDate) { + try { + await chai.request(updateURL) + .post('/job/download/insert/history/period') + .send({ + indexBase: 'unpaywall-base', + startDate, + endDate, + }) + .set('x-api-key', 'changeme'); + } catch (err) { + console.error(`Cannot POST ${updateURL}/snapshot ${err}`); + process.exit(1); + } + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } +} + +module.exports = { + addChangefile, + deleteChangefile, + updateChangefile, + insertChangefile, + insertInHistory, +}; diff --git a/src/update/test/utils/cron.js b/services/update/test/utils/cron.js similarity index 50% rename from src/update/test/utils/cron.js rename to services/update/test/utils/cron.js index b4fa06d3..8244bad5 100644 --- a/src/update/test/utils/cron.js +++ b/services/update/test/utils/cron.js @@ -10,11 +10,29 @@ chai.use(chaiHttp); * * @returns {Promise} */ -async function resetCronConfig() { +async function resetCronConfig(type) { + let config; + if (type === 'dataUpdate') { + config = { + schedule: '0 0 0 * * *', + index: 'unpaywall', + interval: 'day', + }; + } + + if (type === 'dataUpdateHistory') { + config = { + schedule: '0 0 0 * * *', + indexBase: 'unpaywall-base', + indexHistory: 'unpaywall-history', + interval: 'day', + }; + } + try { await chai.request(updateURL) - .patch('/cron') - .send({ time: '0 0 0 * * *', index: 'unpaywall', interval: 'day' }) + .patch(`/cron/${type}`) + .send(config) .set('x-api-key', 'changeme'); } catch (err) { console.error(`Cannot PATCH ${updateURL}/cron`); diff --git a/src/update/test/utils/elastic.js b/services/update/test/utils/elastic.js similarity index 54% rename from src/update/test/utils/elastic.js rename to services/update/test/utils/elastic.js index c22f9aca..ac74cac1 100644 --- a/src/update/test/utils/elastic.js +++ b/services/update/test/utils/elastic.js @@ -49,6 +49,62 @@ async function insertDataUnpaywall() { } } +async function insertHistoryDataUnpaywall() { + const filepath1 = path.resolve(__dirname, '..', 'sources', 'unpaywall-history.jsonl'); + let readStream1; + try { + readStream1 = await fs.createReadStream(filepath1); + } catch (err) { + console.error(`fs.createReadStream in insertDataUnpaywall: ${err}`); + } + + const rl1 = readline.createInterface({ + input: readStream1, + crlfDelay: Infinity, + }); + + const data1 = []; + + for await (const line of rl1) { + data1.push(JSON.parse(line)); + } + + const body1 = data1.flatMap((doc) => [{ index: { _index: 'unpaywall-history' } }, doc]); + + try { + await elasticClient.bulk({ refresh: true, body: body1 }); + } catch (err) { + console.error(err); + } + + const filepath2 = path.resolve(__dirname, '..', 'sources', 'unpaywall.jsonl'); + let readStream2; + try { + readStream2 = await fs.createReadStream(filepath2); + } catch (err) { + console.error(`fs.createReadStream in insertDataUnpaywall: ${err}`); + } + + const rl2 = readline.createInterface({ + input: readStream2, + crlfDelay: Infinity, + }); + + const data2 = []; + + for await (const line of rl2) { + data2.push(JSON.parse(line)); + } + + const body2 = data2.flatMap((doc) => [{ index: { _index: 'unpaywall-base', _id: doc.doi } }, doc]); + + try { + await elasticClient.bulk({ refresh: true, body: body2 }); + } catch (err) { + console.error(err); + } +} + /** * Check if index exit. * @@ -132,11 +188,65 @@ async function countDocuments(name) { return data?.body?.count ? data?.body?.count : 0; } +async function getAllData(index) { + let res; + try { + res = await elasticClient.search({ + index, + body: { + query: { + match_all: { }, + }, + }, + + }); + } catch (err) { + console.error('[elastic]: Cannot request elastic', err); + return null; + } + // eslint-disable-next-line no-underscore-dangle + return res.body.hits.hits.map((hit) => hit._source); +} + +async function searchByDOI(dois, index) { + if (!dois) { return []; } + // Normalize request + const normalizeDOI = dois.map((doi) => doi.toLowerCase()); + + const filter = [{ terms: { doi: normalizeDOI } }]; + + const query = { + bool: { + filter, + }, + }; + + let res; + try { + res = await elasticClient.search({ + index, + size: 1000, + body: { + query, + }, + + }); + } catch (err) { + console.error('[elastic]: Cannot search documents with DOI as ID', err); + return []; + } + // eslint-disable-next-line no-underscore-dangle + return res.body.hits.hits.map((hit) => hit._source); +} + module.exports = { elasticClient, createIndex, deleteIndex, checkIfIndexExist, insertDataUnpaywall, + insertHistoryDataUnpaywall, countDocuments, + getAllData, + searchByDOI, }; diff --git a/src/update/test/utils/ping.js b/services/update/test/utils/ping.js similarity index 94% rename from src/update/test/utils/ping.js rename to services/update/test/utils/ping.js index 539233e7..81ac5a29 100644 --- a/src/update/test/utils/ping.js +++ b/services/update/test/utils/ping.js @@ -27,7 +27,7 @@ async function ping() { const elastic = await chai.request(elasticHost).get('/'); if (elastic?.status !== 200) { - throw new Error(`[elastic] Bad status : ${elastic?.status}`); + throw new Error(`[elastic]: Bad status : ${elastic?.status}`); } const apikey = await chai.request(apikeyHost).get('/ping'); diff --git a/src/update/test/utils/report.js b/services/update/test/utils/report.js similarity index 74% rename from src/update/test/utils/report.js rename to services/update/test/utils/report.js index a06cdd51..d2e29468 100644 --- a/src/update/test/utils/report.js +++ b/services/update/test/utils/report.js @@ -11,19 +11,16 @@ const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; * * @returns {Promise{Object}} report */ -async function getReport() { +async function getReport(type) { let res; try { res = await chai.request(updateURL) - .get('/reports') + .get(`/reports?type=${type}`) .query({ latest: true }); } catch (err) { - console.error(`Cannot GET ${updateURL}/report`); process.exit(1); } return res?.body; } -module.exports = { - getReport, -}; +module.exports = getReport; diff --git a/services/update/test/utils/reset.js b/services/update/test/utils/reset.js new file mode 100644 index 00000000..898f8c46 --- /dev/null +++ b/services/update/test/utils/reset.js @@ -0,0 +1,38 @@ +const { + deleteSnapshot, +} = require('./snapshot'); + +const { + deleteChangefile, +} = require('./changefile'); + +const { + deleteIndex, +} = require('./elastic'); + +const resetCronConfig = require('./cron'); + +/** + * Reset ezunpaywall + * + * @returns {Promise} + */ +async function reset() { + await deleteChangefile('2020-01-02-history.jsonl.gz'); + await deleteChangefile('2020-01-03-history.jsonl.gz'); + await deleteChangefile('2020-01-05-history.jsonl.gz'); + await deleteChangefile('fake1.jsonl.gz'); + await deleteChangefile('fake2.jsonl.gz'); + await deleteChangefile('fake3.jsonl.gz'); + await deleteChangefile('fake1-error.jsonl.gz'); + await deleteSnapshot('2019-01-01-snapshot.jsonl.gz'); + await deleteSnapshot('2020-01-01-snapshot.jsonl.gz'); + await deleteIndex('unpaywall'); + await deleteIndex('unpaywall-test'); + await deleteIndex('unpaywall-base'); + await deleteIndex('unpaywall-history'); + await resetCronConfig('dataUpdate'); + await resetCronConfig('dataUpdateHistory'); +} + +module.exports = reset; diff --git a/services/update/test/utils/server.js b/services/update/test/utils/server.js new file mode 100644 index 00000000..05ae932e --- /dev/null +++ b/services/update/test/utils/server.js @@ -0,0 +1,14 @@ +const axios = require('axios'); + +const updateService = axios.create({ + timeout: 3000, + proxy: false, + baseURL: 'http://localhost:3000/', + maxContentLength: Infinity, + maxBodyLength: Infinity, + validateStatus: (status) => status < 500, +}); + +updateService.baseURL = 'http://localhost:3000/'; + +module.exports = updateService; diff --git a/src/update/test/utils/snapshot.js b/services/update/test/utils/snapshot.js similarity index 62% rename from src/update/test/utils/snapshot.js rename to services/update/test/utils/snapshot.js index 09f89719..d5118eb9 100644 --- a/src/update/test/utils/snapshot.js +++ b/services/update/test/utils/snapshot.js @@ -4,18 +4,19 @@ const path = require('path'); chai.use(chaiHttp); -const snapshotsDir = path.resolve(__dirname, '..', 'sources'); +const checkIfInUpdate = require('./status'); + +const snapshotsDir = path.resolve(__dirname, '..', 'sources', 'snapshots'); // TODO put it in config const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; -const fakeUnpaywall = process.env.FAKEUNPAYWALL_URL || 'http://localhost:59799'; /** * Delete a snapshot in ezunpaywall. * * @param {Promise} filename - Name of file needed to be delete on ezunpaywall. */ -async function deleteFile(filename) { +async function deleteSnapshot(filename) { try { await chai.request(updateURL) .delete(`/snapshots/${filename}`) @@ -46,25 +47,33 @@ async function addSnapshot(filename) { } /** - * Update the registry of changefiles of fakeUnpaywall. + * insert file in ezunpaywall. * - * @param {string} interval - Interval of registry. + * @param {string} filename - Filename needed to be insert on ezunpaywall. * * @returns {Promise} */ -async function updateChangeFile(interval) { +async function insertSnapshot(filename, index) { try { - await chai.request(fakeUnpaywall) - .patch('/changefiles') - .query({ interval }); + await chai.request(updateURL) + .post(`/job/insert/snapshot/${filename}`) + .send({ + index, + }) + .set('x-api-key', 'changeme'); } catch (err) { - console.error(`Cannot PATCH ${updateURL}/changefiles ${err}`); + console.error(`Cannot POST ${updateURL}/snapshot ${err}`); process.exit(1); } + let isUpdate = true; + while (isUpdate) { + await new Promise((resolve) => { setTimeout(resolve, 100); }); + isUpdate = await checkIfInUpdate(); + } } module.exports = { addSnapshot, - deleteFile, - updateChangeFile, + deleteSnapshot, + insertSnapshot, }; diff --git a/src/update/test/utils/state.js b/services/update/test/utils/state.js similarity index 100% rename from src/update/test/utils/state.js rename to services/update/test/utils/state.js diff --git a/src/update/test/utils/status.js b/services/update/test/utils/status.js similarity index 100% rename from src/update/test/utils/status.js rename to services/update/test/utils/status.js diff --git a/src/apikey/.gitignore b/src/apikey/.gitignore deleted file mode 100644 index 0c54eff5..00000000 --- a/src/apikey/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -data/ -node_modules/ \ No newline at end of file diff --git a/src/apikey/Dockerfile b/src/apikey/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/apikey/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/apikey/README.md b/src/apikey/README.md deleted file mode 100644 index a18c3e9b..00000000 --- a/src/apikey/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# ezunpaywall-apikey - -API key management service for update, graphql and enrich service. - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| NODE_ENV | development | environment of node | -| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | -| REDIS_HOST | redis | redis host | -| REDIS_PORT | 6379 | redis port | -| REDIS_PASSWORD | changeme | redis password | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | \ No newline at end of file diff --git a/src/apikey/app.js b/src/apikey/app.js deleted file mode 100644 index 99db8b87..00000000 --- a/src/apikey/app.js +++ /dev/null @@ -1,48 +0,0 @@ -const express = require('express'); -const cors = require('cors'); -const fs = require('fs-extra'); -const path = require('path'); - -const logger = require('./lib/logger'); -const morgan = require('./lib/morgan'); -const getConfig = require('./lib/config'); - -const { pingRedis, startConnectionRedis, loadDemoAPIKey } = require('./lib/services/redis'); - -const cronDemo = require('./lib/cron'); - -const routerPing = require('./lib/routers/ping'); -const routerAdmin = require('./lib/routers/admin'); -const routerManage = require('./lib/routers/manage'); -const routerOpenapi = require('./lib/routers/openapi'); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); -fs.ensureDir(path.resolve(logDir, 'access')); - -const app = express(); - -app.use(morgan); -app.use(express.json()); -app.use(cors()); - -app.use(routerAdmin); -app.use(routerPing); -app.use(routerManage); -app.use(routerOpenapi); -app.use(routerPing); - -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); - -app.use((error, req, res, next) => res.status(500).json({ message: error.message })); - -app.listen(3000, async () => { - logger.info('[express] ezunpaywall apikey service listening on 3000'); - getConfig(); - await startConnectionRedis(); - pingRedis(); - loadDemoAPIKey(); - cronDemo.start(); -}); diff --git a/src/apikey/config/default.json b/src/apikey/config/default.json deleted file mode 100644 index 1f3e2d8c..00000000 --- a/src/apikey/config/default.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "nodeEnv": "development", - "accessLogRotate": false, - "redis": { - "host": "redis", - "port": "6379", - "password": "changeme" - }, - "apikey": "changeme", - "healthTimeout": 3000 -} \ No newline at end of file diff --git a/src/apikey/lib/routers/openapi.js b/src/apikey/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/apikey/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/apikey/openapi.json b/src/apikey/openapi.json deleted file mode 100644 index 38303b0a..00000000 --- a/src/apikey/openapi.json +++ /dev/null @@ -1,741 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "The Apikey service is reserved for the administrator, it allows to manage the API keys", - "version": "1.0.0", - "title": "Apikey service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "tags": [ - { - "name": "apikey" - }, - { - "name": "ping" - } - ], - "paths": { - "/apikey": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "Success": { - "examples": { - "response": { - "value": "apikey service" - } - }, - "schema": { - "type": "string", - "x-examples": { - "example-1": "apikey service" - } - } - } - } - } - }, - "operationId": "get-apikey", - "description": "Name of service", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/apikey/ping": { - "get": { - "summary": "Ping apikey service", - "operationId": "get-apikey-ping", - "description": "Ping apikey service", - "responses": { - "204": { - "description": "No Content" - } - }, - "tags": [ - "ping" - ] - } - }, - "/apikey/health": { - "get": { - "summary": "Health", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "examples": { - "Success": { - "value": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elapsedTime": 0, - "status": true - } - }, - "Error redis": { - "value": { - "redis": { - "elapsedTime": 3000, - "status": false, - "error": "time out" - }, - "elapsedTime": 3001, - "status": false - } - } - }, - "schema": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - }, - "x-examples": { - "Example 1": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elapsedTime": 0, - "status": true - } - } - } - } - } - } - }, - "operationId": "get-apikey-health", - "description": "Health on all service connected to apikey service", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/apikey/health/redis": { - "get": { - "summary": "Health on redis service", - "operationId": "get-apikey-health-redis", - "description": "Health on redis", - "tags": [ - "ping" - ], - "parameters": [], - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - } - }, - "parameters": [] - }, - "/apikey/keys/${apikey}": { - "get": { - "tags": [ - "apikey" - ], - "summary": "Get config of apikey", - "operationId": "get-apikey-keys-$-apikey", - "description": "Get config of apikey", - "parameters": [ - { - "in": "path", - "name": "apikey", - "description": "apikey", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "config of apikey", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "apikey": { - "type": "string", - "default": "azerty" - }, - "name": { - "type": "string", - "default": "john doe" - }, - "attributes": { - "type": "array", - "items": { - "type": "string", - "default": "*" - } - }, - "access": { - "type": "array", - "items": { - "type": "string", - "default": "graphql" - } - }, - "allowed": { - "type": "boolean" - } - } - } - } - } - } - } - }, - "put": { - "tags": [ - "apikey" - ], - "summary": "Update apikey", - "operationId": "put-apikeys-keys-$-apikey", - "description": "Update apikey", - "parameters": [ - { - "in": "path", - "name": "apikey", - "description": "apikey", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "update apikey", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "apikey": { - "type": "string", - "default": "azerty" - }, - "name": { - "type": "string", - "default": "john doe" - }, - "attributes": { - "type": "array", - "items": { - "type": "string", - "default": "*" - } - }, - "access": { - "type": "array", - "items": { - "type": "string", - "default": "graphql" - } - }, - "allowed": { - "type": "boolean" - } - } - }, - "examples": { - "John Doe apikey": { - "value": { - "apikey": "azerty", - "name": "john doe", - "attributes": [ - "*" - ], - "access": [ - "graphql" - ], - "allowed": true - } - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "\"name\" is required" - } - } - }, - "examples": { - "Name is required": { - "value": { - "message": "\"name\" is required" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - }, - "delete": { - "tags": [ - "apikey" - ], - "summary": "Delete apikey", - "operationId": "delete-apikey-keys-$-apikey", - "description": "Delete apikey", - "parameters": [ - { - "in": "path", - "name": "apikey", - "description": "apikey", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "apikey deleted" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - } - }, - "/apikey/keys": { - "get": { - "tags": [ - "apikey" - ], - "summary": "Get all config of all apikey", - "operationId": "get-apikey-keys", - "description": "Get all config of all apikey", - "responses": { - "200": { - "description": "update apikey", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "apikey": { - "type": "string", - "default": "azerty" - }, - "name": { - "type": "string", - "default": "john doe" - }, - "attributes": { - "type": "array", - "items": { - "type": "string", - "default": "*" - } - }, - "access": { - "type": "array", - "items": { - "type": "string", - "default": "graphql" - } - }, - "allowed": { - "type": "boolean" - } - } - } - }, - "examples": { - "John doe apikey": { - "value": [ - { - "apikey": "azerty", - "name": "john doe", - "attributes": [ - "*" - ], - "access": [ - "graphql" - ], - "allowed": true - } - ] - } - } - }, - "apikey of John Doe": { - "examples": { - "response": { - "value": [ - { - "apikey": "azerty123456", - "name": "John Doe", - "attributes": [ - "*" - ], - "access": [ - "graphql" - ], - "allowed": true - } - ] - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - }, - "delete": { - "tags": [ - "apikey" - ], - "summary": "Delete all apikey", - "operationId": "delete-apikey-keys", - "description": "Delete all apikey", - "responses": { - "204": { - "description": "all apikey are deleted" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - }, - "post": { - "tags": [ - "apikey" - ], - "summary": "Create apikey", - "operationId": "post-apikey-keys", - "description": "Create new apikey", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "attributes": { - "type": "array", - "items": { - "type": "string" - } - }, - "access": { - "type": "array", - "items": { - "type": "string" - } - }, - "allowed": { - "type": "boolean" - } - } - } - } - }, - "description": "config for apikey", - "required": true - }, - "responses": { - "200": { - "description": "update apikey", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "apikey": { - "type": "string", - "default": "azerty" - }, - "name": { - "type": "string", - "default": "john doe" - }, - "attributes": { - "type": "array", - "items": { - "type": "string", - "default": "*" - } - }, - "access": { - "type": "array", - "items": { - "type": "string", - "default": "graphql" - } - }, - "allowed": { - "type": "boolean" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - } - }, - "/apikey/keys/load": { - "post": { - "tags": [ - "apikey" - ], - "summary": "Load apikey", - "operationId": "post-apikeys-keys-load", - "description": "Load apikey", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "apikey": { - "type": "string" - }, - "name": { - "type": "string" - }, - "attributes": { - "type": "array", - "items": { - "type": "string" - } - }, - "access": { - "type": "array", - "items": { - "type": "string" - } - }, - "allowed": { - "type": "boolean" - } - } - }, - "x-examples": { - "example-1": [ - { - "apikey": "string", - "name": "string", - "attributes": [ - "string" - ], - "access": [ - "string" - ], - "allowed": true - } - ] - } - }, - "examples": { - "example-1": { - "value": [ - { - "apikey": "string", - "name": "string", - "attributes": [ - "string" - ], - "access": [ - "string" - ], - "allowed": true - } - ] - } - } - } - }, - "description": "apikeys", - "required": true - }, - "responses": { - "204": { - "description": "all apikey are loaded" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ] - } - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "components": { - "responses": { - "Not-authorized": { - "description": "Not authorized", - "content": { - "Not authorized": { - "examples": { - "response": { - "value": { - "message": "Not authorized" - } - } - } - } - }, - "headers": { - "x-api-key": { - "schema": { - "type": "string" - }, - "description": "redis password" - } - } - }, - "Health": { - "description": "Example response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "elapsedTime": { - "type": "integer" - } - }, - "x-examples": { - "Example 1": { - "name": "redis", - "status": true, - "elapsedTime": 1 - } - } - }, - "examples": { - "Success": { - "value": { - "name": "name of service", - "status": true, - "elapsedTime": 1 - } - }, - "Error redis": { - "value": { - "name": "redis", - "elapsedTime": 3002, - "error": "time out", - "status": false - } - } - } - } - } - } - }, - "securitySchemes": { - "x-api-key": { - "name": "API Key", - "type": "apiKey", - "in": "header" - } - } - } -} \ No newline at end of file diff --git a/src/enrich/Dockerfile b/src/enrich/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/enrich/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/enrich/README.md b/src/enrich/README.md deleted file mode 100644 index f670a2e4..00000000 --- a/src/enrich/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# ezunpaywall-enrich - -csv and jsonl file enrichment service with unpaywall data. - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| NODE_ENV | development | environment of node | -| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | -| REDIS_HOST | redis | redis host | -| REDIS_PORT | 6379 | redis port | -| REDIS_PASSWORD | changeme | redis password | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | - diff --git a/src/enrich/app.js b/src/enrich/app.js deleted file mode 100644 index 96505db2..00000000 --- a/src/enrich/app.js +++ /dev/null @@ -1,60 +0,0 @@ -const express = require('express'); -const fs = require('fs-extra'); -const path = require('path'); -const cors = require('cors'); - -const logger = require('./lib/logger'); -const morgan = require('./lib/morgan'); -const getConfig = require('./lib/config'); - -const { startConnectionRedis, pingRedis } = require('./lib/services/redis'); - -require('./lib/cron'); - -const routerPing = require('./lib/routers/ping'); -const routerJob = require('./lib/routers/job'); -const routerFile = require('./lib/routers/file'); -const routerState = require('./lib/routers/state'); -const routerOpenapi = require('./lib/routers/openapi'); - -const dataDir = path.resolve(__dirname, 'data'); - -fs.ensureDir(path.resolve(dataDir)); -fs.ensureDir(path.resolve(dataDir, 'states')); -fs.ensureDir(path.resolve(dataDir, 'upload')); -fs.ensureDir(path.resolve(dataDir, 'enriched')); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); -fs.ensureDir(path.resolve(logDir, 'access')); - -const app = express(); -app.use(morgan); - -app.use(cors({ - origin: '*', - allowedHeaders: ['Content-Type', 'x-api-key'], - method: ['GET', 'POST'], -})); - -app.use(express.urlencoded({ extended: true })); -app.use(express.json()); - -app.use(routerJob); -app.use(routerFile); -app.use(routerState); -app.use(routerOpenapi); -app.use(routerPing); - -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); - -app.use((error, req, res, next) => res.status(500).json({ message: error.message })); - -app.listen(3000, async () => { - logger.info('[express] ezunpaywall enrich service listening on 3000'); - getConfig(); - await startConnectionRedis(); - pingRedis(); -}); diff --git a/src/enrich/config/default.json b/src/enrich/config/default.json deleted file mode 100644 index 7121fa44..00000000 --- a/src/enrich/config/default.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "nodeEnv": "development", - "accessLogRotate": false, - "redis": { - "host": "redis", - "port": 6379, - "password": "changeme" - }, - "graphql": { - "host": "http://graphql:3000" - }, - "healthTimeout": 3000 -} \ No newline at end of file diff --git a/src/enrich/lib/cron.js b/src/enrich/lib/cron.js deleted file mode 100644 index 7d5dc280..00000000 --- a/src/enrich/lib/cron.js +++ /dev/null @@ -1,32 +0,0 @@ -const path = require('path'); -const Cron = require('./models/cron'); -const logger = require('./logger'); - -const enrichedDir = path.resolve(__dirname, '..', 'data', 'enriched'); -const statesDir = path.resolve(__dirname, '..', 'data', 'states'); -const uploadDir = path.resolve(__dirname, '..', 'data', 'upload'); - -const { deleteFilesInDir } = require('./file'); - -/** - * Removes files generated by an enrichment that are older than one day. - * - * @returns {Promise} - */ -async function task() { - const deletedEnrichedFiles = await deleteFilesInDir(enrichedDir, 1); - logger.info(`[cron: delete out files] ${deletedEnrichedFiles?.join(',')} (${deletedEnrichedFiles.length}) enriched files are deleted`); - - const deletedStatesFiles = await deleteFilesInDir(statesDir, 1); - logger.info(`[cron: delete out files] ${deletedStatesFiles?.join(',')} (${deletedStatesFiles.length}) enriched files are deleted`); - - const deletedUploadedFiles = await deleteFilesInDir(uploadDir, 1); - logger.info(`[cron: delete out files] ${deletedUploadedFiles?.join(',')} (${deletedUploadedFiles.length}) enriched files are deleted`); -} - -/** - * Cron that runs every day to delete files generated by an enrichment that are older than one day. - */ -const cron = new Cron('delete out files', '0 0 0 * * *', task, true); - -module.exports = cron; diff --git a/src/enrich/lib/routers/openapi.js b/src/enrich/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/enrich/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/enrich/lib/services/redis.js b/src/enrich/lib/services/redis.js deleted file mode 100644 index 941b6415..00000000 --- a/src/enrich/lib/services/redis.js +++ /dev/null @@ -1,50 +0,0 @@ -const redis = require('redis'); -const util = require('util'); -const config = require('config'); -const logger = require('../logger'); - -const redisClient = redis.createClient({ - legacyMode: true, - socket: { - host: config.get('redis.host'), - port: config.get('redis.port'), - }, - password: config.get('redis.password'), -}); - -// -redisClient.get = util.promisify(redisClient.get); -redisClient.ping = util.promisify(redisClient.ping); - -/** - * Ping redis service. - * - * @returns {Promise} Ping - */ -async function pingRedis() { - try { - await redisClient.ping(); - } catch (err) { - logger.error(`[redis] Cannot ping ${config.get('redis.host')}:${config.get('redis.port')}`, err); - return false; - } - logger.info(`[redis] ping success ${config.get('redis.host')}:${config.get('redis.port')}`); - return true; -} - -async function startConnectionRedis() { - try { - await redisClient.connect(); - } catch (err) { - logger.error(`[redis] Cannot start connection ${config.get('redis.host')}:${config.get('redis.port')}`, err); - return false; - } - logger.info(`[redis] connect success ${config.get('redis.host')}:${config.get('redis.port')}`); - return true; -} - -module.exports = { - redisClient, - startConnectionRedis, - pingRedis, -}; diff --git a/src/enrich/openapi.json b/src/enrich/openapi.json deleted file mode 100644 index 46a9b03f..00000000 --- a/src/enrich/openapi.json +++ /dev/null @@ -1,633 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "The enrichment service allows to enrich a csv or jsonl file which contains a \"doi\" field with the metadata of the ezunpaywall mirror", - "version": "1.0.0", - "title": "Enrich service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "tags": [ - { - "name": "job" - }, - { - "name": "ping" - } - ], - "paths": { - "/enrich": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "string", - "x-examples": { - "Example 1": "enrich service" - } - }, - "examples": { - "response": { - "value": "enrich service" - } - } - } - } - } - }, - "operationId": "get-enrich", - "description": "Get name of enrich service", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/enrich/ping": { - "get": { - "summary": "Ping enrich service", - "responses": { - "204": { - "description": "No Content" - } - }, - "operationId": "get-enrich-ping", - "description": "Ping enrich service", - "tags": [ - "ping" - ] - } - }, - "/enrich/health": { - "get": { - "summary": "Health", - "operationId": "get-enrich-health", - "description": "Health on all service connected to enrich service", - "tags": [ - "ping" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "graphql": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - }, - "x-examples": { - "Example 1": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "graphql": { - "elapsedTime": 2, - "status": true - }, - "elapsedTime": 2, - "status": true - } - } - }, - "examples": { - "Success": { - "value": { - "redis": { - "elapsedTime": 4, - "status": true - }, - "graphql": { - "elapsedTime": 3, - "status": true - }, - "elapsedTime": 6, - "status": true - } - }, - "Error redis": { - "value": { - "redis": { - "elapsedTime": 3003, - "status": false, - "error": "time out" - }, - "graphql": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 3003, - "status": false - } - } - } - } - } - } - } - }, - "parameters": [] - }, - "/enrich/health/redis": { - "get": { - "summary": "Health on redis service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-enrich-health-redis", - "description": "Health on redis", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/enrich/health/elastic": { - "get": { - "summary": "Health on graphql service", - "operationId": "get-enrich-health-elastic", - "description": "Health on elastic", - "tags": [ - "ping" - ], - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - } - }, - "parameters": [] - }, - "/enrich/upload": { - "post": { - "summary": "Upload a file", - "operationId": "post-enrich-upload", - "description": "Upload a file to be enriched", - "responses": { - "200": { - "description": "filename of uploaded file", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "id" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - }, - "parameters": [] - }, - "/enrich/job/{filename}": { - "post": { - "summary": "Enrich job", - "operationId": "post-enrich-job-$-filename", - "description": "Start a enrich job with uploaded file", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "keys": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "args": { - "type": "string" - }, - "index": { - "type": "string" - }, - "separator": { - "type": "string" - } - } - } - } - } - } - } - }, - "description": "apikeys", - "required": true - }, - "responses": { - "200": { - "description": "filename of process", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "id" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/enrich/enriched": { - "get": { - "summary": "Get enriched files", - "operationId": "get-enrich-enriched", - "description": "Get the list of enriched files", - "responses": { - "200": { - "description": "list of enriched file", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string", - "default": "file.csv" - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/enrich/enriched/${filename}": { - "get": { - "summary": "Get enriched file", - "operationId": "get-enrich-enriched-$-filename", - "description": "Get the enriched file, generated at the end of the enrichment process", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "enriched file", - "content": { - "application/json": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/enrich/states": { - "get": { - "summary": "Get list of states of enrich job", - "operationId": "get-enrich-states", - "description": "Get list of filenames state of enrich process", - "parameters": [ - { - "in": "query", - "name": "latest", - "description": "latest", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "list of states file", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string", - "default": "file.json" - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "tags": [ - "job" - ] - } - }, - "/enrich/states/${filename}": { - "get": { - "summary": "Get State", - "operationId": "get-enrich-states-$-filename", - "description": "Get state of enrich process with his filename", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "list of uploaded file", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "done": { - "type": "boolean", - "default": true - }, - "loaded": { - "type": "integer", - "default": 150 - }, - "linesRead": { - "type": "integer", - "default": 3 - }, - "enrichedLines": { - "type": "integer", - "default": 3 - }, - "createdAt": { - "type": "string", - "default": "2021-11-30T10:00:00.000Z" - }, - "endAt": { - "type": "string", - "default": "2021-11-30T10:01:00.000Z" - }, - "error": { - "type": "boolean", - "default": false - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "404": { - "description": "File not found", - "content": { - "File not found": { - "examples": { - "response": { - "value": { - "message": "File not found" - } - } - } - } - } - } - }, - "tags": [ - "job" - ] - } - }, - "/enrich/uploaded": { - "get": { - "summary": "Get uploaded files", - "operationId": "get-enriched-uploaded", - "description": "Get the lists of uploaded files", - "responses": { - "200": { - "description": "list of uploaded file", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string", - "default": "file.csv" - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - }, - "parameters": [] - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "components": { - "responses": { - "Not-authorized": { - "description": "Not authorized", - "headers": {}, - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "Not authorized" - } - } - } - }, - "Not authorized": { - "examples": { - "response": { - "value": { - "message": "Not authorized" - } - } - } - } - } - }, - "Health": { - "description": "Example response", - "content": { - "Success": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "elapsedTime": { - "type": "integer" - } - }, - "x-examples": { - "Example 1": { - "name": "redis", - "status": true, - "elapsedTime": 1 - } - } - }, - "examples": { - "Success": { - "value": { - "name": "name of service", - "status": true, - "elapsedTime": 1 - } - }, - "Error redis": { - "value": { - "name": "redis", - "elapsedTime": 3002, - "error": "time out", - "status": false - } - } - } - } - } - } - }, - "securitySchemes": { - "x-api-key": { - "name": "API Key", - "type": "apiKey", - "in": "header" - } - } - } -} \ No newline at end of file diff --git a/src/fakeUnpaywall/snapshots/changefiles-day-example.json b/src/fakeUnpaywall/snapshots/changefiles-day-example.json deleted file mode 100644 index d40c80d4..00000000 --- a/src/fakeUnpaywall/snapshots/changefiles-day-example.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "list": [ - { - "date": "", - "filename": "fake1.jsonl.gz", - "filetype": "jsonl", - "last_modified": "", - "lines": 50, - "size": 19896, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz?api_key=default" - }, - { - "date": "", - "filename": "fake2.jsonl.gz", - "filetype": "jsonl", - "last_modified": "", - "lines": 100, - "size": 44137, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake2.jsonl.gz?api_key=default" - }, - { - "date": "", - "filename": "fake3.jsonl.gz", - "filetype": "jsonl", - "last_modified": "", - "lines": 2000, - "size": 877494, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake3.jsonl.gz?api_key=default" - }, - { - "date": "", - "filename": "fake1-error.jsonl.gz", - "filetype": "jsonl", - "last_modified": "", - "lines": 50, - "size": 19918, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1-error.jsonl.gz?api_key=default" - }, - { - "date": "", - "filename": "fake1.jsonl.gz", - "filetype": "jsonl", - "last_modified": "", - "lines": 50, - "size": 19896, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz?api_key=default" - } - ] -} \ No newline at end of file diff --git a/src/frontend/components/administration/health/HealthCard.vue b/src/frontend/components/administration/health/HealthCard.vue deleted file mode 100644 index 36710cd8..00000000 --- a/src/frontend/components/administration/health/HealthCard.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/src/frontend/components/graphql/result/ResultTab.vue b/src/frontend/components/graphql/result/ResultTab.vue deleted file mode 100644 index 54790cd9..00000000 --- a/src/frontend/components/graphql/result/ResultTab.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/src/frontend/components/graphql/settings/UnpaywallArgsSelectorTab.vue b/src/frontend/components/graphql/settings/UnpaywallArgsSelectorTab.vue deleted file mode 100644 index e1a864b9..00000000 --- a/src/frontend/components/graphql/settings/UnpaywallArgsSelectorTab.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json deleted file mode 100644 index e38fc008..00000000 --- a/src/frontend/package-lock.json +++ /dev/null @@ -1,28927 +0,0 @@ -{ - "name": "client", - "version": "1.3.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "client", - "version": "1.3.0", - "hasInstallScript": true, - "dependencies": { - "@highlightjs/vue-plugin": "^2.1.0", - "@mdi/font": "^7.2.96", - "@nuxtjs/i18n": "^8.0.0-rc.2", - "@pinia/nuxt": "^0.4.11", - "axios": "^1.4.0", - "pinia": "^2.1.6", - "sass": "^1.65.1", - "swagger-ui": "^5.4.2", - "vuetify": "^3.3.14" - }, - "devDependencies": { - "@nuxt/devtools": "latest", - "@nuxt/eslint-config": "^0.2.0", - "eslint": "^8.48.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-vue": "^9.17.0", - "nuxt": "^3.7.0", - "vue-i18n": "^9.2.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==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@antfu/utils": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.6.tgz", - "integrity": "sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", - "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.11", - "@babel/parser": "^7.22.11", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", - "dependencies": { - "@babel/types": "^7.22.10", - "@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-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", - "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", - "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.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "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==", - "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==", - "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==", - "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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", - "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.6", - "@babel/helper-validator-identifier": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.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-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", - "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" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.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==", - "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.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==", - "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==", - "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==", - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", - "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", - "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.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-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "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-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", - "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", - "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-typescript": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz", - "integrity": "sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", - "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.22.11.tgz", - "integrity": "sha512-NhfzUbdWbiE6fCFypbWCPu6AR8xre31EOPF7wwAIJEvGQ2avov04eymayWinCuyXmV1b0+jzoXP/HYzzUYdvwg==", - "dependencies": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/standalone": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.22.14.tgz", - "integrity": "sha512-i61lDNe0nRm44nZj05g+1HNb0EVfDGaTI6PkoeUMUSel3GTG6T1OM3BdjZIXghnnFB8bSWbmfS1lkBQgNUdu5w==", - "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==", - "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.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", - "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@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.11", - "@babel/types": "^7.22.11", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", - "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/@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "node_modules/@cloudflare/kv-asset-handler": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.0.tgz", - "integrity": "sha512-9CB/MKf/wdvbfkUdfrj+OkEwZ5b7rws0eogJ4293h+7b6KX5toPwym+VQKmILafNB9YiehqY0DlNrDcDhdWHSQ==", - "dev": true, - "dependencies": { - "mime": "^3.0.0" - } - }, - "node_modules/@esbuild-kit/cjs-loader": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz", - "integrity": "sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==", - "dev": true, - "dependencies": { - "@esbuild-kit/core-utils": "^3.0.0", - "get-tsconfig": "^4.4.0" - } - }, - "node_modules/@esbuild-kit/core-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.2.2.tgz", - "integrity": "sha512-Ub6LaRaAgF80dTSzUdXpFLM1pVDdmEVB9qb5iAzSpyDlX/mfJTFGOnZ516O05p5uWWteNviMKi4PAyEuRxI5gA==", - "dev": true, - "dependencies": { - "esbuild": "~0.18.20", - "source-map-support": "^0.5.21" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/@esbuild-kit/esm-loader": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz", - "integrity": "sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==", - "dev": true, - "dependencies": { - "@esbuild-kit/core-utils": "^3.0.0", - "get-tsconfig": "^4.4.0" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.2.tgz", - "integrity": "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz", - "integrity": "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.2.tgz", - "integrity": "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz", - "integrity": "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz", - "integrity": "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz", - "integrity": "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz", - "integrity": "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz", - "integrity": "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz", - "integrity": "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz", - "integrity": "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz", - "integrity": "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz", - "integrity": "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz", - "integrity": "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz", - "integrity": "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz", - "integrity": "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz", - "integrity": "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz", - "integrity": "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz", - "integrity": "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz", - "integrity": "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz", - "integrity": "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz", - "integrity": "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz", - "integrity": "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==", - "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.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "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/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.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/@highlightjs/vue-plugin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz", - "integrity": "sha512-E+bmk4ncca+hBEYRV2a+1aIzIV0VSY/e5ArjpuSN9IO7wBJrzUE2u4ESCwrbQD7sAy+jWQjkV5qCCWgc+pu7CQ==", - "peerDependencies": { - "highlight.js": "^11.0.1", - "vue": "^3" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "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/@intlify/bundle-utils": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.1.0.tgz", - "integrity": "sha512-Q88Wl2T8oaRXls8Yr6l807jZM88mceJvK7QS6gKdU8/pf3gTpU9XmcYORDgAv6h5WKQMoaFjNVf5+SWLfTAysA==", - "dependencies": { - "@intlify/message-compiler": "9.3.0-beta.27", - "@intlify/shared": "9.3.0-beta.27", - "acorn": "^8.8.2", - "escodegen": "^2.0.0", - "estree-walker": "^2.0.2", - "jsonc-eslint-parser": "^2.3.0", - "magic-string": "^0.30.0", - "mlly": "^1.2.0", - "source-map-js": "^1.0.1", - "yaml-eslint-parser": "^1.2.2" - }, - "engines": { - "node": ">= 14.16" - }, - "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - } - } - }, - "node_modules/@intlify/bundle-utils/node_modules/@intlify/shared": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.27.tgz", - "integrity": "sha512-hPMsmVCs+ZUVHHU5VORG6LopzXZT7zmyVNqc9OQG80YpA/N4lT/pkJ4B6DTNIsv2C7mwfGM7RdK+0qPki43YgA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/bundle-utils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@intlify/bundle-utils/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@intlify/core-base": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz", - "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", - "devOptional": true, - "dependencies": { - "@intlify/devtools-if": "9.2.2", - "@intlify/message-compiler": "9.2.2", - "@intlify/shared": "9.2.2", - "@intlify/vue-devtools": "9.2.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/core-base/node_modules/@intlify/message-compiler": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", - "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", - "devOptional": true, - "dependencies": { - "@intlify/shared": "9.2.2", - "source-map": "0.6.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/core-base/node_modules/@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/devtools-if": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", - "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", - "devOptional": true, - "dependencies": { - "@intlify/shared": "9.2.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/devtools-if/node_modules/@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/message-compiler": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.27.tgz", - "integrity": "sha512-GC8rSbd7V67Zu+a9Z0bpV4riBek11YCURJU50YaEhV4Ub2JHEPtoYxK5r2eIsq/kp+M2hJyGLiC4NJUrGa2VwQ==", - "dependencies": { - "@intlify/shared": "9.3.0-beta.27", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/message-compiler/node_modules/@intlify/shared": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.27.tgz", - "integrity": "sha512-hPMsmVCs+ZUVHHU5VORG6LopzXZT7zmyVNqc9OQG80YpA/N4lT/pkJ4B6DTNIsv2C7mwfGM7RdK+0qPki43YgA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/shared": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.26.tgz", - "integrity": "sha512-RpCtfSYIg4tSskrazTr5+WCHyw6qpgwdIxC+x3nCnrPGxyk+en9FoSbadVfx/w7uDTdyhKslEw4d2+qhNc0s4Q==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/unplugin-vue-i18n": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-0.12.3.tgz", - "integrity": "sha512-0riPtSfTM58JmGNMmJho/aHD2z3K24BESYAmkLvKlo61/LbaPvnjYU1DbSbJEm6bSjE2oEjUj+di3QaYxXei/w==", - "dependencies": { - "@intlify/bundle-utils": "^7.0.2", - "@intlify/shared": "9.3.0-beta.24", - "@rollup/pluginutils": "^5.0.2", - "@vue/compiler-sfc": "^3.2.47", - "debug": "^4.3.3", - "fast-glob": "^3.2.12", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "pathe": "^1.0.0", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2", - "unplugin": "^1.1.0" - }, - "engines": { - "node": ">= 14.16" - }, - "peerDependencies": { - "petite-vue-i18n": "*", - "vue-i18n": "*", - "vue-i18n-bridge": "*" - }, - "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { - "optional": true - } - } - }, - "node_modules/@intlify/unplugin-vue-i18n/node_modules/@intlify/shared": { - "version": "9.3.0-beta.24", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.24.tgz", - "integrity": "sha512-AKxJ8s7eKIQWkNaf4wyyoLRwf4puCuQgjSChlDJm5JBEt6T8HGgnYTJLRXu6LD/JACn3Qwu6hM/XRX1c9yvjmQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/vue-devtools": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", - "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", - "devOptional": true, - "dependencies": { - "@intlify/core-base": "9.2.2", - "@intlify/shared": "9.2.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@intlify/vue-devtools/node_modules/@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" - }, - "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/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/@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==", - "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.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "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==", - "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==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/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/@mapbox/node-pre-gyp/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/@mapbox/node-pre-gyp/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/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": 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/@mdi/font": { - "version": "7.2.96", - "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.2.96.tgz", - "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w==" - }, - "node_modules/@mizchi/sucrase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@mizchi/sucrase/-/sucrase-4.1.0.tgz", - "integrity": "sha512-AaN8HSGdXmNqEqIb0IQPIQL+MI/8Xr1QTOcVnA6k0u2afqfYhlre05hSxRybOFpq34oF8EqMTrYovYZxEV1FLw==", - "dependencies": { - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@netlify/functions": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.0.2.tgz", - "integrity": "sha512-goWRtaIPUK/q47qLYtfGGj7HgJIRaT0snw7zZ0yeoNTfQfCRwQwvRrMAsXkCsCtq2N2Oo81L26SpkMxEQMk9hg==", - "dev": true, - "dependencies": { - "@netlify/serverless-functions-api": "1.7.3", - "is-promise": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@netlify/node-cookies": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", - "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==", - "dev": true, - "engines": { - "node": "^14.16.0 || >=16.0.0" - } - }, - "node_modules/@netlify/serverless-functions-api": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.7.3.tgz", - "integrity": "sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==", - "dev": true, - "dependencies": { - "@netlify/node-cookies": "^0.1.0", - "urlpattern-polyfill": "8.0.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.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==", - "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==", - "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==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.1.0.tgz", - "integrity": "sha512-/HFJP3a/DzgIg+6TWVee3bQmnBcWeKKYE9DKQqS8SWpAV8oYDTn/zkDM8iQ7bWI6kDDgNfHOlEFZZpN/UXMwig==", - "dev": true, - "dependencies": { - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/agent/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, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/@npmcli/agent/node_modules/socks-proxy-agent": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz", - "integrity": "sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.1", - "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "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": "5.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.3.tgz", - "integrity": "sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw==", - "dev": true, - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/@npmcli/git/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^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": "7.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz", - "integrity": "sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ==", - "dev": true, - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.1.tgz", - "integrity": "sha512-Od/JMrgkjZ8alyBE0IzeqZDiF1jgMez9Gkc/OYrCkHHiXNwM0wc6s7+h+xM7kYDZkS0tAoOLr9VvygyE5+2F7g==", - "dev": true, - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/run-script/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@nuxt/devalue": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz", - "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==", - "dev": true - }, - "node_modules/@nuxt/devtools": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools/-/devtools-0.8.2.tgz", - "integrity": "sha512-E3ycLEkqTlXpdz3P7lJRMdB4AnC4tzALM6N6eCUskSCtUQfF57mjk0k7z1duHIjU8xTIFm6gnsotJnR/n6/B0g==", - "dev": true, - "dependencies": { - "@antfu/utils": "^0.7.6", - "@nuxt/devtools-kit": "0.8.2", - "@nuxt/devtools-wizard": "0.8.2", - "@nuxt/kit": "^3.7.0", - "birpc": "^0.2.13", - "boxen": "^7.1.1", - "consola": "^3.2.3", - "error-stack-parser-es": "^0.1.1", - "execa": "^7.2.0", - "fast-folder-size": "^2.2.0", - "fast-glob": "^3.3.1", - "flatted": "^3.2.7", - "get-port-please": "^3.0.2", - "global-dirs": "^3.0.1", - "h3": "^1.8.1", - "hookable": "^5.5.3", - "image-meta": "^0.1.1", - "is-installed-globally": "^0.4.0", - "launch-editor": "^2.6.0", - "local-pkg": "^0.4.3", - "magicast": "^0.2.10", - "nypm": "^0.3.1", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "pacote": "^17.0.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "picocolors": "^1.0.0", - "pkg-types": "^1.0.3", - "rc9": "^2.1.1", - "semver": "^7.5.4", - "simple-git": "^3.19.1", - "sirv": "^2.0.3", - "unimport": "^3.2.0", - "vite-plugin-inspect": "^0.7.38", - "vite-plugin-vue-inspector": "^3.6.0", - "wait-on": "^7.0.1", - "which": "^3.0.1", - "ws": "^8.13.0" - }, - "bin": { - "devtools": "cli.mjs" - }, - "peerDependencies": { - "nuxt": "^3.6.5", - "vite": "*" - } - }, - "node_modules/@nuxt/devtools-kit": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-0.8.2.tgz", - "integrity": "sha512-GEqpBxa/ojfhAM9HN5L/OzCADpfH9nDbcC7INHFgao6KuAu6JclTpcuV6VZP6LthsETBsd2cKAt93WY+vEJnnQ==", - "dev": true, - "dependencies": { - "@nuxt/kit": "^3.7.0", - "@nuxt/schema": "^3.7.0", - "execa": "^7.2.0" - }, - "peerDependencies": { - "nuxt": "^3.6.5", - "vite": "*" - } - }, - "node_modules/@nuxt/devtools-wizard": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools-wizard/-/devtools-wizard-0.8.2.tgz", - "integrity": "sha512-d6uT98di8T6Bn/aQpRwMZPjUtrdBmjNAdrDS8s3e2SDy13HVMAsEVbJWKtfYV8oN8vrSkB0Z6tGgdbKyOLyiuw==", - "dev": true, - "dependencies": { - "consola": "^3.2.3", - "diff": "^5.1.0", - "execa": "^7.2.0", - "global-dirs": "^3.0.1", - "magicast": "^0.2.10", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "pkg-types": "^1.0.3", - "prompts": "^2.4.2", - "rc9": "^2.1.1", - "semver": "^7.5.4" - }, - "bin": { - "devtools-wizard": "cli.mjs" - } - }, - "node_modules/@nuxt/eslint-config": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@nuxt/eslint-config/-/eslint-config-0.2.0.tgz", - "integrity": "sha512-NeJX8TLcnNAjQFiDs3XhP+9CHKK8jaKsP7eUyCSrQdgY7nqWe7VJx64lwzx5FTT4cW3RHMEyH+Y0qzLGYYoa/A==", - "dev": true, - "dependencies": { - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/eslint-plugin": "^6.5.0", - "@typescript-eslint/parser": "^6.5.0", - "eslint-plugin-vue": "^9.17.0", - "typescript": "^5.2.2" - }, - "peerDependencies": { - "eslint": "^8.48.0" - } - }, - "node_modules/@nuxt/kit": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.7.0.tgz", - "integrity": "sha512-bsPRb2NTLHRacjyybhhA3pZFIqo2pxB6bcP4FQDuzlGzVTI5PtJzbfNpkmQC7q+LZt8K0pNlxKVGisDvZctk6w==", - "dependencies": { - "@nuxt/schema": "3.7.0", - "c12": "^1.4.2", - "consola": "^3.2.3", - "defu": "^6.1.2", - "globby": "^13.2.2", - "hash-sum": "^2.0.0", - "ignore": "^5.2.4", - "jiti": "^1.19.3", - "knitwork": "^1.0.0", - "mlly": "^1.4.1", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "scule": "^1.0.0", - "semver": "^7.5.4", - "ufo": "^1.3.0", - "unctx": "^2.3.1", - "unimport": "^3.2.0", - "untyped": "^1.4.0" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/@nuxt/schema": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-3.7.0.tgz", - "integrity": "sha512-fNRAubny1x6rIibm/HcacnEGeAQri/FkJ5ei24aY4YjQ12+xDfi7bljfFr6C2+CrEGc1beYd4OQcUqXqEpz5+g==", - "dependencies": { - "@nuxt/ui-templates": "^1.3.1", - "defu": "^6.1.2", - "hookable": "^5.5.3", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "postcss-import-resolver": "^2.0.0", - "std-env": "^3.4.3", - "ufo": "^1.3.0", - "unimport": "^3.2.0", - "untyped": "^1.4.0" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/@nuxt/telemetry": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-2.4.1.tgz", - "integrity": "sha512-Cj+4sXjO5pZNW2sX7Y+djYpf4pZwgYF3rV/YHLWIOq9nAjo2UcDXjh1z7qnhkoUkvJN3lHnvhnCNhfAioe6k/A==", - "dev": true, - "dependencies": { - "@nuxt/kit": "^3.6.5", - "chalk": "^5.3.0", - "ci-info": "^3.8.0", - "consola": "^3.2.3", - "create-require": "^1.1.1", - "defu": "^6.1.2", - "destr": "^2.0.0", - "dotenv": "^16.3.1", - "fs-extra": "^11.1.1", - "git-url-parse": "^13.1.0", - "is-docker": "^3.0.0", - "jiti": "^1.19.1", - "mri": "^1.2.0", - "nanoid": "^4.0.2", - "node-fetch": "^3.3.1", - "ofetch": "^1.1.1", - "parse-git-config": "^3.0.0", - "pathe": "^1.1.1", - "rc9": "^2.1.1", - "std-env": "^3.3.3" - }, - "bin": { - "nuxt-telemetry": "bin/nuxt-telemetry.mjs" - } - }, - "node_modules/@nuxt/ui-templates": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@nuxt/ui-templates/-/ui-templates-1.3.1.tgz", - "integrity": "sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==" - }, - "node_modules/@nuxt/vite-builder": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/vite-builder/-/vite-builder-3.7.0.tgz", - "integrity": "sha512-bRJy3KarHrFm/xLGHoHeZyqI/h6c4UFRCF5ngRZ/R9uebJEHuL4UhAioxDLTFu7D0vEeK7XaDgx6+NPLhBg51g==", - "dev": true, - "dependencies": { - "@nuxt/kit": "3.7.0", - "@rollup/plugin-replace": "^5.0.2", - "@vitejs/plugin-vue": "^4.3.3", - "@vitejs/plugin-vue-jsx": "^3.0.2", - "autoprefixer": "^10.4.15", - "clear": "^0.1.0", - "consola": "^3.2.3", - "cssnano": "^6.0.1", - "defu": "^6.1.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "externality": "^1.0.2", - "fs-extra": "^11.1.1", - "get-port-please": "^3.0.1", - "h3": "^1.8.0", - "knitwork": "^1.0.0", - "magic-string": "^0.30.3", - "mlly": "^1.4.1", - "ohash": "^1.1.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "postcss": "^8.4.28", - "postcss-import": "^15.1.0", - "postcss-url": "^10.1.3", - "rollup-plugin-visualizer": "^5.9.2", - "std-env": "^3.4.3", - "strip-literal": "^1.3.0", - "ufo": "^1.3.0", - "unplugin": "^1.4.0", - "vite": "^4.4.9", - "vite-node": "^0.33.0", - "vite-plugin-checker": "^0.6.2", - "vue-bundle-renderer": "^2.0.0" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0" - }, - "peerDependencies": { - "vue": "^3.3.4" - } - }, - "node_modules/@nuxt/vite-builder/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@nuxt/vite-builder/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@nuxtjs/i18n": { - "version": "8.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@nuxtjs/i18n/-/i18n-8.0.0-rc.3.tgz", - "integrity": "sha512-TrJF7OxCK1CcEnKQHcP3VjVnb0K22OdMxdbWOk/kUzD9DX6+hrcrfrQD6W7xDA5pnEhBnsw1pLT2I+DYVpK/gw==", - "dependencies": { - "@intlify/shared": "9.3.0-beta.26", - "@intlify/unplugin-vue-i18n": "^0.12.2", - "@mizchi/sucrase": "^4.1.0", - "@nuxt/kit": "^3.6.5", - "@vue/compiler-sfc": "^3.3.4", - "cookie-es": "^1.0.0", - "debug": "^4.3.4", - "defu": "^6.1.2", - "estree-walker": "^3.0.3", - "is-https": "^4.0.0", - "js-cookie": "^3.0.5", - "knitwork": "^1.0.0", - "magic-string": "^0.27.0", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.1.2", - "unplugin": "^1.3.2", - "unstorage": "^1.5.0", - "vue-i18n": "9.3.0-beta.26", - "vue-i18n-routing": "^0.13.3" - }, - "engines": { - "node": "^14.16.0 || >=16.11.0" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@intlify/core-base": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.3.0-beta.26.tgz", - "integrity": "sha512-omhEuB6+uE3D36wAtBazTkjQxfMy+sHAdvPe51aPINVcIiL9RZiSMgecipbvkjqnL/5ogTcCc/UXKWlM3jb90g==", - "dependencies": { - "@intlify/devtools-if": "9.3.0-beta.26", - "@intlify/message-compiler": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26", - "@intlify/vue-devtools": "9.3.0-beta.26" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@intlify/devtools-if": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.3.0-beta.26.tgz", - "integrity": "sha512-N13XwjkT/payWlr8DqBVylsPlwjm4WyaI+eaG+eVdBKPw0yI/9c4zJ3U+/ASRBRuzArVJxALE+LT/cI1NxWGvw==", - "dependencies": { - "@intlify/shared": "9.3.0-beta.26" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@intlify/message-compiler": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.26.tgz", - "integrity": "sha512-qsfU6Lca7mI80ts1vgy+pfNvGm2gHy0nERpT/K1GYgnECmsKwud0e8SG1PPxKPEHKa5Mdngzs4pS7X1wH0SCGA==", - "dependencies": { - "@intlify/shared": "9.3.0-beta.26", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@intlify/vue-devtools": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.3.0-beta.26.tgz", - "integrity": "sha512-IwJM8jUCM+savGDvgcOQaVHNMPDbvRf9dVjB+skCemYA7DBqtJ0YypTlRDtt6PO9rDfkWU2Z0ueaY/o6OaGtRg==", - "dependencies": { - "@intlify/core-base": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.3.0-beta.26.tgz", - "integrity": "sha512-RfyxO4wMJ3SiqjxKGydA1RnJ6rvl4y60Urzqab80x9weCooNdb7++fRce+ZtSqtvnt4NTSq4je/WWyU8EAR9cA==", - "dependencies": { - "@intlify/core-base": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26", - "@intlify/vue-devtools": "9.3.0-beta.26", - "@vue/devtools-api": "^6.5.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/vue-i18n-routing/-/vue-i18n-routing-0.13.4.tgz", - "integrity": "sha512-cihM/X4c6dgAnSVoIc3wUoiGG6B/Y+a3B3+Xt+7b9n2mjnKQ+ZkQ6oKVQxOd8WFRdJyohlP5dyL3Xsho4HZjBw==", - "dependencies": { - "@intlify/shared": "next", - "@intlify/vue-i18n-bridge": "^0.8.0", - "@intlify/vue-router-bridge": "^0.8.0", - "ufo": "^1.2.0", - "vue-demi": "^0.14.5" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^2.6.14 || ^2.7.0 || ^3.2.0", - "vue-i18n": "^8.26.1 || ^9.2.0 || ^9.3.0-beta.10", - "vue-i18n-bridge": "^9.2.0 || ^9.3.0-beta.10", - "vue-router": "^3.5.3 || ^3.6.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "vue": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { - "optional": true - }, - "vue-router": { - "optional": true - } - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing/node_modules/@intlify/vue-i18n-bridge": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@intlify/vue-i18n-bridge/-/vue-i18n-bridge-0.8.0.tgz", - "integrity": "sha512-wQ18fSccm9QaWpUW2vq2QHvojgKIog7s+UMj9LeY3pUV3yD9bU4YZI+1PTNoX3tOA+BE71gQyqVGox/TVQKP6Q==", - "hasInstallScript": true, - "bin": { - "vue-i18n-fix": "bin/fix.js", - "vue-i18n-switch": "bin/switch.js" - }, - "engines": { - "node": ">= 12" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue-i18n": "^8.26.1 || ^9.2.0-beta.25 || ^9.3.0-beta.5", - "vue-i18n-bridge": "^9.2.0-beta.25 || ^9.3.0-beta.5" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { - "optional": true - } - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing/node_modules/@intlify/vue-router-bridge": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@intlify/vue-router-bridge/-/vue-router-bridge-0.8.0.tgz", - "integrity": "sha512-CNxOgvyQcRhtGmRrksicL+HGjDijXtz+J/x04C/RslZ74CFdZkxjCe8MABkeD3xr+ry8G8tCm2nV2hLjZbynQw==", - "hasInstallScript": true, - "dependencies": { - "vue-demi": "^0.13.5" - }, - "bin": { - "vue-router-fix": "bin/fix.js", - "vue-router-switch": "bin/switch.js" - }, - "engines": { - "node": ">= 12" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue-router": "^4.0.0-0 || ^3.0.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "vue-router": { - "optional": true - } - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing/node_modules/@intlify/vue-router-bridge/node_modules/vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@parcel/watcher": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.3.0.tgz", - "integrity": "sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ==", - "hasInstallScript": true, - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.3.0", - "@parcel/watcher-darwin-arm64": "2.3.0", - "@parcel/watcher-darwin-x64": "2.3.0", - "@parcel/watcher-freebsd-x64": "2.3.0", - "@parcel/watcher-linux-arm-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-musl": "2.3.0", - "@parcel/watcher-linux-x64-glibc": "2.3.0", - "@parcel/watcher-linux-x64-musl": "2.3.0", - "@parcel/watcher-win32-arm64": "2.3.0", - "@parcel/watcher-win32-ia32": "2.3.0", - "@parcel/watcher-win32-x64": "2.3.0" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz", - "integrity": "sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz", - "integrity": "sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz", - "integrity": "sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz", - "integrity": "sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz", - "integrity": "sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz", - "integrity": "sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz", - "integrity": "sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz", - "integrity": "sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz", - "integrity": "sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-wasm": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz", - "integrity": "sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA==", - "bundleDependencies": [ - "napi-wasm" - ], - "dependencies": { - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "napi-wasm": "^1.1.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-wasm/node_modules/napi-wasm": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz", - "integrity": "sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz", - "integrity": "sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz", - "integrity": "sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@pinia/nuxt": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.4.11.tgz", - "integrity": "sha512-bhuNFngJpmBCdAqWguezNJ/oJFR7wvKieqiZrmmdmPR07XjsidAw8RLXHMZE9kUm32M9E6T057OBbG/22jERTg==", - "dependencies": { - "@nuxt/kit": "^3.5.0", - "pinia": ">=2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - } - }, - "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/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true - }, - "node_modules/@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", - "dev": true, - "dependencies": { - "slash": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", - "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@rollup/plugin-inject": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", - "integrity": "sha512-411QlbL+z2yXpRWFXSmw/teQRMkXcAAC8aYTemc15gwJRpvEVDQwoe+N/HTFD8RFG8+88Bme9DK2V9CVm7hJdA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-inject/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", - "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", - "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz", - "integrity": "sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==", - "dev": true, - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.x || ^3.x" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-wasm": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", - "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", - "dev": true, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz", - "integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", - "integrity": "sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw==", - "dev": true - }, - "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/bundle": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.1.0.tgz", - "integrity": "sha512-89uOo6yh/oxaU8AeOUnVrTdVMcGk9Q1hJa7Hkvalc6G3Z3CupWk4Xe9djSgJm9fMkH69s0P0cVHUoKSOemLdng==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", - "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.1.0.tgz", - "integrity": "sha512-4VRpfJxs+8eLqzLVrZngVNExVA/zAhVbi4UT4zmtLi4xRd7vz5qie834OgkrGsLlLB1B2nz/3wUxT1XAUBe8gw==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/tuf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.1.0.tgz", - "integrity": "sha512-BUoVCx+7Wj+8moEGvUU2MyBI+f93lmg1CLmoG6KrhQMeDyAG8HAZNk+YRCNuvwvSDCfPhwsj37Bg63/Q+bnGsw==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@swagger-api/apidom-ast": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.75.0.tgz", - "integrity": "sha512-IOAVA835ZuNFR23Tpca/q1FUyv4cQ8c4nnN3NsmXU+rLP+qrhsyyqkUa0pRAMvE77EfZfOcfJpUo0WTYozPTag==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "unraw": "^3.0.0" - } - }, - "node_modules/@swagger-api/apidom-core": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.75.0.tgz", - "integrity": "sha512-DuWQm0YYhBhEDX/u8EbLtKhWpgrk7+DjYD6WYh8emt6eZGpRuVWDABPN6LXZy4BpQ60Fy0aBSZaSf5C+404LCw==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@types/ramda": "~0.29.3", - "minim": "~0.23.8", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "short-unique-id": "^4.4.4", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-json-pointer": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.75.0.tgz", - "integrity": "sha512-BdwXIHA3Ulmdik3bOzvX2n320fDcdOX+GO0eUG2Ewi7OHI5gQEQZdkeGONF6PFpG5M5afKYnduYOxkz4MPQEjA==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-ns-api-design-systems": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-0.75.0.tgz", - "integrity": "sha512-3+2w4WJ5iHeTeI5Go3T1kbpHUVeTd/GGrbjP5YpD8FGeW5aNodRnMZi5DnmPZ1jqJJT6JLLxQWTubFnd3v1ksQ==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-asyncapi-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-0.75.0.tgz", - "integrity": "sha512-W+EifcReXeNTaDlp75+sX5Ev3upkT1aZ3D1HLSKhGyi3weuOcPFYc7PTDVmoDJTSCch4NFXIFrAEvRNNxzhHvA==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-7": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.75.0.tgz", - "integrity": "sha512-DjkbOjeqz5AYr6PWFWSPb4hKiVFUpB0iRdZEtPOU4YKd9lSImDe4rnob2uDDJR5uQV6FoG2BAVRTckEvPQa0+g==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-0.75.0.tgz", - "integrity": "sha512-sDQLgRpjRUons2B8s3fvRZXCS4Zg5gC3zhkuQmh4a1Uu+Fu+QG2wQ/WY5Q7MBj6G8QL2wnxihCYOdTd9IpA/Xg==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-0.75.0.tgz", - "integrity": "sha512-P0g0J16QmAO4Tjd8E1Gi7ESlEcyouq3CaYVZ0Rz1KSNNi9nkUOKTd4/i1LSTgKQHs86U4WlJFSk6iQxfkzhgcQ==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-6": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.75.0.tgz", - "integrity": "sha512-ndJC9QeIIMeK2WpeJeEGUuwcmDXXuEtOKl9GCX4sbXicZbI00cv7FJCJeFPL7QdVsHFfAm+e9DbDgn1k2K7Eww==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.75.0.tgz", - "integrity": "sha512-j2lvGKceplAVDnhm84klUPzBAwJewdpZf7fD28szEeMMNfXi40y70rs6iFKTH6FVuBc/k5/nf/M44tQY+sdqGw==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-0.75.0.tgz", - "integrity": "sha512-DE16Dg2Fjgv7mmZYhGkcvmcQVHk6+7ly1GRbTVBgLY10CGibd41FF3ttS1jiiT+yJxQbnuhvV0gJGV5X17GPNg==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-api-design-systems": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-0.75.0.tgz", - "integrity": "sha512-i3RMF3GKR62tW+cEYkRhbcnlm0SpGh59iQb+90my8udk3eeNwblvoqk5DlBWlZwT4FFQyAMXczYzX69DahKZKw==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-api-design-systems": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-0.75.0.tgz", - "integrity": "sha512-1Pa+cBFTMJFSVKdtsk7Q8h+/rR1/7Tfa/jkS6bIHRxuebQS6eY3JXgU22FhhOiuqNpLIkQOO1qHTknIJG77K2Q==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-0.75.0.tgz", - "integrity": "sha512-iqdmbdHgZ0I1KfrqZ+/qLqsDa/CuHzF/EvhAGHAwpVFP3w1bFS1gkUfnj5iSev4IUySyFpjf1dpZjHlXunrczg==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-json": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-0.75.0.tgz", - "integrity": "sha512-uYw1E7xUvf7fEaY9UdctTWmelztPv1qVl7VnZfct1LawOgtW8/hldhUaVrBmirBI10C6piy+3tDRA/mxRo6Y1Q==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "tree-sitter": "=0.20.4", - "tree-sitter-json": "=0.20.0", - "web-tree-sitter": "=0.20.3" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-0.75.0.tgz", - "integrity": "sha512-3Rc8tucPhqGakh4Txgmu+uoASnIDvjSwOo6Vh36LQo6SRf5S86NLmLOMd+nXfiP3WnWwoQtcfvi0IHML/dQhKg==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-0.75.0.tgz", - "integrity": "sha512-UBqvU6RwGVFPLO52+N/iW+g3pgfoIOxX6wtCtaeu71IvC8klQnvRPl7DRydNM46DuDeJRYfAR7rDUO/kWxu/LQ==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-0.75.0.tgz", - "integrity": "sha512-nQAuODuSgQw3JcY4lEll2RCp7Tj5RtksLwXGBpd6ZMmy4fqsYvgmhgpqlc/T4V3OXdsB98YVdEnGrwAq5GYdag==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-0.75.0.tgz", - "integrity": "sha512-7kICmmDib+Lg/HLe7pwUeXD1CzNyLhIocvxg4wz1nBxwLAcBnLybN1sAsPTISHG/1SVh/XOPaYMyOyfN1TmkAw==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-0.75.0.tgz", - "integrity": "sha512-8d443eF60U/8lYhuzbRyloGISqCy2ypugGAKaDGPDwgldy232mQG6Izhrwqj65qj+945n3j/rD0FcwKdUZmK6w==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "tree-sitter": "=0.20.4", - "tree-sitter-yaml": "=0.5.0", - "web-tree-sitter": "=0.20.3" - } - }, - "node_modules/@swagger-api/apidom-reference": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.75.0.tgz", - "integrity": "sha512-3eqMfGaNBa3+Ao/9zrRPfxCuz9/3jag3W2XV8xuS4Xq2g3xqCEzPPUeraf6zoerk5EdXMSSoO6O8v074E4R4dg==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "axios": "^1.4.0", - "minimatch": "^7.4.3", - "process": "^0.11.10", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - }, - "optionalDependencies": { - "@swagger-api/apidom-json-pointer": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.75.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.75.0", - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0" - } - }, - "node_modules/@swagger-api/apidom-reference/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==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@swagger-api/apidom-reference/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==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@tufjs/models": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.0.tgz", - "integrity": "sha512-c8nj8BaOExmZKO2DXhDfegyhSGcG9E/mPN3U13L+/PsoWm1uaGiHHjxqSHQiasDBQwDA3aHuw9+9spYAP1qvvg==", - "dev": true, - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - }, - "engines": { - "node": "^16.14.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.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==" - }, - "node_modules/@types/hast": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz", - "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "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/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/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.12.tgz", - "integrity": "sha512-d6xjC9fJ/nSnfDeU0AMDsaJyb1iHsqCSOdi84w4u+SlN/UgQdY5tRhpMzaFYsI4mnpvgTivEaQd0yOUhAtOnEQ==", - "dev": true - }, - "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" - }, - "node_modules/@types/ramda": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.3.tgz", - "integrity": "sha512-Yh/RHkjN0ru6LVhSQtTkCRo6HXkfL9trot/2elzM/yXLJmbLm2v6kJc8yftTnwv1zvUob6TEtqI2cYjdqG3U0Q==", - "dependencies": { - "types-ramda": "^0.29.4" - } - }, - "node_modules/@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, - "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", - "dev": true - }, - "node_modules/@types/unist": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", - "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" - }, - "node_modules/@types/use-sync-external-store": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", - "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/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/@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@unhead/dom": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.3.9.tgz", - "integrity": "sha512-bTbPFjXjmk8MC0cBC+7Bgf0Mcw62gsE2XqOhMH/qQo6NP4vR2XGxqy054Y7MGurznR1JVAqxUiU3cR/oxWFk3g==", - "dev": true, - "dependencies": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/schema": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.3.9.tgz", - "integrity": "sha512-iIa0dczd2qTOxwYZbVR+iAKdlELnLTlKSFsN/YuJ/33sRi5VFa9D8TDBEPLec9gpcjB/bH0FhERfR4bb4UbRuA==", - "dev": true, - "dependencies": { - "hookable": "^5.5.3", - "zhead": "^2.0.10" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/shared": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.3.9.tgz", - "integrity": "sha512-lBXK1gzsg3XOnsOgYUVTT2RKOvM+AB0myDXkwQb0jsJB3Tc1qVOSz9JAOR+ZGrosSr7+Iv91+Fu/0E+knxaj2Q==", - "dev": true, - "dependencies": { - "@unhead/schema": "1.3.9" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/ssr": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/ssr/-/ssr-1.3.9.tgz", - "integrity": "sha512-FTt4IQOAxHiSfRM7IoJJiFnUEBH8CG5zkJOQ/LydG19QpYa9/AGOi4xvngeCr++1as51p2hWoRO6gPxSRhV8cA==", - "dev": true, - "dependencies": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/vue": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.3.9.tgz", - "integrity": "sha512-rVAsRLBc+3Y//NRmr7vmRs5yhIf65jYSvcj0V5DtDfDwql7BbGgc3VIIEvY0+EjLQuNsS5kxwm78LSPCIl/3Xw==", - "dev": true, - "dependencies": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9", - "hookable": "^5.5.3", - "unhead": "1.3.9" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - }, - "peerDependencies": { - "vue": ">=2.7 || >=3" - } - }, - "node_modules/@vercel/nft": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.23.1.tgz", - "integrity": "sha512-NE0xSmGWVhgHF1OIoir71XAd0W0C1UE3nzFyhpFiMr3rVhetww7NvM1kc41trBsPG37Bh+dE5FYCTMzM/gBu0w==", - "dev": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.5", - "@rollup/pluginutils": "^4.0.0", - "acorn": "^8.6.0", - "async-sema": "^3.1.1", - "bindings": "^1.4.0", - "estree-walker": "2.0.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.2", - "node-gyp-build": "^4.2.2", - "resolve-from": "^5.0.0" - }, - "bin": { - "nft": "out/cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@vercel/nft/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/@vercel/nft/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@vercel/nft/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/@vercel/nft/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/@vitejs/plugin-vue": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz", - "integrity": "sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==", - "dev": true, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vitejs/plugin-vue-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.2.tgz", - "integrity": "sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.22.10", - "@babel/plugin-transform-typescript": "^7.22.10", - "@vue/babel-plugin-jsx": "^1.1.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.0.0", - "vue": "^3.0.0" - } - }, - "node_modules/@vue-macros/common": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-1.7.2.tgz", - "integrity": "sha512-0/2A4kWLTCNEx+DDQKLvs7zXpfjgAbGBZ58SIvDN1DjGXhG4WaIUZtgMqzA6bvc5dNN7RaOatZYubkVumwmjWA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.10", - "@rollup/pluginutils": "^5.0.3", - "@vue/compiler-sfc": "^3.3.4", - "ast-kit": "^0.10.0", - "local-pkg": "^0.4.3", - "magic-string-ast": "^0.3.0" - }, - "engines": { - "node": ">=16.14.0" - }, - "peerDependencies": { - "vue": "^2.7.0 || ^3.2.25" - }, - "peerDependenciesMeta": { - "vue": { - "optional": true - } - } - }, - "node_modules/@vue/babel-helper-vue-transform-on": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.1.5.tgz", - "integrity": "sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==", - "dev": true - }, - "node_modules/@vue/babel-plugin-jsx": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.5.tgz", - "integrity": "sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5", - "@vue/babel-helper-vue-transform-on": "^1.1.5", - "camelcase": "^6.3.0", - "html-tags": "^3.3.1", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-plugin-jsx/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/compiler-core/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@vue/compiler-sfc/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" - }, - "node_modules/@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", - "dependencies": { - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" - } - }, - "node_modules/@vue/reactivity-transform/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@vue/reactivity-transform/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", - "dependencies": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", - "dependencies": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", - "dependencies": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" - }, - "peerDependencies": { - "vue": "3.3.4" - } - }, - "node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "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==" - }, - "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/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-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "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, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dev": true, - "dependencies": { - "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": "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/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/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/ansi-align/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/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-escapes/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/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": "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/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "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==", - "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/archiver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.0.tgz", - "integrity": "sha512-EPGa+bYaxaMiCT8DCbEDqFz8IjeBSExrJzyUOJx2FBkFJ/OZzJuso3lMSk901M50gMqXxTQcumlGajOFlXhVhw==", - "dev": true, - "dependencies": { - "archiver-utils": "^3.0.0", - "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.1.2", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/archiver-utils": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.3.tgz", - "integrity": "sha512-fXzpEZTKgBJMWy0eUT0/332CAQnJ27OJd7sGcvNZzxS2Yzg7iITivMhXOm+zUTO4vT8ZqlPCqiaLPmB8qWhWRA==", - "dev": true, - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/archiver-utils/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/archiver/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/archiver/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/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "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-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "node_modules/ast-kit": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-0.10.0.tgz", - "integrity": "sha512-8y01XClpURgvxTJmM4AY2oHa1B/6iysALB9yJM1j4ak3Z2ZsnU0ewjDZzqOHdbNdit6hC0DGZNrBqNuCrv51fQ==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.22.10", - "@rollup/pluginutils": "^5.0.3", - "pathe": "^1.1.1" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/ast-types": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ast-walker-scope": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.4.2.tgz", - "integrity": "sha512-vdCU9JvpsrxWxvJiRHAr8If8cu07LWJXDPhkqLiP4ErbN1fu/mK623QGmU4Qbn2Nq4Mx0vR/Q017B6+HcHg1aQ==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.22.4", - "@babel/types": "^7.22.4" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "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/async-sema": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", - "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", - "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==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autolinker": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", - "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", - "dependencies": { - "tslib": "^2.3.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.15", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", - "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001520", - "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/axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.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-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/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/birpc": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.13.tgz", - "integrity": "sha512-30rz9OBSJoGfiWox7dpyqoSVo6664PBEYSTfmmG1GBridUxnMysyovNpnwhaPMvjtKn3Y1UfII+HMTU0kqJFjA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/bl/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/bl/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/bl/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/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/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.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/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "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.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "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==", - "devOptional": 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": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "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-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, - "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/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/c12": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/c12/-/c12-1.4.2.tgz", - "integrity": "sha512-3IP/MuamSVRVw8W8+CHWAz9gKN4gd+voF2zm/Ln6D25C2RhytEZ1ABbC8MjKr4BR9rhoV1JQ7jJA158LDiTkLg==", - "dependencies": { - "chokidar": "^3.5.3", - "defu": "^6.1.2", - "dotenv": "^16.3.1", - "giget": "^1.1.2", - "jiti": "^1.18.2", - "mlly": "^1.4.0", - "ohash": "^1.1.2", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "rc9": "^2.1.1" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacache": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.0.tgz", - "integrity": "sha512-I7mVOPl3PUCeRub1U8YoGz2Lqv9WOBpobZ8RyWFXmReuILz+3OAyTa5oH3QPdtKZD7N0Yk00aLfzn0qvp8dZ1w==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "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": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/cacache/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/cacache/node_modules/glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "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": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001525", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz", - "integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==", - "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/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "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==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/citty": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.3.tgz", - "integrity": "sha512-tb6zTEb2BDSrzFedqFYFUKUuKNaxVJWCm7o02K4kADGkBDyyiz7D40rDMpguczdZyAN3aetd5fhpB01HkreNyg==", - "dependencies": { - "consola": "^3.2.3" - } - }, - "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" - }, - "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/clear": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clear/-/clear-0.1.0.tgz", - "integrity": "sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clipboardy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", - "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", - "dependencies": { - "arch": "^2.2.0", - "execa": "^5.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clipboardy/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "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/clipboardy/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==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/clipboardy/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==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clipboardy/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/clipboardy/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==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clipboardy/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/clipboardy/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==", - "engines": { - "node": ">=6" - } - }, - "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/cliui/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/cliui/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/cliui/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/cliui/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/cliui/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/cliui/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/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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==" - }, - "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/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "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/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/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/compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", - "dev": true, - "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "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/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/consola": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "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/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==" - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-es": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.0.0.tgz", - "integrity": "sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==" - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/core-js-pure": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.1.tgz", - "integrity": "sha512-f52QZwkFVDPf7UEQZGHKx6NYxsxmVGJe5DIvbzOdRMJlmT6yv0KDjR8rmy3ngr/t5wU54c7Sp/qIJH0ppbhVpQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "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==" - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/cross-fetch/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "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==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "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-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "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==" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.1.tgz", - "integrity": "sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==", - "dev": true, - "dependencies": { - "cssnano-preset-default": "^6.0.1", - "lilconfig": "^2.1.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz", - "integrity": "sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^4.0.0", - "postcss-calc": "^9.0.0", - "postcss-colormin": "^6.0.0", - "postcss-convert-values": "^6.0.0", - "postcss-discard-comments": "^6.0.0", - "postcss-discard-duplicates": "^6.0.0", - "postcss-discard-empty": "^6.0.0", - "postcss-discard-overridden": "^6.0.0", - "postcss-merge-longhand": "^6.0.0", - "postcss-merge-rules": "^6.0.1", - "postcss-minify-font-values": "^6.0.0", - "postcss-minify-gradients": "^6.0.0", - "postcss-minify-params": "^6.0.0", - "postcss-minify-selectors": "^6.0.0", - "postcss-normalize-charset": "^6.0.0", - "postcss-normalize-display-values": "^6.0.0", - "postcss-normalize-positions": "^6.0.0", - "postcss-normalize-repeat-style": "^6.0.0", - "postcss-normalize-string": "^6.0.0", - "postcss-normalize-timing-functions": "^6.0.0", - "postcss-normalize-unicode": "^6.0.0", - "postcss-normalize-url": "^6.0.0", - "postcss-normalize-whitespace": "^6.0.0", - "postcss-ordered-values": "^6.0.0", - "postcss-reduce-initial": "^6.0.0", - "postcss-reduce-transforms": "^6.0.0", - "postcss-svgo": "^6.0.0", - "postcss-unique-selectors": "^6.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.0.tgz", - "integrity": "sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dev": true, - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true - }, - "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" - }, - "node_modules/cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", - "dev": true - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, - "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/decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "optional": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "dependencies": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tar/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tarbz2/node_modules/file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tarbz2/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-targz/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", - "dev": true, - "dependencies": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-unzip/node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-unzip/node_modules/get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", - "dev": true, - "dependencies": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">=4.0.0" - } - }, - "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/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "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/defu": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz", - "integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==" - }, - "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/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "engines": { - "node": ">=0.10" - } - }, - "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/destr": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.1.tgz", - "integrity": "sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==" - }, - "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-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==", - "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/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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-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": "3.0.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A==" - }, - "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/dot-prop": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-8.0.2.tgz", - "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", - "dev": true, - "dependencies": { - "type-fest": "^3.8.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/drange": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", - "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", - "engines": { - "node": ">=4" - } - }, - "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/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/electron-to-chromium": { - "version": "1.4.506", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz", - "integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA==" - }, - "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/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==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "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==", - "devOptional": true, - "dependencies": { - "once": "^1.4.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/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": 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==", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-stack-parser-es": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.1.tgz", - "integrity": "sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, - "node_modules/esbuild": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.2.tgz", - "integrity": "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.19.2", - "@esbuild/android-arm64": "0.19.2", - "@esbuild/android-x64": "0.19.2", - "@esbuild/darwin-arm64": "0.19.2", - "@esbuild/darwin-x64": "0.19.2", - "@esbuild/freebsd-arm64": "0.19.2", - "@esbuild/freebsd-x64": "0.19.2", - "@esbuild/linux-arm": "0.19.2", - "@esbuild/linux-arm64": "0.19.2", - "@esbuild/linux-ia32": "0.19.2", - "@esbuild/linux-loong64": "0.19.2", - "@esbuild/linux-mips64el": "0.19.2", - "@esbuild/linux-ppc64": "0.19.2", - "@esbuild/linux-riscv64": "0.19.2", - "@esbuild/linux-s390x": "0.19.2", - "@esbuild/linux-x64": "0.19.2", - "@esbuild/netbsd-x64": "0.19.2", - "@esbuild/openbsd-x64": "0.19.2", - "@esbuild/sunos-x64": "0.19.2", - "@esbuild/win32-arm64": "0.19.2", - "@esbuild/win32-ia32": "0.19.2", - "@esbuild/win32-x64": "0.19.2" - } - }, - "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": "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/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/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "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.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "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", - "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", - "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-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/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/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/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/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/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/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-vue": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz", - "integrity": "sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "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.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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/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/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/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/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/esno": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/esno/-/esno-0.16.3.tgz", - "integrity": "sha512-6slSBEV1lMKcX13DBifvnDFpNno5WXhw4j/ff7RI0y51BZiDqEe5dNhhjhIQ3iCOQuzsm2MbVzmwqbN78BBhPg==", - "dev": true, - "dependencies": { - "tsx": "^3.2.1" - }, - "bin": { - "esno": "esno.js" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "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==", - "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==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.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/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/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": 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/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "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/externality": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/externality/-/externality-1.0.2.tgz", - "integrity": "sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==", - "dev": true, - "dependencies": { - "enhanced-resolve": "^5.14.1", - "mlly": "^1.3.0", - "pathe": "^1.1.1", - "ufo": "^1.1.2" - } - }, - "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-folder-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/fast-folder-size/-/fast-folder-size-2.2.0.tgz", - "integrity": "sha512-7VsTlT/ELl5OQ4fnckM3idvaUkdJxf6VaYn0sC43GWoRmKqvbGfpoyC4BC/imTd9CEZtlfNsEf8/ZqdfoU4Nwg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "decompress": "^4.2.1", - "https-proxy-agent": "^7.0.0" - }, - "bin": { - "fast-folder-size": "cli.js" - } - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "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-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" - }, - "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==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "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/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "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==", - "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-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dependencies": { - "micromatch": "^4.0.2" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", - "dev": true, - "dependencies": { - "flatted": "^3.2.7", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=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.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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/form-data-encoder": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.9.0.tgz", - "integrity": "sha512-rahaRMkN8P8d/tgK/BLPX+WBVM27NbvdXBxqQujBtkDAIFspaRqN7Od7lfdGQA6KAD+f82fYCLBq1ipvcu8qLw==" - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "dependencies": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "engines": { - "node": ">= 12.20" - } - }, - "node_modules/formdata-node/node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fraction.js": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.2.tgz", - "integrity": "sha512-9VLF466MqX1OUP7/d9r7/Vsvu6Hpp+taXBLmiR5x6mEYfT0BDkGVBt5TyA1aDu1WzIE1sF8F66evOFaz7iAEGQ==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "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==", - "devOptional": true - }, - "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-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gauge/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/gauge/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/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==", - "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==", - "dev": true, - "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==", - "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-port-please": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.0.2.tgz", - "integrity": "sha512-c14cAITf0E+uqdxGALvyYHwOL7UsnWcv3oDtgDAZksiVSGN87xlWVUWGZcmWQU3cICdaOxT+6LdQzUfK2ei1SA==" - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.0.tgz", - "integrity": "sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/giget": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/giget/-/giget-1.1.2.tgz", - "integrity": "sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==", - "dependencies": { - "colorette": "^2.0.19", - "defu": "^6.1.2", - "https-proxy-agent": "^5.0.1", - "mri": "^1.2.0", - "node-fetch-native": "^1.0.2", - "pathe": "^1.1.0", - "tar": "^6.1.13" - }, - "bin": { - "giget": "dist/cli.mjs" - } - }, - "node_modules/giget/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/giget/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/git-config-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", - "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", - "dev": true, - "dependencies": { - "is-ssh": "^1.4.0", - "parse-url": "^8.1.0" - } - }, - "node_modules/git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", - "dev": true, - "dependencies": { - "git-up": "^7.0.0" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "optional": true - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "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==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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": "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/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/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/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/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "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/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/gzip-size": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", - "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/h3": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/h3/-/h3-1.8.1.tgz", - "integrity": "sha512-m5rFuu+5bpwBBHqqS0zexjK+Q8dhtFRvO9JXQG0RvSPL6QrIT6vv42vuBM22SLOgGMoZYsHk0y7VPidt9s+nkw==", - "dependencies": { - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "iron-webcrypto": "^0.8.0", - "radix3": "^1.1.0", - "ufo": "^1.3.0", - "uncrypto": "^0.1.3", - "unenv": "^1.7.4" - } - }, - "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-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==", - "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==", - "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==", - "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-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" - }, - "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/highlight.js": { - "version": "11.8.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", - "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==", - "peer": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" - }, - "node_modules/hosted-git-info": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", - "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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-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-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-agent/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/http-shutdown": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.2.tgz", - "integrity": "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "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, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/httpxy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.1.4.tgz", - "integrity": "sha512-ArXKNWhU5taozl6fFnu01M9HiInAqSOw4mUp+7DY/zbTHPmS8JBqH0IC3VLovRBd9b8ZE03ztemcxzeWT6pCoA==", - "dev": true - }, - "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, - "engines": { - "node": ">=14.18.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/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==", - "optional": true, - "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/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.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/image-meta": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/image-meta/-/image-meta-0.1.1.tgz", - "integrity": "sha512-+oXiHwOEPr1IE5zY0tcBLED/CYcre15J4nwL50x3o0jxWqEkyjrusiKP3YSU+tr9fvJp33ZcP5Gpj2295g3aEw==", - "dev": true, - "engines": { - "node": ">=10.18.0" - } - }, - "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" - }, - "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/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": "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/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/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ioredis": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", - "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", - "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" - } - }, - "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/iron-webcrypto": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-0.8.2.tgz", - "integrity": "sha512-jGiwmpgTuF19Vt4hn3+AzaVFGpVZt7A1ysd5ivFel2r4aNVFwqaYa6aU6qsF1PM7b+WFivZHz3nipwUOXaOnHg==", - "funding": { - "url": "https://github.com/sponsors/brc-dd" - } - }, - "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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-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==", - "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-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "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-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "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==", - "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-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-https": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-https/-/is-https-4.0.0.tgz", - "integrity": "sha512-FeMLiqf8E5g6SdiVJsPcNZX8k4h2fBs1wp5Bb6uaNxn58ufK1axBqQZdmAQsqh0t9BuwFObybrdVJh6MKyPlyg==" - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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-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-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "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==", - "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-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-primitive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "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-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-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", - "dev": true, - "dependencies": { - "protocols": "^2.0.1" - } - }, - "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, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "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.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/is-wsl/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/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/jackspeak": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.1.tgz", - "integrity": "sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==", - "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/jiti": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", - "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.10.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.10.0.tgz", - "integrity": "sha512-hrazgRSlhzacZ69LdcKfhi3Vu13z2yFfoAzmEov3yFIJlatTdVGUW6vle1zjH8qkzdCn/qGw8rapjqsObbYXAg==", - "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/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "engines": { - "node": ">=14" - } - }, - "node_modules/js-file-download": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", - "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" - }, - "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==" - }, - "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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "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-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/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", - "dependencies": { - "jsonify": "^0.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-eslint-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.3.0.tgz", - "integrity": "sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ==", - "dependencies": { - "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - } - }, - "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==" - }, - "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/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "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/knitwork": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.0.0.tgz", - "integrity": "sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==" - }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "dev": true - }, - "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/lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lazystream/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/lazystream/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/lazystream/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/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/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "node_modules/listhen": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/listhen/-/listhen-1.4.4.tgz", - "integrity": "sha512-xoZWbfziou7xPWj9nlFXeroFTJZVIyJ6wKrLea2jxvWgMkcz/vLMoZACYHLRmcLGi5hZkcDF48tmkmv1Y6Y42Q==", - "dependencies": { - "@parcel/watcher": "^2.3.0", - "@parcel/watcher-wasm": "2.3.0", - "citty": "^0.1.3", - "clipboardy": "^3.0.0", - "consola": "^3.2.3", - "defu": "^6.1.2", - "get-port-please": "^3.0.2", - "h3": "^1.8.1", - "http-shutdown": "^1.2.2", - "jiti": "^1.19.3", - "mlly": "^1.4.1", - "node-forge": "^1.3.1", - "pathe": "^1.1.1", - "ufo": "^1.3.0", - "untun": "^0.1.2", - "uqr": "^0.1.2" - }, - "bin": { - "listen": "bin/listhen.mjs", - "listhen": "bin/listhen.mjs" - } - }, - "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "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==" - }, - "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==" - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", - "dev": true - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" - }, - "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 - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "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.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", - "dev": true - }, - "node_modules/lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", - "dev": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "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==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lowlight": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", - "dependencies": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lowlight/node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } - }, - "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==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/magic-string-ast": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-0.3.0.tgz", - "integrity": "sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.2" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/magic-string-ast/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/magicast": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.2.10.tgz", - "integrity": "sha512-Ah2qatigknxwmoYCd9hx/mmVyrRNhDKiaWZIuW4gL6dWrAGMoOpCVkQ3VpGWARtkaJVFhe8uIphcsxDzLPQUyg==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", - "recast": "^0.23.3" - } - }, - "node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/make-dir/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/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/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/make-fetch-happen/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/make-fetch-happen/node_modules/cacache": { - "version": "17.1.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", - "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^7.0.3", - "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/make-fetch-happen/node_modules/cacache/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/make-fetch-happen/node_modules/glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/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/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/make-fetch-happen/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/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/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true - }, - "node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/memory-fs/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==", - "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/memory-fs/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==" - }, - "node_modules/memory-fs/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "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==", - "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==", - "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==", - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minim": { - "version": "0.23.8", - "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", - "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", - "dependencies": { - "lodash": "^4.15.0" - }, - "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/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "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.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "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==", - "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==", - "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==" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "optional": true - }, - "node_modules/mlly": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.1.tgz", - "integrity": "sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==", - "dependencies": { - "acorn": "^8.10.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.3.0" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "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==" - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true - }, - "node_modules/nanoid": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", - "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^14 || ^16 || >=18" - } - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "optional": true - }, - "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/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/nitropack": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.6.2.tgz", - "integrity": "sha512-gzbxLIhCoQrK+NrgW5Szuo6zzFEU/bqoohimyJ8IkETI3MXlYtLphlW/UVE8pv8UQ0IJ2HzxFpZ7Ldd0+bQ35A==", - "dev": true, - "dependencies": { - "@cloudflare/kv-asset-handler": "^0.3.0", - "@netlify/functions": "^2.0.2", - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^25.0.4", - "@rollup/plugin-inject": "^5.0.3", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.4.3", - "@rollup/plugin-wasm": "^6.1.3", - "@rollup/pluginutils": "^5.0.4", - "@types/http-proxy": "^1.17.11", - "@vercel/nft": "^0.23.1", - "archiver": "^6.0.0", - "c12": "^1.4.2", - "chalk": "^5.3.0", - "chokidar": "^3.5.3", - "citty": "^0.1.3", - "consola": "^3.2.3", - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "dot-prop": "^8.0.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "etag": "^1.8.1", - "fs-extra": "^11.1.1", - "globby": "^13.2.2", - "gzip-size": "^7.0.0", - "h3": "^1.8.1", - "hookable": "^5.5.3", - "httpxy": "^0.1.4", - "is-primitive": "^3.0.1", - "jiti": "^1.19.3", - "klona": "^2.0.6", - "knitwork": "^1.0.0", - "listhen": "^1.4.2", - "magic-string": "^0.30.3", - "mime": "^3.0.0", - "mlly": "^1.4.1", - "mri": "^1.2.0", - "node-fetch-native": "^1.4.0", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "openapi-typescript": "^6.5.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "pretty-bytes": "^6.1.1", - "radix3": "^1.1.0", - "rollup": "^3.28.1", - "rollup-plugin-visualizer": "^5.9.2", - "scule": "^1.0.0", - "semver": "^7.5.4", - "serve-placeholder": "^2.0.1", - "serve-static": "^1.15.0", - "std-env": "^3.4.3", - "ufo": "^1.3.0", - "uncrypto": "^0.1.3", - "unctx": "^2.3.1", - "unenv": "^1.7.4", - "unimport": "^3.2.0", - "unstorage": "^1.9.0" - }, - "bin": { - "nitro": "dist/cli/index.mjs", - "nitropack": "dist/cli/index.mjs" - }, - "engines": { - "node": "^16.11.0 || >=17.0.0" - } - }, - "node_modules/nitropack/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nitropack/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", - "optional": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", - "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==" - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/node-fetch-native": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.4.0.tgz", - "integrity": "sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==" - }, - "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==", - "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.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "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/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/node-gyp/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/node-gyp/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/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-gyp/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/node-gyp/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/node-gyp/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/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.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==", - "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.2.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.2.0.tgz", - "integrity": "sha512-744wat5wAAHsxa4590mWO0tJ8PKxR8ORZsH9wGpQc3nWTzozMAgBN/XyqYw7mg3yqLM8dLwEnwSfKMmXAjF69g==", - "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": "11.0.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.0.tgz", - "integrity": "sha512-D8sItaQ8n6VlBUFed3DLz2sCpkabRAjaiLkTamDppvh8lmmAPirzNfBuhJd/2rlmoxZ2S9mOHmIEvzV2z2jOeA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-packlist": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.0.tgz", - "integrity": "sha512-ErAGFB5kJUciPy1mmx/C2YFbvxoJ0QJ9uwkCZOeR6CqLLISPZBOiFModAbSXnjjlwW5lOhuhXva+fURsSGJqyw==", - "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": "9.0.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz", - "integrity": "sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg==", - "dev": true, - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.0.0.tgz", - "integrity": "sha512-JFCpAPUpvpwfSydv99u85yhP68rNIxSFmDpNbNnRWKSe3gpjHnWL8v320gATwRzjtgmZ9Jfe37+ZPOLZPwz6BQ==", - "dev": true, - "dependencies": { - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.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, - "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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.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/nuxi": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/nuxi/-/nuxi-3.7.3.tgz", - "integrity": "sha512-Cg+ygRmhonE6PwAtDeKvKU/0VRqEyzmSSoJYfr0MzwIxQYrBSnLvw0z3UgJl/8MgFKjiZ5Y4wBUEiRsUw8O6uw==", - "dev": true, - "bin": { - "nuxi": "bin/nuxi.mjs", - "nuxi-ng": "bin/nuxi.mjs", - "nuxt": "bin/nuxi.mjs", - "nuxt-cli": "bin/nuxi.mjs" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/nuxt": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-3.7.0.tgz", - "integrity": "sha512-y0/xHYqwuJt20r26xezjpr74FLWR144dMpwSxZ/O2XXUrQUnyO7vHm3fEY4vi+miKbf343YMH5B78GXAELO/Vw==", - "dev": true, - "dependencies": { - "@nuxt/devalue": "^2.0.2", - "@nuxt/kit": "3.7.0", - "@nuxt/schema": "3.7.0", - "@nuxt/telemetry": "^2.4.1", - "@nuxt/ui-templates": "^1.3.1", - "@nuxt/vite-builder": "3.7.0", - "@unhead/dom": "^1.3.7", - "@unhead/ssr": "^1.3.7", - "@unhead/vue": "^1.3.7", - "@vue/shared": "^3.3.4", - "acorn": "8.10.0", - "c12": "^1.4.2", - "chokidar": "^3.5.3", - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "devalue": "^4.3.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "fs-extra": "^11.1.1", - "globby": "^13.2.2", - "h3": "^1.8.0", - "hookable": "^5.5.3", - "jiti": "^1.19.3", - "klona": "^2.0.6", - "knitwork": "^1.0.0", - "magic-string": "^0.30.3", - "mlly": "^1.4.1", - "nitropack": "^2.6.1", - "nuxi": "^3.7.0", - "nypm": "^0.3.1", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "prompts": "^2.4.2", - "scule": "^1.0.0", - "std-env": "^3.4.3", - "strip-literal": "^1.3.0", - "ufo": "^1.3.0", - "ultrahtml": "^1.3.0", - "uncrypto": "^0.1.3", - "unctx": "^2.3.1", - "unenv": "^1.7.3", - "unimport": "^3.2.0", - "unplugin": "^1.4.0", - "unplugin-vue-router": "^0.6.4", - "untyped": "^1.4.0", - "vue": "^3.3.4", - "vue-bundle-renderer": "^2.0.0", - "vue-devtools-stub": "^0.1.0", - "vue-router": "^4.2.4" - }, - "bin": { - "nuxi": "bin/nuxt.mjs", - "nuxt": "bin/nuxt.mjs" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0" - }, - "peerDependencies": { - "@parcel/watcher": "^2.1.0", - "@types/node": "^14.18.0 || >=16.10.0" - }, - "peerDependenciesMeta": { - "@parcel/watcher": { - "optional": true - }, - "@types/node": { - "optional": true - } - } - }, - "node_modules/nuxt/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nuxt/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/nypm": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.2.tgz", - "integrity": "sha512-a49F06faGtgflUVvqIkBmrYkijbbhjEoR40gzgw7I43J1p3DkHQegNcRhaGaHddIYQ0KwrmvD1W/h16jn/2puA==", - "dev": true, - "dependencies": { - "execa": "^8.0.1", - "ufo": "^1.3.0" - }, - "engines": { - "node": "^14.16.0 || >=16.10.0" - } - }, - "node_modules/nypm/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/nypm/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nypm/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/nypm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "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==", - "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/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ofetch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.3.3.tgz", - "integrity": "sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==", - "dependencies": { - "destr": "^2.0.1", - "node-fetch-native": "^1.4.0", - "ufo": "^1.3.0" - } - }, - "node_modules/ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==" - }, - "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/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": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "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/open/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/openapi-typescript": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-6.5.4.tgz", - "integrity": "sha512-ndNgrYIGSWSMrcXC8bFdx/voXRINB3dcHIm2+Sg9Tn7LJPXc7ufuaSr9E2eVucSwNxPu8oBbJxmMnxEZgT1lzA==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.3", - "fast-glob": "^3.3.1", - "js-yaml": "^4.1.0", - "supports-color": "^9.4.0", - "undici": "^5.23.0", - "yargs-parser": "^21.1.1" - }, - "bin": { - "openapi-typescript": "bin/cli.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/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, - "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": "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/pacote": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.4.tgz", - "integrity": "sha512-eGdLHrV/g5b5MtD5cTPyss+JxOlaOloSMG3UwPMAvL8ywaLJ6beONPF40K4KKl/UI6q5hTKCJq5rCu8tkF+7Dg==", - "dev": true, - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "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-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", - "dev": true, - "dependencies": { - "git-config-path": "^2.0.0", - "ini": "^1.3.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parse-git-config/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/parse-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", - "dev": true, - "dependencies": { - "protocols": "^2.0.0" - } - }, - "node_modules/parse-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", - "dev": true, - "dependencies": { - "parse-path": "^7.0.0" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=14", - "npm": ">5" - } - }, - "node_modules/patch-package/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/patch-package/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/patch-package/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/patch-package/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/patch-package/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==", - "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/patch-package/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/patch-package/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/patch-package/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/patch-package/node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/patch-package/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/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==", - "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.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", - "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==" - }, - "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/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "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/pinia": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz", - "integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==", - "dependencies": { - "@vue/devtools-api": "^6.5.0", - "vue-demi": ">=0.14.5" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "@vue/composition-api": "^1.4.0", - "typescript": ">=4.4.4", - "vue": "^2.6.14 || ^3.3.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/pinia/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "node_modules/postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", - "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-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.0.tgz", - "integrity": "sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz", - "integrity": "sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz", - "integrity": "sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz", - "integrity": "sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz", - "integrity": "sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz", - "integrity": "sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-import-resolver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-import-resolver/-/postcss-import-resolver-2.0.0.tgz", - "integrity": "sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==", - "dependencies": { - "enhanced-resolve": "^4.1.1" - } - }, - "node_modules/postcss-import-resolver/node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-import-resolver/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz", - "integrity": "sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz", - "integrity": "sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz", - "integrity": "sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz", - "integrity": "sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==", - "dev": true, - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz", - "integrity": "sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz", - "integrity": "sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz", - "integrity": "sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz", - "integrity": "sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz", - "integrity": "sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz", - "integrity": "sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz", - "integrity": "sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz", - "integrity": "sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz", - "integrity": "sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz", - "integrity": "sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz", - "integrity": "sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz", - "integrity": "sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==", - "dev": true, - "dependencies": { - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz", - "integrity": "sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz", - "integrity": "sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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-svgo": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.0.tgz", - "integrity": "sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.0.2" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz", - "integrity": "sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-url": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", - "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", - "dev": true, - "dependencies": { - "make-dir": "~3.1.0", - "mime": "~2.5.2", - "minimatch": "~3.0.4", - "xxhashjs": "~0.2.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-url/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/postcss-url/node_modules/mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-url/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/postcss-url/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "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/postcss/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/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "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": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "dev": true, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "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": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "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.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "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==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true - }, - "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==" - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" - }, - "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==", - "optional": 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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "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/radix3": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.0.tgz", - "integrity": "sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==" - }, - "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/ramda-adjunct": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-4.1.1.tgz", - "integrity": "sha512-BnCGsZybQZMDGram9y7RiryoRHS5uwx8YeGuUeDKuZuvK38XO6JJfmK85BwRWAKFA6pZ5nZBO/HBFtExVaf31w==", - "engines": { - "node": ">=0.10.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ramda-adjunct" - }, - "peerDependencies": { - "ramda": ">= 0.29.0" - } - }, - "node_modules/randexp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", - "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", - "dependencies": { - "drange": "^1.0.2", - "ret": "^0.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "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/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/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "optional": true - }, - "node_modules/rc/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==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rc9": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.1.tgz", - "integrity": "sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==", - "dependencies": { - "defu": "^6.1.2", - "destr": "^2.0.0", - "flat": "^5.0.2" - } - }, - "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-copy-to-clipboard": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", - "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", - "dependencies": { - "copy-to-clipboard": "^3.3.1", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "react": "^15.3.0 || 16 || 17 || 18" - } - }, - "node_modules/react-debounce-input": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", - "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", - "dependencies": { - "lodash.debounce": "^4", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "react": "^15.3.0 || 16 || 17 || 18" - } - }, - "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - }, - "peerDependencies": { - "react": "17.0.2" - } - }, - "node_modules/react-immutable-proptypes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", - "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", - "dependencies": { - "invariant": "^2.2.2" - }, - "peerDependencies": { - "immutable": ">=3.6.2" - } - }, - "node_modules/react-immutable-pure-component": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", - "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", - "peerDependencies": { - "immutable": ">= 2 || >= 4.0.0-rc", - "react": ">= 16.6", - "react-dom": ">= 16.6" - } - }, - "node_modules/react-inspector": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", - "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0 || ^18.0.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==" - }, - "node_modules/react-redux": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", - "integrity": "sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==", - "dependencies": { - "@babel/runtime": "^7.12.1", - "@types/hoist-non-react-statics": "^3.3.1", - "@types/use-sync-external-store": "^0.0.3", - "hoist-non-react-statics": "^3.3.2", - "react-is": "^18.0.0", - "use-sync-external-store": "^1.0.0" - }, - "peerDependencies": { - "@types/react": "^16.8 || ^17.0 || ^18.0", - "@types/react-dom": "^16.8 || ^17.0 || ^18.0", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0", - "react-native": ">=0.59", - "redux": "^4 || ^5.0.0-beta.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - }, - "redux": { - "optional": true - } - } - }, - "node_modules/react-redux/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "node_modules/react-syntax-highlighter": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "highlight.js": "^10.4.1", - "lowlight": "^1.17.0", - "prismjs": "^1.27.0", - "refractor": "^3.6.0" - }, - "peerDependencies": { - "react": ">= 0.14.0" - } - }, - "node_modules/react-syntax-highlighter/node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-package-json": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.0.tgz", - "integrity": "sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg==", - "dev": true, - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.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/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/read-package-json/node_modules/glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/read-package-json/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "devOptional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdir-glob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", - "dev": true, - "dependencies": { - "minimatch": "^5.1.0" - } - }, - "node_modules/readdir-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/readdir-glob/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/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recast": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.4.tgz", - "integrity": "sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==", - "dev": true, - "dependencies": { - "assert": "^2.0.0", - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } - }, - "node_modules/redux-immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", - "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", - "peerDependencies": { - "immutable": "^3.8.1 || ^4.0.0-rc.1" - } - }, - "node_modules/refractor": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", - "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", - "dependencies": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.27.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/refractor/node_modules/prismjs": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", - "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "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/remarkable": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", - "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", - "dependencies": { - "argparse": "^1.0.10", - "autolinker": "^3.11.0" - }, - "bin": { - "remarkable": "bin/remarkable.js" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/remarkable/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "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==", - "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==" - }, - "node_modules/reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" - }, - "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.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": "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/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/ret": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", - "engines": { - "node": ">=4" - } - }, - "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==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/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/rollup": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", - "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", - "devOptional": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-visualizer": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.9.2.tgz", - "integrity": "sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==", - "dev": true, - "dependencies": { - "open": "^8.4.0", - "picomatch": "^2.3.1", - "source-map": "^0.7.4", - "yargs": "^17.5.1" - }, - "bin": { - "rollup-plugin-visualizer": "dist/bin/cli.js" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "rollup": "2.x || 3.x" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/rollup-plugin-visualizer/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/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/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/run-applescript/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/run-applescript/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/run-applescript/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/run-applescript/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/run-applescript/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/run-applescript/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/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==", - "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==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/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/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/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "node_modules/sass": { - "version": "1.66.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", - "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", - "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/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/scule": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/scule/-/scule-1.0.0.tgz", - "integrity": "sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==" - }, - "node_modules/seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "dev": true, - "dependencies": { - "commander": "^2.8.1" - }, - "bin": { - "seek-bunzip": "bin/seek-bunzip", - "seek-table": "bin/seek-bzip-table" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "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==", - "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==" - }, - "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/serialize-error": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", - "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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-placeholder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-2.0.1.tgz", - "integrity": "sha512-rUzLlXk4uPFnbEaIz3SW8VISTxMuONas88nYWjAWaM2W9VDbt9tyFOr3lq8RhVOFrT3XISoBw8vni5una8qMnQ==", - "dev": true, - "dependencies": { - "defu": "^6.0.0" - } - }, - "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/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==", - "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==", - "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/short-unique-id": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-4.4.4.tgz", - "integrity": "sha512-oLF1NCmtbiTWl2SqdXZQbo5KM1b7axdp0RgQLq8qCBBLoq+o3A5wmLrNM6bZIh54/a8BJ3l69kTXuxwZ+XCYuw==", - "bin": { - "short-unique-id": "bin/short-unique-id", - "suid": "bin/short-unique-id" - } - }, - "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==", - "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==" - }, - "node_modules/sigstore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.1.0.tgz", - "integrity": "sha512-kPIj+ZLkyI3QaM0qX8V/nSsweYND3W448pwkDgS6CQ74MfhEkIR8ToK5Iyx46KJYRjseVcD3Rp9zAmUAj6ZjPw==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-git": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.1.tgz", - "integrity": "sha512-Ck+rcjVaE1HotraRAS8u/+xgTvToTuoMkT9/l9lvuP5jftwnYUp6DwuJzsKErHgfyRk8IB8pqGHWEbM3tLgV1w==", - "dev": true, - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, - "node_modules/sirv": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", - "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", - "dev": true, - "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/smob": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", - "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", - "dev": true - }, - "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/socks-proxy-agent/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/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "devOptional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/stampit": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz", - "integrity": "sha512-pE2org1+ZWQBnIxRPrBM2gVupkuDD0TTNIo1H6GdT/vO82NXli2z8lRE8cu/nBIHrcOCXFBAHpb9ZldrB2/qOA==" - }, - "node_modules/standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" - }, - "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/std-env": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", - "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==" - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true, - "engines": { - "node": ">=10.0.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==", - "devOptional": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "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/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/string-width-cjs/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/string-width/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/string-width/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/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-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-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "dependencies": { - "is-natural-number": "^4.0.1" - } - }, - "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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", - "dependencies": { - "acorn": "^8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/stylehacks": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.0.tgz", - "integrity": "sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/supports-color": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", - "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "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/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "node_modules/svgo": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", - "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.2.1", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/swagger-client": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.20.0.tgz", - "integrity": "sha512-5RLge2NIE1UppIT/AjUPEceT05hcBAzjiQkrXJYjpxsbFV/UDH3pp+fsrWbAeuZtgRdhNB9KDo+szLoUpzkydQ==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.13", - "@swagger-api/apidom-core": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-json-pointer": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-reference": ">=0.74.1 <1.0.0", - "cookie": "~0.5.0", - "cross-fetch": "^3.1.5", - "deepmerge": "~4.3.0", - "fast-json-patch": "^3.0.0-1", - "form-data-encoder": "^1.4.3", - "formdata-node": "^4.0.0", - "is-plain-object": "^5.0.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "qs": "^6.10.2", - "traverse": "~0.6.6", - "url": "~0.11.0" - } - }, - "node_modules/swagger-ui": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-5.4.2.tgz", - "integrity": "sha512-EQtY7Ur53JWfn6GEU64x3xQEpJ2hfg79oplboR+2dhmqUjyeDZNFL5r8zfATjlREdkKI9IqzrcdK7CP5DNaBFg==", - "hasInstallScript": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.22.10", - "@braintree/sanitize-url": "=6.0.4", - "base64-js": "^1.5.1", - "classnames": "^2.3.1", - "css.escape": "1.5.1", - "deep-extend": "0.6.0", - "dompurify": "=3.0.5", - "ieee754": "^1.2.1", - "immutable": "^3.x.x", - "js-file-download": "^0.4.12", - "js-yaml": "=4.1.0", - "lodash": "^4.17.21", - "patch-package": "^8.0.0", - "prop-types": "^15.8.1", - "randexp": "^0.5.3", - "randombytes": "^2.1.0", - "react": "=17.0.2", - "react-copy-to-clipboard": "5.1.0", - "react-debounce-input": "=3.3.0", - "react-dom": "=17.0.2", - "react-immutable-proptypes": "2.2.0", - "react-immutable-pure-component": "^2.2.0", - "react-inspector": "^6.0.1", - "react-redux": "^8.1.2", - "react-syntax-highlighter": "^15.5.0", - "redux": "^4.1.2", - "redux-immutable": "^4.0.0", - "remarkable": "^2.0.1", - "reselect": "^4.1.8", - "serialize-error": "^8.1.0", - "sha.js": "^2.4.11", - "swagger-client": "^3.20.0", - "url-parse": "^1.5.10", - "xml": "=1.0.1", - "xml-but-prettier": "^1.0.1", - "zenscroll": "^4.0.2" - } - }, - "node_modules/swagger-ui/node_modules/immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "optional": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true - }, - "node_modules/tar-fs/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==", - "optional": 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-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "dependencies": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/tar-stream/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/tar-stream/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/tar-stream/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/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==", - "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==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "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==" - }, - "node_modules/terser": { - "version": "5.19.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.3.tgz", - "integrity": "sha512-pQzJ9UJzM0IgmT4FAtYI6+VqFf0lj/to58AV0Xfgg0Up37RyPG7Al+1cepC6/BVuAxR9oNb41/DL4DEoHJvTdg==", - "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/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/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/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "dev": true - }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "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==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "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/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tree-sitter": { - "version": "0.20.4", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz", - "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "nan": "^2.17.0", - "prebuild-install": "^7.1.1" - } - }, - "node_modules/tree-sitter-json": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.0.tgz", - "integrity": "sha512-PteOLH+Tx6Bz4ZA/d40/DbkiSXXRM/gKahhHI8hQ1lWNfFvdknnz9k3Mz84ol5srRyLboJ8wp8GSkhZ6ht9EGQ==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "nan": "^2.14.1" - } - }, - "node_modules/tree-sitter-yaml": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz", - "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "nan": "^2.14.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", - "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-toolbelt": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" - }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/tsx": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz", - "integrity": "sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==", - "dev": true, - "dependencies": { - "@esbuild-kit/cjs-loader": "^2.4.2", - "@esbuild-kit/core-utils": "^3.0.0", - "@esbuild-kit/esm-loader": "^2.5.5" - }, - "bin": { - "tsx": "dist/cli.js" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tuf-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.1.0.tgz", - "integrity": "sha512-eD7YPPjVlMzdggrOeE8zwoegUaG/rt6Bt3jwoQPunRiNVzgcCE009UDFJKJjG+Gk9wFu6W/Vi+P5d/5QpdD9jA==", - "dev": true, - "dependencies": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/tuf-js/node_modules/make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.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==", - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "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": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/types-ramda": { - "version": "0.29.4", - "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.4.tgz", - "integrity": "sha512-XO/820iRsCDwqLjE8XE+b57cVGPyk1h+U9lBGpDWvbEky+NQChvHVwaKM05WnW1c5z3EVQh8NhXFmh2E/1YazQ==", - "dependencies": { - "ts-toolbelt": "^9.6.0" - } - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "devOptional": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", - "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==" - }, - "node_modules/ultrahtml": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.4.0.tgz", - "integrity": "sha512-2SbudS8oD4GNq4en+3ivp25JTCwP5O2soJhIBxGJrjojjLVaLcP84xVU6Xdf0wKMhZvr68rTtrXtO6uvEr2llQ==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "node_modules/uncrypto": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", - "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==" - }, - "node_modules/unctx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.3.1.tgz", - "integrity": "sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==", - "dependencies": { - "acorn": "^8.8.2", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.0", - "unplugin": "^1.3.1" - } - }, - "node_modules/unctx/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", - "dev": true, - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/unenv": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.7.4.tgz", - "integrity": "sha512-fjYsXYi30It0YCQYqLOcT6fHfMXsBr2hw9XC7ycf8rTG7Xxpe3ZssiqUnD0khrjiZEmkBXWLwm42yCSCH46fMw==", - "dependencies": { - "consola": "^3.2.3", - "defu": "^6.1.2", - "mime": "^3.0.0", - "node-fetch-native": "^1.4.0", - "pathe": "^1.1.1" - } - }, - "node_modules/unhead": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/unhead/-/unhead-1.3.9.tgz", - "integrity": "sha512-vzWZJW8l6dlNM5egJs3c7NMHWZ+iw2x7jCZtU2rrhwFINlKCaA3J42fvOeDxx6t5QR9dfZ96HF2AeNlCcPT+bQ==", - "dev": true, - "dependencies": { - "@unhead/dom": "1.3.9", - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9", - "hookable": "^5.5.3" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/unimport": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.2.0.tgz", - "integrity": "sha512-9buxPxkNwxwxAlH/RfOFHxtQTUrlmBGi9Ai9HezY2yYbkoOhgJTYPI6+WqxI1EZphoM9cw1SHoCFRkXSb8/fjQ==", - "dependencies": { - "@rollup/pluginutils": "^5.0.3", - "escape-string-regexp": "^5.0.0", - "fast-glob": "^3.3.1", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.3", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "scule": "^1.0.0", - "strip-literal": "^1.3.0", - "unplugin": "^1.4.0" - } - }, - "node_modules/unimport/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==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unimport/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unplugin": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.4.0.tgz", - "integrity": "sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==", - "dependencies": { - "acorn": "^8.9.0", - "chokidar": "^3.5.3", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.5.0" - } - }, - "node_modules/unplugin-vue-router": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/unplugin-vue-router/-/unplugin-vue-router-0.6.4.tgz", - "integrity": "sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.5", - "@rollup/pluginutils": "^5.0.2", - "@vue-macros/common": "^1.3.1", - "ast-walker-scope": "^0.4.1", - "chokidar": "^3.5.3", - "fast-glob": "^3.2.12", - "json5": "^2.2.3", - "local-pkg": "^0.4.3", - "mlly": "^1.2.0", - "pathe": "^1.1.0", - "scule": "^1.0.0", - "unplugin": "^1.3.1", - "yaml": "^2.2.2" - }, - "peerDependencies": { - "vue-router": "^4.1.0" - }, - "peerDependenciesMeta": { - "vue-router": { - "optional": true - } - } - }, - "node_modules/unraw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", - "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==" - }, - "node_modules/unstorage": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.9.0.tgz", - "integrity": "sha512-VpD8ZEYc/le8DZCrny3bnqKE4ZjioQxBRnWE+j5sGNvziPjeDlaS1NaFFHzl/kkXaO3r7UaF8MGQrs14+1B4pQ==", - "dependencies": { - "anymatch": "^3.1.3", - "chokidar": "^3.5.3", - "destr": "^2.0.1", - "h3": "^1.7.1", - "ioredis": "^5.3.2", - "listhen": "^1.2.2", - "lru-cache": "^10.0.0", - "mri": "^1.2.0", - "node-fetch-native": "^1.2.0", - "ofetch": "^1.1.1", - "ufo": "^1.2.0" - }, - "peerDependencies": { - "@azure/app-configuration": "^1.4.1", - "@azure/cosmos": "^3.17.3", - "@azure/data-tables": "^13.2.2", - "@azure/identity": "^3.2.3", - "@azure/keyvault-secrets": "^4.7.0", - "@azure/storage-blob": "^12.14.0", - "@capacitor/preferences": "^5.0.0", - "@planetscale/database": "^1.8.0", - "@upstash/redis": "^1.22.0", - "@vercel/kv": "^0.2.2", - "idb-keyval": "^6.2.1" - }, - "peerDependenciesMeta": { - "@azure/app-configuration": { - "optional": true - }, - "@azure/cosmos": { - "optional": true - }, - "@azure/data-tables": { - "optional": true - }, - "@azure/identity": { - "optional": true - }, - "@azure/keyvault-secrets": { - "optional": true - }, - "@azure/storage-blob": { - "optional": true - }, - "@capacitor/preferences": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/kv": { - "optional": true - }, - "idb-keyval": { - "optional": true - } - } - }, - "node_modules/unstorage/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "engines": { - "node": "14 || >=16.14" - } - }, - "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/untun": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/untun/-/untun-0.1.2.tgz", - "integrity": "sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q==", - "dependencies": { - "citty": "^0.1.3", - "consola": "^3.2.3", - "pathe": "^1.1.1" - }, - "bin": { - "untun": "bin/untun.mjs" - } - }, - "node_modules/untyped": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.4.0.tgz", - "integrity": "sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==", - "dependencies": { - "@babel/core": "^7.22.9", - "@babel/standalone": "^7.22.9", - "@babel/types": "^7.22.5", - "defu": "^6.1.2", - "jiti": "^1.19.1", - "mri": "^1.2.0", - "scule": "^1.0.0" - }, - "bin": { - "untyped": "dist/cli.mjs" - } - }, - "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==", - "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/uqr": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", - "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==" - }, - "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/url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.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/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", - "dev": true - }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "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/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/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", - "dev": true, - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.33.0.tgz", - "integrity": "sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-plugin-checker": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.6.2.tgz", - "integrity": "sha512-YvvvQ+IjY09BX7Ab+1pjxkELQsBd4rPhWNw8WLBeFVxu/E7O+n6VYAqNsKdK/a2luFlX/sMpoWdGFfg4HvwdJQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "ansi-escapes": "^4.3.0", - "chalk": "^4.1.1", - "chokidar": "^3.5.1", - "commander": "^8.0.0", - "fast-glob": "^3.2.7", - "fs-extra": "^11.1.0", - "lodash.debounce": "^4.0.8", - "lodash.pick": "^4.4.0", - "npm-run-path": "^4.0.1", - "semver": "^7.5.0", - "strip-ansi": "^6.0.0", - "tiny-invariant": "^1.1.0", - "vscode-languageclient": "^7.0.0", - "vscode-languageserver": "^7.0.0", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-uri": "^3.0.2" - }, - "engines": { - "node": ">=14.16" - }, - "peerDependencies": { - "eslint": ">=7", - "meow": "^9.0.0", - "optionator": "^0.9.1", - "stylelint": ">=13", - "typescript": "*", - "vite": ">=2.0.0", - "vls": "*", - "vti": "*", - "vue-tsc": ">=1.3.9" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "meow": { - "optional": true - }, - "optionator": { - "optional": true - }, - "stylelint": { - "optional": true - }, - "typescript": { - "optional": true - }, - "vls": { - "optional": true - }, - "vti": { - "optional": true - }, - "vue-tsc": { - "optional": true - } - } - }, - "node_modules/vite-plugin-checker/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/vite-plugin-checker/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/vite-plugin-checker/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/vite-plugin-checker/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/vite-plugin-checker/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/vite-plugin-checker/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/vite-plugin-checker/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/vite-plugin-checker/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/vite-plugin-inspect": { - "version": "0.7.38", - "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.7.38.tgz", - "integrity": "sha512-+p6pJVtBOLGv+RBrcKAFUdx+euizg0bjL35HhPyM0MjtKlqoC5V9xkCmO9Ctc8JrTyXqODbHqiLWJKumu5zJ7g==", - "dev": true, - "dependencies": { - "@antfu/utils": "^0.7.5", - "@rollup/pluginutils": "^5.0.2", - "debug": "^4.3.4", - "error-stack-parser-es": "^0.1.1", - "fs-extra": "^11.1.1", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "sirv": "^2.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^3.1.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "@nuxt/kit": { - "optional": true - } - } - }, - "node_modules/vite-plugin-inspect/node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-inspect/node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-inspector": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-3.6.0.tgz", - "integrity": "sha512-Fi+9JaMx/reuic+MWbrdw8g5TwZM5a/BmdBT8OKKZi3rK4Qw3wND9smT+Ld+Daitbgly17uvuCiull2KV/hEBQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.21.3", - "@vue/babel-plugin-jsx": "^1.1.1", - "@vue/compiler-dom": "^3.2.47", - "esno": "^0.16.3", - "kolorist": "^1.7.0", - "magic-string": "^0.30.0", - "shell-quote": "^1.8.0" - }, - "peerDependencies": { - "vite": "^3.0.0-0 || ^4.0.0-0" - } - }, - "node_modules/vite-plugin-vue-inspector/node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/vscode-jsonrpc": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", - "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", - "dev": true, - "engines": { - "node": ">=8.0.0 || >=10.0.0" - } - }, - "node_modules/vscode-languageclient": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", - "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", - "dev": true, - "dependencies": { - "minimatch": "^3.0.4", - "semver": "^7.3.4", - "vscode-languageserver-protocol": "3.16.0" - }, - "engines": { - "vscode": "^1.52.0" - } - }, - "node_modules/vscode-languageserver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", - "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", - "dev": true, - "dependencies": { - "vscode-languageserver-protocol": "3.16.0" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", - "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", - "dev": true, - "dependencies": { - "vscode-jsonrpc": "6.0.0", - "vscode-languageserver-types": "3.16.0" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz", - "integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==", - "dev": true - }, - "node_modules/vscode-languageserver-types": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", - "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", - "dev": true - }, - "node_modules/vscode-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", - "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==", - "dev": true - }, - "node_modules/vue": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", - "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/vue-bundle-renderer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vue-bundle-renderer/-/vue-bundle-renderer-2.0.0.tgz", - "integrity": "sha512-oYATTQyh8XVkUWe2kaKxhxKVuuzK2Qcehe+yr3bGiaQAhK3ry2kYE4FWOfL+KO3hVFwCdLmzDQTzYhTi9C+R2A==", - "dev": true, - "dependencies": { - "ufo": "^1.2.0" - } - }, - "node_modules/vue-devtools-stub": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz", - "integrity": "sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==", - "dev": true - }, - "node_modules/vue-eslint-parser": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz", - "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/vue-i18n": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz", - "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", - "devOptional": true, - "dependencies": { - "@intlify/core-base": "9.2.2", - "@intlify/shared": "9.2.2", - "@intlify/vue-devtools": "9.2.2", - "@vue/devtools-api": "^6.2.1" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/vue-i18n/node_modules/@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/vue-router": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz", - "integrity": "sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==", - "devOptional": true, - "dependencies": { - "@vue/devtools-api": "^6.5.0" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, - "node_modules/vuetify": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.3.15.tgz", - "integrity": "sha512-n7GYBO31k8vA9UfvRwLNyBlkq1WoN3IJ9wNnIBFeV4axleSjFAzzR4WUw7rgj6Ba3q6N2hxXoyxJM21tseQTfQ==", - "engines": { - "node": "^12.20 || >=14.13" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/johnleider" - }, - "peerDependencies": { - "typescript": ">=4.7", - "vite-plugin-vuetify": "^1.0.0-alpha.12", - "vue": "^3.2.0", - "vue-i18n": "^9.0.0", - "webpack-plugin-vuetify": "^2.0.0-alpha.11" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vite-plugin-vuetify": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "webpack-plugin-vuetify": { - "optional": true - } - } - }, - "node_modules/wait-on": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.0.1.tgz", - "integrity": "sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==", - "dev": true, - "dependencies": { - "axios": "^0.27.2", - "joi": "^17.7.0", - "lodash": "^4.17.21", - "minimist": "^1.2.7", - "rxjs": "^7.8.0" - }, - "bin": { - "wait-on": "bin/wait-on" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/wait-on/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==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/web-tree-sitter": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz", - "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==", - "optional": true - }, - "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==" - }, - "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==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-virtual-modules": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz", - "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==" - }, - "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==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "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/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-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "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/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/wide-align/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/wide-align/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/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dev": true, - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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-cjs/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/wrap-ansi-cjs/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/wrap-ansi/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/wrap-ansi/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/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==", - "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/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" - }, - "node_modules/xml-but-prettier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", - "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", - "dependencies": { - "repeat-string": "^1.5.2" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "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/xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "dev": true, - "dependencies": { - "cuint": "^0.2.2" - } - }, - "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": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/yaml-eslint-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", - "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", - "dependencies": { - "eslint-visitor-keys": "^3.0.0", - "lodash": "^4.17.21", - "yaml": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/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/yargs/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/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/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/zenscroll": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", - "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==" - }, - "node_modules/zhead": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/zhead/-/zhead-2.0.10.tgz", - "integrity": "sha512-irug8fXNKjqazkA27cFQs7C6/ZD3qNiEzLC56kDyzQART/Z9GMGfg8h2i6fb9c8ZWnIx/QgOgFJxK3A/CYHG0g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", - "dev": true, - "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/zip-stream/node_modules/archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/zip-stream/node_modules/archiver-utils/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/zip-stream/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/zip-stream/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/zip-stream/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" - } - } - }, - "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==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@antfu/utils": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.6.tgz", - "integrity": "sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==", - "dev": true - }, - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.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==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==" - }, - "@babel/core": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", - "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.11", - "@babel/parser": "^7.22.11", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", - "requires": { - "@babel/types": "^7.22.10", - "@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-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", - "requires": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", - "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", - "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.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@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==" - }, - "@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==", - "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==", - "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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", - "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.6", - "@babel/helper-validator-identifier": "^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-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", - "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/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==", - "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.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==", - "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==" - }, - "@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==" - }, - "@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==" - }, - "@babel/helpers": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", - "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", - "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" - } - }, - "@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.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==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==" - }, - "@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-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", - "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz", - "integrity": "sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.22.5" - } - }, - "@babel/runtime": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", - "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/runtime-corejs3": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.22.11.tgz", - "integrity": "sha512-NhfzUbdWbiE6fCFypbWCPu6AR8xre31EOPF7wwAIJEvGQ2avov04eymayWinCuyXmV1b0+jzoXP/HYzzUYdvwg==", - "requires": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/standalone": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.22.14.tgz", - "integrity": "sha512-i61lDNe0nRm44nZj05g+1HNb0EVfDGaTI6PkoeUMUSel3GTG6T1OM3BdjZIXghnnFB8bSWbmfS1lkBQgNUdu5w==" - }, - "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", - "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", - "requires": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@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.11", - "@babel/types": "^7.22.11", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - } - } - }, - "@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" - } - }, - "@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "@cloudflare/kv-asset-handler": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.0.tgz", - "integrity": "sha512-9CB/MKf/wdvbfkUdfrj+OkEwZ5b7rws0eogJ4293h+7b6KX5toPwym+VQKmILafNB9YiehqY0DlNrDcDhdWHSQ==", - "dev": true, - "requires": { - "mime": "^3.0.0" - } - }, - "@esbuild-kit/cjs-loader": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz", - "integrity": "sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==", - "dev": true, - "requires": { - "@esbuild-kit/core-utils": "^3.0.0", - "get-tsconfig": "^4.4.0" - } - }, - "@esbuild-kit/core-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.2.2.tgz", - "integrity": "sha512-Ub6LaRaAgF80dTSzUdXpFLM1pVDdmEVB9qb5iAzSpyDlX/mfJTFGOnZ516O05p5uWWteNviMKi4PAyEuRxI5gA==", - "dev": true, - "requires": { - "esbuild": "~0.18.20", - "source-map-support": "^0.5.21" - }, - "dependencies": { - "@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "dev": true, - "optional": true - }, - "esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - } - } - }, - "@esbuild-kit/esm-loader": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz", - "integrity": "sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==", - "dev": true, - "requires": { - "@esbuild-kit/core-utils": "^3.0.0", - "get-tsconfig": "^4.4.0" - } - }, - "@esbuild/android-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.2.tgz", - "integrity": "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz", - "integrity": "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.2.tgz", - "integrity": "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz", - "integrity": "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz", - "integrity": "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz", - "integrity": "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz", - "integrity": "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz", - "integrity": "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz", - "integrity": "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz", - "integrity": "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz", - "integrity": "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz", - "integrity": "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz", - "integrity": "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz", - "integrity": "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz", - "integrity": "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz", - "integrity": "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz", - "integrity": "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz", - "integrity": "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz", - "integrity": "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz", - "integrity": "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz", - "integrity": "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz", - "integrity": "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==", - "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.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "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" - } - }, - "@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", - "dev": true - }, - "@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" - } - }, - "@highlightjs/vue-plugin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz", - "integrity": "sha512-E+bmk4ncca+hBEYRV2a+1aIzIV0VSY/e5ArjpuSN9IO7wBJrzUE2u4ESCwrbQD7sAy+jWQjkV5qCCWgc+pu7CQ==", - "requires": {} - }, - "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "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 - }, - "@intlify/bundle-utils": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.1.0.tgz", - "integrity": "sha512-Q88Wl2T8oaRXls8Yr6l807jZM88mceJvK7QS6gKdU8/pf3gTpU9XmcYORDgAv6h5WKQMoaFjNVf5+SWLfTAysA==", - "requires": { - "@intlify/message-compiler": "9.3.0-beta.27", - "@intlify/shared": "9.3.0-beta.27", - "acorn": "^8.8.2", - "escodegen": "^2.0.0", - "estree-walker": "^2.0.2", - "jsonc-eslint-parser": "^2.3.0", - "magic-string": "^0.30.0", - "mlly": "^1.2.0", - "source-map-js": "^1.0.1", - "yaml-eslint-parser": "^1.2.2" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.27.tgz", - "integrity": "sha512-hPMsmVCs+ZUVHHU5VORG6LopzXZT7zmyVNqc9OQG80YpA/N4lT/pkJ4B6DTNIsv2C7mwfGM7RdK+0qPki43YgA==" - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "@intlify/core-base": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz", - "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", - "devOptional": true, - "requires": { - "@intlify/devtools-if": "9.2.2", - "@intlify/message-compiler": "9.2.2", - "@intlify/shared": "9.2.2", - "@intlify/vue-devtools": "9.2.2" - }, - "dependencies": { - "@intlify/message-compiler": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", - "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", - "devOptional": true, - "requires": { - "@intlify/shared": "9.2.2", - "source-map": "0.6.1" - } - }, - "@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true - } - } - }, - "@intlify/devtools-if": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", - "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", - "devOptional": true, - "requires": { - "@intlify/shared": "9.2.2" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true - } - } - }, - "@intlify/message-compiler": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.27.tgz", - "integrity": "sha512-GC8rSbd7V67Zu+a9Z0bpV4riBek11YCURJU50YaEhV4Ub2JHEPtoYxK5r2eIsq/kp+M2hJyGLiC4NJUrGa2VwQ==", - "requires": { - "@intlify/shared": "9.3.0-beta.27", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.3.0-beta.27", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.27.tgz", - "integrity": "sha512-hPMsmVCs+ZUVHHU5VORG6LopzXZT7zmyVNqc9OQG80YpA/N4lT/pkJ4B6DTNIsv2C7mwfGM7RdK+0qPki43YgA==" - } - } - }, - "@intlify/shared": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.26.tgz", - "integrity": "sha512-RpCtfSYIg4tSskrazTr5+WCHyw6qpgwdIxC+x3nCnrPGxyk+en9FoSbadVfx/w7uDTdyhKslEw4d2+qhNc0s4Q==" - }, - "@intlify/unplugin-vue-i18n": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-0.12.3.tgz", - "integrity": "sha512-0riPtSfTM58JmGNMmJho/aHD2z3K24BESYAmkLvKlo61/LbaPvnjYU1DbSbJEm6bSjE2oEjUj+di3QaYxXei/w==", - "requires": { - "@intlify/bundle-utils": "^7.0.2", - "@intlify/shared": "9.3.0-beta.24", - "@rollup/pluginutils": "^5.0.2", - "@vue/compiler-sfc": "^3.2.47", - "debug": "^4.3.3", - "fast-glob": "^3.2.12", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "pathe": "^1.0.0", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2", - "unplugin": "^1.1.0" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.3.0-beta.24", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.24.tgz", - "integrity": "sha512-AKxJ8s7eKIQWkNaf4wyyoLRwf4puCuQgjSChlDJm5JBEt6T8HGgnYTJLRXu6LD/JACn3Qwu6hM/XRX1c9yvjmQ==" - } - } - }, - "@intlify/vue-devtools": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", - "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", - "devOptional": true, - "requires": { - "@intlify/core-base": "9.2.2", - "@intlify/shared": "9.2.2" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true - } - } - }, - "@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" - }, - "@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 - }, - "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" - } - } - } - }, - "@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==", - "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.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@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==" - }, - "@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==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, - "requires": { - "debug": "^4.1.1" - } - }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "requires": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "@mdi/font": { - "version": "7.2.96", - "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.2.96.tgz", - "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w==" - }, - "@mizchi/sucrase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@mizchi/sucrase/-/sucrase-4.1.0.tgz", - "integrity": "sha512-AaN8HSGdXmNqEqIb0IQPIQL+MI/8Xr1QTOcVnA6k0u2afqfYhlre05hSxRybOFpq34oF8EqMTrYovYZxEV1FLw==", - "requires": { - "lines-and-columns": "^1.1.6" - } - }, - "@netlify/functions": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.0.2.tgz", - "integrity": "sha512-goWRtaIPUK/q47qLYtfGGj7HgJIRaT0snw7zZ0yeoNTfQfCRwQwvRrMAsXkCsCtq2N2Oo81L26SpkMxEQMk9hg==", - "dev": true, - "requires": { - "@netlify/serverless-functions-api": "1.7.3", - "is-promise": "^4.0.0" - } - }, - "@netlify/node-cookies": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", - "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==", - "dev": true - }, - "@netlify/serverless-functions-api": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.7.3.tgz", - "integrity": "sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==", - "dev": true, - "requires": { - "@netlify/node-cookies": "^0.1.0", - "urlpattern-polyfill": "8.0.2" - } - }, - "@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==", - "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==" - }, - "@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==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.1.0.tgz", - "integrity": "sha512-/HFJP3a/DzgIg+6TWVee3bQmnBcWeKKYE9DKQqS8SWpAV8oYDTn/zkDM8iQ7bWI6kDDgNfHOlEFZZpN/UXMwig==", - "dev": true, - "requires": { - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" - }, - "dependencies": { - "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, - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - }, - "socks-proxy-agent": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz", - "integrity": "sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==", - "dev": true, - "requires": { - "agent-base": "^7.0.1", - "debug": "^4.3.4", - "socks": "^2.7.1" - } - } - } - }, - "@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": "5.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.3.tgz", - "integrity": "sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw==", - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - }, - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - }, - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@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": "7.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz", - "integrity": "sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ==", - "dev": true, - "requires": { - "which": "^4.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - }, - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@npmcli/run-script": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.1.tgz", - "integrity": "sha512-Od/JMrgkjZ8alyBE0IzeqZDiF1jgMez9Gkc/OYrCkHHiXNwM0wc6s7+h+xM7kYDZkS0tAoOLr9VvygyE5+2F7g==", - "dev": true, - "requires": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^4.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - }, - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@nuxt/devalue": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz", - "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==", - "dev": true - }, - "@nuxt/devtools": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools/-/devtools-0.8.2.tgz", - "integrity": "sha512-E3ycLEkqTlXpdz3P7lJRMdB4AnC4tzALM6N6eCUskSCtUQfF57mjk0k7z1duHIjU8xTIFm6gnsotJnR/n6/B0g==", - "dev": true, - "requires": { - "@antfu/utils": "^0.7.6", - "@nuxt/devtools-kit": "0.8.2", - "@nuxt/devtools-wizard": "0.8.2", - "@nuxt/kit": "^3.7.0", - "birpc": "^0.2.13", - "boxen": "^7.1.1", - "consola": "^3.2.3", - "error-stack-parser-es": "^0.1.1", - "execa": "^7.2.0", - "fast-folder-size": "^2.2.0", - "fast-glob": "^3.3.1", - "flatted": "^3.2.7", - "get-port-please": "^3.0.2", - "global-dirs": "^3.0.1", - "h3": "^1.8.1", - "hookable": "^5.5.3", - "image-meta": "^0.1.1", - "is-installed-globally": "^0.4.0", - "launch-editor": "^2.6.0", - "local-pkg": "^0.4.3", - "magicast": "^0.2.10", - "nypm": "^0.3.1", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "pacote": "^17.0.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "picocolors": "^1.0.0", - "pkg-types": "^1.0.3", - "rc9": "^2.1.1", - "semver": "^7.5.4", - "simple-git": "^3.19.1", - "sirv": "^2.0.3", - "unimport": "^3.2.0", - "vite-plugin-inspect": "^0.7.38", - "vite-plugin-vue-inspector": "^3.6.0", - "wait-on": "^7.0.1", - "which": "^3.0.1", - "ws": "^8.13.0" - } - }, - "@nuxt/devtools-kit": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-0.8.2.tgz", - "integrity": "sha512-GEqpBxa/ojfhAM9HN5L/OzCADpfH9nDbcC7INHFgao6KuAu6JclTpcuV6VZP6LthsETBsd2cKAt93WY+vEJnnQ==", - "dev": true, - "requires": { - "@nuxt/kit": "^3.7.0", - "@nuxt/schema": "^3.7.0", - "execa": "^7.2.0" - } - }, - "@nuxt/devtools-wizard": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@nuxt/devtools-wizard/-/devtools-wizard-0.8.2.tgz", - "integrity": "sha512-d6uT98di8T6Bn/aQpRwMZPjUtrdBmjNAdrDS8s3e2SDy13HVMAsEVbJWKtfYV8oN8vrSkB0Z6tGgdbKyOLyiuw==", - "dev": true, - "requires": { - "consola": "^3.2.3", - "diff": "^5.1.0", - "execa": "^7.2.0", - "global-dirs": "^3.0.1", - "magicast": "^0.2.10", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "pkg-types": "^1.0.3", - "prompts": "^2.4.2", - "rc9": "^2.1.1", - "semver": "^7.5.4" - } - }, - "@nuxt/eslint-config": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@nuxt/eslint-config/-/eslint-config-0.2.0.tgz", - "integrity": "sha512-NeJX8TLcnNAjQFiDs3XhP+9CHKK8jaKsP7eUyCSrQdgY7nqWe7VJx64lwzx5FTT4cW3RHMEyH+Y0qzLGYYoa/A==", - "dev": true, - "requires": { - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/eslint-plugin": "^6.5.0", - "@typescript-eslint/parser": "^6.5.0", - "eslint-plugin-vue": "^9.17.0", - "typescript": "^5.2.2" - } - }, - "@nuxt/kit": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.7.0.tgz", - "integrity": "sha512-bsPRb2NTLHRacjyybhhA3pZFIqo2pxB6bcP4FQDuzlGzVTI5PtJzbfNpkmQC7q+LZt8K0pNlxKVGisDvZctk6w==", - "requires": { - "@nuxt/schema": "3.7.0", - "c12": "^1.4.2", - "consola": "^3.2.3", - "defu": "^6.1.2", - "globby": "^13.2.2", - "hash-sum": "^2.0.0", - "ignore": "^5.2.4", - "jiti": "^1.19.3", - "knitwork": "^1.0.0", - "mlly": "^1.4.1", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "scule": "^1.0.0", - "semver": "^7.5.4", - "ufo": "^1.3.0", - "unctx": "^2.3.1", - "unimport": "^3.2.0", - "untyped": "^1.4.0" - } - }, - "@nuxt/schema": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-3.7.0.tgz", - "integrity": "sha512-fNRAubny1x6rIibm/HcacnEGeAQri/FkJ5ei24aY4YjQ12+xDfi7bljfFr6C2+CrEGc1beYd4OQcUqXqEpz5+g==", - "requires": { - "@nuxt/ui-templates": "^1.3.1", - "defu": "^6.1.2", - "hookable": "^5.5.3", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "postcss-import-resolver": "^2.0.0", - "std-env": "^3.4.3", - "ufo": "^1.3.0", - "unimport": "^3.2.0", - "untyped": "^1.4.0" - } - }, - "@nuxt/telemetry": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@nuxt/telemetry/-/telemetry-2.4.1.tgz", - "integrity": "sha512-Cj+4sXjO5pZNW2sX7Y+djYpf4pZwgYF3rV/YHLWIOq9nAjo2UcDXjh1z7qnhkoUkvJN3lHnvhnCNhfAioe6k/A==", - "dev": true, - "requires": { - "@nuxt/kit": "^3.6.5", - "chalk": "^5.3.0", - "ci-info": "^3.8.0", - "consola": "^3.2.3", - "create-require": "^1.1.1", - "defu": "^6.1.2", - "destr": "^2.0.0", - "dotenv": "^16.3.1", - "fs-extra": "^11.1.1", - "git-url-parse": "^13.1.0", - "is-docker": "^3.0.0", - "jiti": "^1.19.1", - "mri": "^1.2.0", - "nanoid": "^4.0.2", - "node-fetch": "^3.3.1", - "ofetch": "^1.1.1", - "parse-git-config": "^3.0.0", - "pathe": "^1.1.1", - "rc9": "^2.1.1", - "std-env": "^3.3.3" - } - }, - "@nuxt/ui-templates": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@nuxt/ui-templates/-/ui-templates-1.3.1.tgz", - "integrity": "sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==" - }, - "@nuxt/vite-builder": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@nuxt/vite-builder/-/vite-builder-3.7.0.tgz", - "integrity": "sha512-bRJy3KarHrFm/xLGHoHeZyqI/h6c4UFRCF5ngRZ/R9uebJEHuL4UhAioxDLTFu7D0vEeK7XaDgx6+NPLhBg51g==", - "dev": true, - "requires": { - "@nuxt/kit": "3.7.0", - "@rollup/plugin-replace": "^5.0.2", - "@vitejs/plugin-vue": "^4.3.3", - "@vitejs/plugin-vue-jsx": "^3.0.2", - "autoprefixer": "^10.4.15", - "clear": "^0.1.0", - "consola": "^3.2.3", - "cssnano": "^6.0.1", - "defu": "^6.1.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "externality": "^1.0.2", - "fs-extra": "^11.1.1", - "get-port-please": "^3.0.1", - "h3": "^1.8.0", - "knitwork": "^1.0.0", - "magic-string": "^0.30.3", - "mlly": "^1.4.1", - "ohash": "^1.1.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "postcss": "^8.4.28", - "postcss-import": "^15.1.0", - "postcss-url": "^10.1.3", - "rollup-plugin-visualizer": "^5.9.2", - "std-env": "^3.4.3", - "strip-literal": "^1.3.0", - "ufo": "^1.3.0", - "unplugin": "^1.4.0", - "vite": "^4.4.9", - "vite-node": "^0.33.0", - "vite-plugin-checker": "^0.6.2", - "vue-bundle-renderer": "^2.0.0" - }, - "dependencies": { - "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 - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "@nuxtjs/i18n": { - "version": "8.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@nuxtjs/i18n/-/i18n-8.0.0-rc.3.tgz", - "integrity": "sha512-TrJF7OxCK1CcEnKQHcP3VjVnb0K22OdMxdbWOk/kUzD9DX6+hrcrfrQD6W7xDA5pnEhBnsw1pLT2I+DYVpK/gw==", - "requires": { - "@intlify/shared": "9.3.0-beta.26", - "@intlify/unplugin-vue-i18n": "^0.12.2", - "@mizchi/sucrase": "^4.1.0", - "@nuxt/kit": "^3.6.5", - "@vue/compiler-sfc": "^3.3.4", - "cookie-es": "^1.0.0", - "debug": "^4.3.4", - "defu": "^6.1.2", - "estree-walker": "^3.0.3", - "is-https": "^4.0.0", - "js-cookie": "^3.0.5", - "knitwork": "^1.0.0", - "magic-string": "^0.27.0", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.1.2", - "unplugin": "^1.3.2", - "unstorage": "^1.5.0", - "vue-i18n": "9.3.0-beta.26", - "vue-i18n-routing": "^0.13.3" - }, - "dependencies": { - "@intlify/core-base": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.3.0-beta.26.tgz", - "integrity": "sha512-omhEuB6+uE3D36wAtBazTkjQxfMy+sHAdvPe51aPINVcIiL9RZiSMgecipbvkjqnL/5ogTcCc/UXKWlM3jb90g==", - "requires": { - "@intlify/devtools-if": "9.3.0-beta.26", - "@intlify/message-compiler": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26", - "@intlify/vue-devtools": "9.3.0-beta.26" - } - }, - "@intlify/devtools-if": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.3.0-beta.26.tgz", - "integrity": "sha512-N13XwjkT/payWlr8DqBVylsPlwjm4WyaI+eaG+eVdBKPw0yI/9c4zJ3U+/ASRBRuzArVJxALE+LT/cI1NxWGvw==", - "requires": { - "@intlify/shared": "9.3.0-beta.26" - } - }, - "@intlify/message-compiler": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.26.tgz", - "integrity": "sha512-qsfU6Lca7mI80ts1vgy+pfNvGm2gHy0nERpT/K1GYgnECmsKwud0e8SG1PPxKPEHKa5Mdngzs4pS7X1wH0SCGA==", - "requires": { - "@intlify/shared": "9.3.0-beta.26", - "source-map-js": "^1.0.2" - } - }, - "@intlify/vue-devtools": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.3.0-beta.26.tgz", - "integrity": "sha512-IwJM8jUCM+savGDvgcOQaVHNMPDbvRf9dVjB+skCemYA7DBqtJ0YypTlRDtt6PO9rDfkWU2Z0ueaY/o6OaGtRg==", - "requires": { - "@intlify/core-base": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26" - } - }, - "vue-i18n": { - "version": "9.3.0-beta.26", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.3.0-beta.26.tgz", - "integrity": "sha512-RfyxO4wMJ3SiqjxKGydA1RnJ6rvl4y60Urzqab80x9weCooNdb7++fRce+ZtSqtvnt4NTSq4je/WWyU8EAR9cA==", - "requires": { - "@intlify/core-base": "9.3.0-beta.26", - "@intlify/shared": "9.3.0-beta.26", - "@intlify/vue-devtools": "9.3.0-beta.26", - "@vue/devtools-api": "^6.5.0" - } - }, - "vue-i18n-routing": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/vue-i18n-routing/-/vue-i18n-routing-0.13.4.tgz", - "integrity": "sha512-cihM/X4c6dgAnSVoIc3wUoiGG6B/Y+a3B3+Xt+7b9n2mjnKQ+ZkQ6oKVQxOd8WFRdJyohlP5dyL3Xsho4HZjBw==", - "requires": { - "@intlify/shared": "next", - "@intlify/vue-i18n-bridge": "^0.8.0", - "@intlify/vue-router-bridge": "^0.8.0", - "ufo": "^1.2.0", - "vue-demi": "^0.14.5" - }, - "dependencies": { - "@intlify/vue-i18n-bridge": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@intlify/vue-i18n-bridge/-/vue-i18n-bridge-0.8.0.tgz", - "integrity": "sha512-wQ18fSccm9QaWpUW2vq2QHvojgKIog7s+UMj9LeY3pUV3yD9bU4YZI+1PTNoX3tOA+BE71gQyqVGox/TVQKP6Q==", - "requires": {} - }, - "@intlify/vue-router-bridge": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@intlify/vue-router-bridge/-/vue-router-bridge-0.8.0.tgz", - "integrity": "sha512-CNxOgvyQcRhtGmRrksicL+HGjDijXtz+J/x04C/RslZ74CFdZkxjCe8MABkeD3xr+ry8G8tCm2nV2hLjZbynQw==", - "requires": { - "vue-demi": "^0.13.5" - }, - "dependencies": { - "vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", - "requires": {} - } - } - }, - "vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "requires": {} - } - } - } - } - }, - "@parcel/watcher": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.3.0.tgz", - "integrity": "sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ==", - "requires": { - "@parcel/watcher-android-arm64": "2.3.0", - "@parcel/watcher-darwin-arm64": "2.3.0", - "@parcel/watcher-darwin-x64": "2.3.0", - "@parcel/watcher-freebsd-x64": "2.3.0", - "@parcel/watcher-linux-arm-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-musl": "2.3.0", - "@parcel/watcher-linux-x64-glibc": "2.3.0", - "@parcel/watcher-linux-x64-musl": "2.3.0", - "@parcel/watcher-win32-arm64": "2.3.0", - "@parcel/watcher-win32-ia32": "2.3.0", - "@parcel/watcher-win32-x64": "2.3.0", - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "dependencies": { - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==" - } - } - }, - "@parcel/watcher-android-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz", - "integrity": "sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA==", - "optional": true - }, - "@parcel/watcher-darwin-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz", - "integrity": "sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw==", - "optional": true - }, - "@parcel/watcher-darwin-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz", - "integrity": "sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow==", - "optional": true - }, - "@parcel/watcher-freebsd-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz", - "integrity": "sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw==", - "optional": true - }, - "@parcel/watcher-linux-arm-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz", - "integrity": "sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ==", - "optional": true - }, - "@parcel/watcher-linux-arm64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz", - "integrity": "sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA==", - "optional": true - }, - "@parcel/watcher-linux-arm64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz", - "integrity": "sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw==", - "optional": true - }, - "@parcel/watcher-linux-x64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz", - "integrity": "sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow==", - "optional": true - }, - "@parcel/watcher-linux-x64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz", - "integrity": "sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g==", - "optional": true - }, - "@parcel/watcher-wasm": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz", - "integrity": "sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA==", - "requires": { - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "napi-wasm": "^1.1.0" - }, - "dependencies": { - "napi-wasm": { - "version": "1.1.0", - "bundled": true - } - } - }, - "@parcel/watcher-win32-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz", - "integrity": "sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw==", - "optional": true - }, - "@parcel/watcher-win32-ia32": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz", - "integrity": "sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow==", - "optional": true - }, - "@parcel/watcher-win32-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz", - "integrity": "sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA==", - "optional": true - }, - "@pinia/nuxt": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.4.11.tgz", - "integrity": "sha512-bhuNFngJpmBCdAqWguezNJ/oJFR7wvKieqiZrmmdmPR07XjsidAw8RLXHMZE9kUm32M9E6T057OBbG/22jERTg==", - "requires": { - "@nuxt/kit": "^3.5.0", - "pinia": ">=2.1.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 - }, - "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true - }, - "@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", - "dev": true, - "requires": { - "slash": "^4.0.0" - } - }, - "@rollup/plugin-commonjs": { - "version": "25.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", - "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - } - } - }, - "@rollup/plugin-inject": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", - "integrity": "sha512-411QlbL+z2yXpRWFXSmw/teQRMkXcAAC8aYTemc15gwJRpvEVDQwoe+N/HTFD8RFG8+88Bme9DK2V9CVm7hJdA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.27.0" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - } - } - }, - "@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1" - } - }, - "@rollup/plugin-node-resolve": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", - "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-replace": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", - "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.27.0" - } - }, - "@rollup/plugin-terser": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz", - "integrity": "sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==", - "dev": true, - "requires": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - } - }, - "@rollup/plugin-wasm": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", - "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", - "dev": true, - "requires": {} - }, - "@rollup/pluginutils": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz", - "integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==", - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - } - } - }, - "@rushstack/eslint-patch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", - "integrity": "sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw==", - "dev": true - }, - "@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/bundle": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.1.0.tgz", - "integrity": "sha512-89uOo6yh/oxaU8AeOUnVrTdVMcGk9Q1hJa7Hkvalc6G3Z3CupWk4Xe9djSgJm9fMkH69s0P0cVHUoKSOemLdng==", - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.1" - } - }, - "@sigstore/protobuf-specs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", - "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", - "dev": true - }, - "@sigstore/sign": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.1.0.tgz", - "integrity": "sha512-4VRpfJxs+8eLqzLVrZngVNExVA/zAhVbi4UT4zmtLi4xRd7vz5qie834OgkrGsLlLB1B2nz/3wUxT1XAUBe8gw==", - "dev": true, - "requires": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "make-fetch-happen": "^13.0.0" - }, - "dependencies": { - "make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "requires": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - } - } - } - }, - "@sigstore/tuf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.1.0.tgz", - "integrity": "sha512-BUoVCx+7Wj+8moEGvUU2MyBI+f93lmg1CLmoG6KrhQMeDyAG8HAZNk+YRCNuvwvSDCfPhwsj37Bg63/Q+bnGsw==", - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" - } - }, - "@swagger-api/apidom-ast": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.75.0.tgz", - "integrity": "sha512-IOAVA835ZuNFR23Tpca/q1FUyv4cQ8c4nnN3NsmXU+rLP+qrhsyyqkUa0pRAMvE77EfZfOcfJpUo0WTYozPTag==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "unraw": "^3.0.0" - } - }, - "@swagger-api/apidom-core": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.75.0.tgz", - "integrity": "sha512-DuWQm0YYhBhEDX/u8EbLtKhWpgrk7+DjYD6WYh8emt6eZGpRuVWDABPN6LXZy4BpQ60Fy0aBSZaSf5C+404LCw==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@types/ramda": "~0.29.3", - "minim": "~0.23.8", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "short-unique-id": "^4.4.4", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-json-pointer": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.75.0.tgz", - "integrity": "sha512-BdwXIHA3Ulmdik3bOzvX2n320fDcdOX+GO0eUG2Ewi7OHI5gQEQZdkeGONF6PFpG5M5afKYnduYOxkz4MPQEjA==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-ns-api-design-systems": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-0.75.0.tgz", - "integrity": "sha512-3+2w4WJ5iHeTeI5Go3T1kbpHUVeTd/GGrbjP5YpD8FGeW5aNodRnMZi5DnmPZ1jqJJT6JLLxQWTubFnd3v1ksQ==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-asyncapi-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-0.75.0.tgz", - "integrity": "sha512-W+EifcReXeNTaDlp75+sX5Ev3upkT1aZ3D1HLSKhGyi3weuOcPFYc7PTDVmoDJTSCch4NFXIFrAEvRNNxzhHvA==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-7": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.75.0.tgz", - "integrity": "sha512-DjkbOjeqz5AYr6PWFWSPb4hKiVFUpB0iRdZEtPOU4YKd9lSImDe4rnob2uDDJR5uQV6FoG2BAVRTckEvPQa0+g==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-json-schema-draft-6": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-0.75.0.tgz", - "integrity": "sha512-sDQLgRpjRUons2B8s3fvRZXCS4Zg5gC3zhkuQmh4a1Uu+Fu+QG2wQ/WY5Q7MBj6G8QL2wnxihCYOdTd9IpA/Xg==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-json-schema-draft-7": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-0.75.0.tgz", - "integrity": "sha512-P0g0J16QmAO4Tjd8E1Gi7ESlEcyouq3CaYVZ0Rz1KSNNi9nkUOKTd4/i1LSTgKQHs86U4WlJFSk6iQxfkzhgcQ==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-6": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.75.0.tgz", - "integrity": "sha512-ndJC9QeIIMeK2WpeJeEGUuwcmDXXuEtOKl9GCX4sbXicZbI00cv7FJCJeFPL7QdVsHFfAm+e9DbDgn1k2K7Eww==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.75.0.tgz", - "integrity": "sha512-j2lvGKceplAVDnhm84klUPzBAwJewdpZf7fD28szEeMMNfXi40y70rs6iFKTH6FVuBc/k5/nf/M44tQY+sdqGw==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - } - }, - "@swagger-api/apidom-parser-adapter-api-design-systems-json": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-0.75.0.tgz", - "integrity": "sha512-DE16Dg2Fjgv7mmZYhGkcvmcQVHk6+7ly1GRbTVBgLY10CGibd41FF3ttS1jiiT+yJxQbnuhvV0gJGV5X17GPNg==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-api-design-systems": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-0.75.0.tgz", - "integrity": "sha512-i3RMF3GKR62tW+cEYkRhbcnlm0SpGh59iQb+90my8udk3eeNwblvoqk5DlBWlZwT4FFQyAMXczYzX69DahKZKw==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-api-design-systems": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-0.75.0.tgz", - "integrity": "sha512-1Pa+cBFTMJFSVKdtsk7Q8h+/rR1/7Tfa/jkS6bIHRxuebQS6eY3JXgU22FhhOiuqNpLIkQOO1qHTknIJG77K2Q==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-0.75.0.tgz", - "integrity": "sha512-iqdmbdHgZ0I1KfrqZ+/qLqsDa/CuHzF/EvhAGHAwpVFP3w1bFS1gkUfnj5iSev4IUySyFpjf1dpZjHlXunrczg==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-json": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-0.75.0.tgz", - "integrity": "sha512-uYw1E7xUvf7fEaY9UdctTWmelztPv1qVl7VnZfct1LawOgtW8/hldhUaVrBmirBI10C6piy+3tDRA/mxRo6Y1Q==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "tree-sitter": "=0.20.4", - "tree-sitter-json": "=0.20.0", - "web-tree-sitter": "=0.20.3" - } - }, - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-0.75.0.tgz", - "integrity": "sha512-3Rc8tucPhqGakh4Txgmu+uoASnIDvjSwOo6Vh36LQo6SRf5S86NLmLOMd+nXfiP3WnWwoQtcfvi0IHML/dQhKg==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-0.75.0.tgz", - "integrity": "sha512-UBqvU6RwGVFPLO52+N/iW+g3pgfoIOxX6wtCtaeu71IvC8klQnvRPl7DRydNM46DuDeJRYfAR7rDUO/kWxu/LQ==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-0.75.0.tgz", - "integrity": "sha512-nQAuODuSgQw3JcY4lEll2RCp7Tj5RtksLwXGBpd6ZMmy4fqsYvgmhgpqlc/T4V3OXdsB98YVdEnGrwAq5GYdag==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-0.75.0.tgz", - "integrity": "sha512-7kICmmDib+Lg/HLe7pwUeXD1CzNyLhIocvxg4wz1nBxwLAcBnLybN1sAsPTISHG/1SVh/XOPaYMyOyfN1TmkAw==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - }, - "@swagger-api/apidom-parser-adapter-yaml-1-2": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-0.75.0.tgz", - "integrity": "sha512-8d443eF60U/8lYhuzbRyloGISqCy2ypugGAKaDGPDwgldy232mQG6Izhrwqj65qj+945n3j/rD0FcwKdUZmK6w==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.75.0", - "@swagger-api/apidom-core": "^0.75.0", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2", - "tree-sitter": "=0.20.4", - "tree-sitter-yaml": "=0.5.0", - "web-tree-sitter": "=0.20.3" - } - }, - "@swagger-api/apidom-reference": { - "version": "0.75.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.75.0.tgz", - "integrity": "sha512-3eqMfGaNBa3+Ao/9zrRPfxCuz9/3jag3W2XV8xuS4Xq2g3xqCEzPPUeraf6zoerk5EdXMSSoO6O8v074E4R4dg==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.75.0", - "@swagger-api/apidom-json-pointer": "^0.75.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.75.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.75.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.75.0", - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.75.0", - "@swagger-api/apidom-parser-adapter-json": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.75.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.75.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.75.0", - "@types/ramda": "~0.29.3", - "axios": "^1.4.0", - "minimatch": "^7.4.3", - "process": "^0.11.10", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.1.1", - "stampit": "^4.3.2" - }, - "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==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@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 - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, - "@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", - "dev": true - }, - "@tufjs/models": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.0.tgz", - "integrity": "sha512-c8nj8BaOExmZKO2DXhDfegyhSGcG9E/mPN3U13L+/PsoWm1uaGiHHjxqSHQiasDBQwDA3aHuw9+9spYAP1qvvg==", - "dev": true, - "requires": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - }, - "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.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" - }, - "@types/hast": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz", - "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@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/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/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/node": { - "version": "18.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.12.tgz", - "integrity": "sha512-d6xjC9fJ/nSnfDeU0AMDsaJyb1iHsqCSOdi84w4u+SlN/UgQdY5tRhpMzaFYsI4mnpvgTivEaQd0yOUhAtOnEQ==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" - }, - "@types/ramda": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.3.tgz", - "integrity": "sha512-Yh/RHkjN0ru6LVhSQtTkCRo6HXkfL9trot/2elzM/yXLJmbLm2v6kJc8yftTnwv1zvUob6TEtqI2cYjdqG3U0Q==", - "requires": { - "types-ramda": "^0.29.4" - } - }, - "@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, - "@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", - "dev": true - }, - "@types/unist": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", - "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" - }, - "@types/use-sync-external-store": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", - "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "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" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, - "@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - } - }, - "@unhead/dom": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.3.9.tgz", - "integrity": "sha512-bTbPFjXjmk8MC0cBC+7Bgf0Mcw62gsE2XqOhMH/qQo6NP4vR2XGxqy054Y7MGurznR1JVAqxUiU3cR/oxWFk3g==", - "dev": true, - "requires": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9" - } - }, - "@unhead/schema": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.3.9.tgz", - "integrity": "sha512-iIa0dczd2qTOxwYZbVR+iAKdlELnLTlKSFsN/YuJ/33sRi5VFa9D8TDBEPLec9gpcjB/bH0FhERfR4bb4UbRuA==", - "dev": true, - "requires": { - "hookable": "^5.5.3", - "zhead": "^2.0.10" - } - }, - "@unhead/shared": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.3.9.tgz", - "integrity": "sha512-lBXK1gzsg3XOnsOgYUVTT2RKOvM+AB0myDXkwQb0jsJB3Tc1qVOSz9JAOR+ZGrosSr7+Iv91+Fu/0E+knxaj2Q==", - "dev": true, - "requires": { - "@unhead/schema": "1.3.9" - } - }, - "@unhead/ssr": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/ssr/-/ssr-1.3.9.tgz", - "integrity": "sha512-FTt4IQOAxHiSfRM7IoJJiFnUEBH8CG5zkJOQ/LydG19QpYa9/AGOi4xvngeCr++1as51p2hWoRO6gPxSRhV8cA==", - "dev": true, - "requires": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9" - } - }, - "@unhead/vue": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.3.9.tgz", - "integrity": "sha512-rVAsRLBc+3Y//NRmr7vmRs5yhIf65jYSvcj0V5DtDfDwql7BbGgc3VIIEvY0+EjLQuNsS5kxwm78LSPCIl/3Xw==", - "dev": true, - "requires": { - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9", - "hookable": "^5.5.3", - "unhead": "1.3.9" - } - }, - "@vercel/nft": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.23.1.tgz", - "integrity": "sha512-NE0xSmGWVhgHF1OIoir71XAd0W0C1UE3nzFyhpFiMr3rVhetww7NvM1kc41trBsPG37Bh+dE5FYCTMzM/gBu0w==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.5", - "@rollup/pluginutils": "^4.0.0", - "acorn": "^8.6.0", - "async-sema": "^3.1.1", - "bindings": "^1.4.0", - "estree-walker": "2.0.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.2", - "node-gyp-build": "^4.2.2", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "requires": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - } - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "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" - } - }, - "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 - } - } - }, - "@vitejs/plugin-vue": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz", - "integrity": "sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==", - "dev": true, - "requires": {} - }, - "@vitejs/plugin-vue-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.2.tgz", - "integrity": "sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==", - "dev": true, - "requires": { - "@babel/core": "^7.22.10", - "@babel/plugin-transform-typescript": "^7.22.10", - "@vue/babel-plugin-jsx": "^1.1.5" - } - }, - "@vue-macros/common": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-1.7.2.tgz", - "integrity": "sha512-0/2A4kWLTCNEx+DDQKLvs7zXpfjgAbGBZ58SIvDN1DjGXhG4WaIUZtgMqzA6bvc5dNN7RaOatZYubkVumwmjWA==", - "dev": true, - "requires": { - "@babel/types": "^7.22.10", - "@rollup/pluginutils": "^5.0.3", - "@vue/compiler-sfc": "^3.3.4", - "ast-kit": "^0.10.0", - "local-pkg": "^0.4.3", - "magic-string-ast": "^0.3.0" - } - }, - "@vue/babel-helper-vue-transform-on": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.1.5.tgz", - "integrity": "sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==", - "dev": true - }, - "@vue/babel-plugin-jsx": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.5.tgz", - "integrity": "sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5", - "@vue/babel-helper-vue-transform-on": "^1.1.5", - "camelcase": "^6.3.0", - "html-tags": "^3.3.1", - "svg-tags": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "requires": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - } - } - }, - "@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "requires": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "requires": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "requires": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" - }, - "@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", - "requires": { - "@vue/shared": "3.3.4" - } - }, - "@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", - "requires": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", - "requires": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", - "requires": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" - } - }, - "@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", - "requires": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" - }, - "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 - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "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, - "requires": { - "debug": "^4.3.4" - } - }, - "agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dev": true, - "requires": { - "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": "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-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - }, - "dependencies": { - "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 - }, - "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" - } - } - } - }, - "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" - }, - "dependencies": { - "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 - } - } - }, - "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": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "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==" - }, - "archiver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.0.tgz", - "integrity": "sha512-EPGa+bYaxaMiCT8DCbEDqFz8IjeBSExrJzyUOJx2FBkFJ/OZzJuso3lMSk901M50gMqXxTQcumlGajOFlXhVhw==", - "dev": true, - "requires": { - "archiver-utils": "^3.0.0", - "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.1.2", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - } - } - }, - "archiver-utils": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.3.tgz", - "integrity": "sha512-fXzpEZTKgBJMWy0eUT0/332CAQnJ27OJd7sGcvNZzxS2Yzg7iITivMhXOm+zUTO4vT8ZqlPCqiaLPmB8qWhWRA==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "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" - } - } - } - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "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-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - } - }, - "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 - }, - "array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - } - }, - "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "ast-kit": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-0.10.0.tgz", - "integrity": "sha512-8y01XClpURgvxTJmM4AY2oHa1B/6iysALB9yJM1j4ak3Z2ZsnU0ewjDZzqOHdbNdit6hC0DGZNrBqNuCrv51fQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.22.10", - "@rollup/pluginutils": "^5.0.3", - "pathe": "^1.1.1" - } - }, - "ast-types": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", - "dev": true, - "requires": { - "tslib": "^2.0.1" - } - }, - "ast-walker-scope": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.4.2.tgz", - "integrity": "sha512-vdCU9JvpsrxWxvJiRHAr8If8cu07LWJXDPhkqLiP4ErbN1fu/mK623QGmU4Qbn2Nq4Mx0vR/Q017B6+HcHg1aQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.22.4", - "@babel/types": "^7.22.4" - } - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "async-sema": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", - "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", - "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==" - }, - "autolinker": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", - "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", - "requires": { - "tslib": "^2.3.0" - } - }, - "autoprefixer": { - "version": "10.4.15", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", - "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", - "dev": true, - "requires": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001520", - "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 - }, - "axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.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==" - }, - "big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "birpc": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.13.tgz", - "integrity": "sha512-30rz9OBSJoGfiWox7dpyqoSVo6664PBEYSTfmmG1GBridUxnMysyovNpnwhaPMvjtKn3Y1UfII+HMTU0kqJFjA==", - "dev": true - }, - "bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "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" - } - } - } - }, - "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 - }, - "boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dev": true, - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - } - }, - "bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "requires": { - "big-integer": "^1.6.44" - } - }, - "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==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "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==", - "devOptional": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "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-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "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 - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, - "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" - } - }, - "bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "requires": { - "run-applescript": "^5.0.0" - } - }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "requires": { - "streamsearch": "^1.1.0" - } - }, - "c12": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/c12/-/c12-1.4.2.tgz", - "integrity": "sha512-3IP/MuamSVRVw8W8+CHWAz9gKN4gd+voF2zm/Ln6D25C2RhytEZ1ABbC8MjKr4BR9rhoV1JQ7jJA158LDiTkLg==", - "requires": { - "chokidar": "^3.5.3", - "defu": "^6.1.2", - "dotenv": "^16.3.1", - "giget": "^1.1.2", - "jiti": "^1.18.2", - "mlly": "^1.4.0", - "ohash": "^1.1.2", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "rc9": "^2.1.1" - } - }, - "cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true - }, - "cacache": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.0.tgz", - "integrity": "sha512-I7mVOPl3PUCeRub1U8YoGz2Lqv9WOBpobZ8RyWFXmReuILz+3OAyTa5oH3QPdtKZD7N0Yk00aLfzn0qvp8dZ1w==", - "dev": true, - "requires": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "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": { - "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" - } - }, - "glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "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": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001525", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz", - "integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==" - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "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==" - }, - "ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==" - }, - "citty": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.3.tgz", - "integrity": "sha512-tb6zTEb2BDSrzFedqFYFUKUuKNaxVJWCm7o02K4kADGkBDyyiz7D40rDMpguczdZyAN3aetd5fhpB01HkreNyg==", - "requires": { - "consola": "^3.2.3" - } - }, - "classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" - }, - "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 - }, - "clear": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clear/-/clear-0.1.0.tgz", - "integrity": "sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw==", - "dev": true - }, - "cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "dev": true - }, - "clipboardy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", - "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", - "requires": { - "arch": "^2.2.0", - "execa": "^5.1.1", - "is-wsl": "^2.2.0" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "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==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "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==", - "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==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "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==" - } - } - }, - "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" - }, - "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 - }, - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" - }, - "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==", - "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==" - }, - "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 - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "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" - } - }, - "comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" - }, - "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 - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "consola": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==" - }, - "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 - }, - "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==" - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-es": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.0.0.tgz", - "integrity": "sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==" - }, - "copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "requires": { - "toggle-selection": "^1.0.6" - } - }, - "core-js-pure": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.1.tgz", - "integrity": "sha512-f52QZwkFVDPf7UEQZGHKx6NYxsxmVGJe5DIvbzOdRMJlmT6yv0KDjR8rmy3ngr/t5wU54c7Sp/qIJH0ppbhVpQ==" - }, - "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==" - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "requires": { - "node-fetch": "^2.6.12" - }, - "dependencies": { - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "requires": { - "whatwg-url": "^5.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==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true, - "requires": {} - }, - "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-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "requires": { - "mdn-data": "2.0.30", - "source-map-js": "^1.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==" - }, - "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 - }, - "cssnano": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.1.tgz", - "integrity": "sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==", - "dev": true, - "requires": { - "cssnano-preset-default": "^6.0.1", - "lilconfig": "^2.1.0" - } - }, - "cssnano-preset-default": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz", - "integrity": "sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^4.0.0", - "postcss-calc": "^9.0.0", - "postcss-colormin": "^6.0.0", - "postcss-convert-values": "^6.0.0", - "postcss-discard-comments": "^6.0.0", - "postcss-discard-duplicates": "^6.0.0", - "postcss-discard-empty": "^6.0.0", - "postcss-discard-overridden": "^6.0.0", - "postcss-merge-longhand": "^6.0.0", - "postcss-merge-rules": "^6.0.1", - "postcss-minify-font-values": "^6.0.0", - "postcss-minify-gradients": "^6.0.0", - "postcss-minify-params": "^6.0.0", - "postcss-minify-selectors": "^6.0.0", - "postcss-normalize-charset": "^6.0.0", - "postcss-normalize-display-values": "^6.0.0", - "postcss-normalize-positions": "^6.0.0", - "postcss-normalize-repeat-style": "^6.0.0", - "postcss-normalize-string": "^6.0.0", - "postcss-normalize-timing-functions": "^6.0.0", - "postcss-normalize-unicode": "^6.0.0", - "postcss-normalize-url": "^6.0.0", - "postcss-normalize-whitespace": "^6.0.0", - "postcss-ordered-values": "^6.0.0", - "postcss-reduce-initial": "^6.0.0", - "postcss-reduce-transforms": "^6.0.0", - "postcss-svgo": "^6.0.0", - "postcss-unique-selectors": "^6.0.0" - } - }, - "cssnano-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.0.tgz", - "integrity": "sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==", - "dev": true, - "requires": {} - }, - "csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dev": true, - "requires": { - "css-tree": "~2.2.0" - }, - "dependencies": { - "css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dev": true, - "requires": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - } - }, - "mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true - } - } - }, - "csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", - "dev": true - }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true - }, - "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" - } - }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "dev": true, - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "optional": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", - "dev": true, - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^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==" - }, - "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 - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" - }, - "default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "requires": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - } - }, - "default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "requires": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - } - }, - "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" - } - }, - "defu": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz", - "integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==" - }, - "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 - }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, - "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 - }, - "destr": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.1.tgz", - "integrity": "sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "devOptional": true - }, - "devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==", - "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 - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "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-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": "3.0.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A==" - }, - "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" - } - }, - "dot-prop": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-8.0.2.tgz", - "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", - "dev": true, - "requires": { - "type-fest": "^3.8.0" - }, - "dependencies": { - "type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true - } - } - }, - "dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" - }, - "drange": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", - "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==" - }, - "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 - }, - "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 - }, - "electron-to-chromium": { - "version": "1.4.506", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz", - "integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA==" - }, - "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 - }, - "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==", - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "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==", - "devOptional": true, - "requires": { - "once": "^1.4.0" - } - }, - "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" - } - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": 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==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-stack-parser-es": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.1.tgz", - "integrity": "sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA==", - "dev": true - }, - "es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - } - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, - "esbuild": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.2.tgz", - "integrity": "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.19.2", - "@esbuild/android-arm64": "0.19.2", - "@esbuild/android-x64": "0.19.2", - "@esbuild/darwin-arm64": "0.19.2", - "@esbuild/darwin-x64": "0.19.2", - "@esbuild/freebsd-arm64": "0.19.2", - "@esbuild/freebsd-x64": "0.19.2", - "@esbuild/linux-arm": "0.19.2", - "@esbuild/linux-arm64": "0.19.2", - "@esbuild/linux-ia32": "0.19.2", - "@esbuild/linux-loong64": "0.19.2", - "@esbuild/linux-mips64el": "0.19.2", - "@esbuild/linux-ppc64": "0.19.2", - "@esbuild/linux-riscv64": "0.19.2", - "@esbuild/linux-s390x": "0.19.2", - "@esbuild/linux-x64": "0.19.2", - "@esbuild/netbsd-x64": "0.19.2", - "@esbuild/openbsd-x64": "0.19.2", - "@esbuild/sunos-x64": "0.19.2", - "@esbuild/win32-arm64": "0.19.2", - "@esbuild/win32-ia32": "0.19.2", - "@esbuild/win32-x64": "0.19.2" - } - }, - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "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" - } - }, - "eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "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.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "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", - "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", - "text-table": "^0.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" - } - }, - "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-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" - } - }, - "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" - } - } - } - }, - "eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "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" - } - } - } - }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "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" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "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" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-plugin-vue": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz", - "integrity": "sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", - "xml-name-validator": "^4.0.0" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" - }, - "esno": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/esno/-/esno-0.16.3.tgz", - "integrity": "sha512-6slSBEV1lMKcX13DBifvnDFpNno5WXhw4j/ff7RI0y51BZiDqEe5dNhhjhIQ3iCOQuzsm2MbVzmwqbN78BBhPg==", - "dev": true, - "requires": { - "tsx": "^3.2.1" - } - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "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==" - }, - "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==" - }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true - }, - "execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": 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" - } - }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "optional": 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 - }, - "externality": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/externality/-/externality-1.0.2.tgz", - "integrity": "sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==", - "dev": true, - "requires": { - "enhanced-resolve": "^5.14.1", - "mlly": "^1.3.0", - "pathe": "^1.1.1", - "ufo": "^1.1.2" - } - }, - "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-folder-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/fast-folder-size/-/fast-folder-size-2.2.0.tgz", - "integrity": "sha512-7VsTlT/ELl5OQ4fnckM3idvaUkdJxf6VaYn0sC43GWoRmKqvbGfpoyC4BC/imTd9CEZtlfNsEf8/ZqdfoU4Nwg==", - "dev": true, - "requires": { - "decompress": "^4.2.1", - "https-proxy-agent": "^7.0.0" - } - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "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-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" - }, - "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==", - "requires": { - "reusify": "^1.0.4" - } - }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "requires": { - "format": "^0.2.0" - } - }, - "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" - } - }, - "fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, - "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" - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "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==", - "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-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" - }, - "flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", - "dev": true, - "requires": { - "flatted": "^3.2.7", - "keyv": "^4.5.3", - "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.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "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" - } - }, - "form-data-encoder": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.9.0.tgz", - "integrity": "sha512-rahaRMkN8P8d/tgK/BLPX+WBVM27NbvdXBxqQujBtkDAIFspaRqN7Od7lfdGQA6KAD+f82fYCLBq1ipvcu8qLw==" - }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" - }, - "formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "requires": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "dependencies": { - "web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" - } - } - }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "requires": { - "fetch-blob": "^3.1.2" - } - }, - "fraction.js": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.2.tgz", - "integrity": "sha512-9VLF466MqX1OUP7/d9r7/Vsvu6Hpp+taXBLmiR5x6mEYfT0BDkGVBt5TyA1aDu1WzIE1sF8F66evOFaz7iAEGQ==", - "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==", - "devOptional": true - }, - "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-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "requires": { - "minipass": "^7.0.3" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "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": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "dependencies": { - "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 - }, - "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" - } - } - } - }, - "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==" - }, - "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-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - } - }, - "get-port-please": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.0.2.tgz", - "integrity": "sha512-c14cAITf0E+uqdxGALvyYHwOL7UsnWcv3oDtgDAZksiVSGN87xlWVUWGZcmWQU3cICdaOxT+6LdQzUfK2ei1SA==" - }, - "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==" - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "get-tsconfig": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.0.tgz", - "integrity": "sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==", - "dev": true, - "requires": { - "resolve-pkg-maps": "^1.0.0" - } - }, - "giget": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/giget/-/giget-1.1.2.tgz", - "integrity": "sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==", - "requires": { - "colorette": "^2.0.19", - "defu": "^6.1.2", - "https-proxy-agent": "^5.0.1", - "mri": "^1.2.0", - "node-fetch-native": "^1.0.2", - "pathe": "^1.1.0", - "tar": "^6.1.13" - }, - "dependencies": { - "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" - } - }, - "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" - } - } - } - }, - "git-config-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", - "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", - "dev": true - }, - "git-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", - "dev": true, - "requires": { - "is-ssh": "^1.4.0", - "parse-url": "^8.1.0" - } - }, - "git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", - "dev": true, - "requires": { - "git-up": "^7.0.0" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "optional": true - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.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": "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" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "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" - } - }, - "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": { - "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 - } - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.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 - }, - "gzip-size": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", - "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", - "dev": true, - "requires": { - "duplexer": "^0.1.2" - } - }, - "h3": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/h3/-/h3-1.8.1.tgz", - "integrity": "sha512-m5rFuu+5bpwBBHqqS0zexjK+Q8dhtFRvO9JXQG0RvSPL6QrIT6vv42vuBM22SLOgGMoZYsHk0y7VPidt9s+nkw==", - "requires": { - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "iron-webcrypto": "^0.8.0", - "radix3": "^1.1.0", - "ufo": "^1.3.0", - "uncrypto": "^0.1.3", - "unenv": "^1.7.4" - } - }, - "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-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==" - }, - "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==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "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-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" - }, - "hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" - }, - "hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, - "highlight.js": { - "version": "11.8.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", - "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==", - "peer": true - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" - }, - "hosted-git-info": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", - "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", - "dev": true, - "requires": { - "lru-cache": "^10.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - } - } - }, - "html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true - }, - "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-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" - } - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "http-shutdown": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.2.tgz", - "integrity": "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==" - }, - "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, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "httpxy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.1.4.tgz", - "integrity": "sha512-ArXKNWhU5taozl6fFnu01M9HiInAqSOw4mUp+7DY/zbTHPmS8JBqH0IC3VLovRBd9b8ZE03ztemcxzeWT6pCoA==", - "dev": true - }, - "human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "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" - } - }, - "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==", - "optional": true, - "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==" - }, - "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.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "image-meta": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/image-meta/-/image-meta-0.1.1.tgz", - "integrity": "sha512-+oXiHwOEPr1IE5zY0tcBLED/CYcre15J4nwL50x3o0jxWqEkyjrusiKP3YSU+tr9fvJp33ZcP5Gpj2295g3aEw==", - "dev": true - }, - "immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" - }, - "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" - } - }, - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - }, - "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" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ioredis": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", - "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", - "requires": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - } - }, - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, - "iron-webcrypto": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-0.8.2.tgz", - "integrity": "sha512-jGiwmpgTuF19Vt4hn3+AzaVFGpVZt7A1ysd5ivFel2r4aNVFwqaYa6aU6qsF1PM7b+WFivZHz3nipwUOXaOnHg==" - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "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-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==", - "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-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.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-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "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-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "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-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "is-https": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-https/-/is-https-4.0.0.tgz", - "integrity": "sha512-FeMLiqf8E5g6SdiVJsPcNZX8k4h2fBs1wp5Bb6uaNxn58ufK1axBqQZdmAQsqh0t9BuwFObybrdVJh6MKyPlyg==" - }, - "is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "requires": { - "is-docker": "^3.0.0" - } - }, - "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-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-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "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==" - }, - "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-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "is-primitive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", - "dev": true - }, - "is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "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-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-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", - "dev": true, - "requires": { - "protocols": "^2.0.1" - } - }, - "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 - }, - "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.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "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" - }, - "dependencies": { - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - } - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "jackspeak": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.1.tgz", - "integrity": "sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jiti": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", - "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==" - }, - "joi": { - "version": "17.10.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.10.0.tgz", - "integrity": "sha512-hrazgRSlhzacZ69LdcKfhi3Vu13z2yFfoAzmEov3yFIJlatTdVGUW6vle1zjH8qkzdCn/qGw8rapjqsObbYXAg==", - "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" - } - }, - "js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==" - }, - "js-file-download": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", - "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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-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 - }, - "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 - }, - "json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", - "requires": { - "jsonify": "^0.0.1" - } - }, - "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 - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonc-eslint-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.3.0.tgz", - "integrity": "sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ==", - "requires": { - "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "semver": "^7.3.5" - } - }, - "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==" - }, - "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" - } - }, - "jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==" - }, - "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 - }, - "keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "dev": true - }, - "knitwork": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.0.0.tgz", - "integrity": "sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==" - }, - "kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "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" - } - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "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" - } - } - } - }, - "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" - } - }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "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==" - }, - "listhen": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/listhen/-/listhen-1.4.4.tgz", - "integrity": "sha512-xoZWbfziou7xPWj9nlFXeroFTJZVIyJ6wKrLea2jxvWgMkcz/vLMoZACYHLRmcLGi5hZkcDF48tmkmv1Y6Y42Q==", - "requires": { - "@parcel/watcher": "^2.3.0", - "@parcel/watcher-wasm": "2.3.0", - "citty": "^0.1.3", - "clipboardy": "^3.0.0", - "consola": "^3.2.3", - "defu": "^6.1.2", - "get-port-please": "^3.0.2", - "h3": "^1.8.1", - "http-shutdown": "^1.2.2", - "jiti": "^1.19.3", - "mlly": "^1.4.1", - "node-forge": "^1.3.1", - "pathe": "^1.1.1", - "ufo": "^1.3.0", - "untun": "^0.1.2", - "uqr": "^0.1.2" - } - }, - "local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==" - }, - "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==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" - }, - "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 - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "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.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowlight": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", - "requires": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } - } - }, - "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==", - "requires": { - "yallist": "^3.0.2" - } - }, - "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" - } - }, - "magic-string-ast": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-0.3.0.tgz", - "integrity": "sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==", - "dev": true, - "requires": { - "magic-string": "^0.30.2" - }, - "dependencies": { - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "magicast": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.2.10.tgz", - "integrity": "sha512-Ah2qatigknxwmoYCd9hx/mmVyrRNhDKiaWZIuW4gL6dWrAGMoOpCVkQ3VpGWARtkaJVFhe8uIphcsxDzLPQUyg==", - "dev": true, - "requires": { - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", - "recast": "^0.23.3" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "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 - } - } - }, - "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": { - "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" - } - }, - "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" - } - }, - "cacache": { - "version": "17.1.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", - "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", - "dev": true, - "requires": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^7.0.3", - "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": { - "minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true - } - } - }, - "glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "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" - } - }, - "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 - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true - } - } - }, - "mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "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==", - "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==" - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "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==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "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==" - }, - "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": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "optional": true - }, - "minim": { - "version": "0.23.8", - "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", - "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", - "requires": { - "lodash": "^4.15.0" - } - }, - "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==" - }, - "minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "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.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", - "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^7.0.3", - "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==", - "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==", - "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==" - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "optional": true - }, - "mlly": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.1.tgz", - "integrity": "sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==", - "requires": { - "acorn": "^8.10.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.3.0" - } - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, - "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==" - }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true - }, - "nanoid": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", - "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", - "dev": true - }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "optional": 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 - }, - "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 - }, - "nitropack": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.6.2.tgz", - "integrity": "sha512-gzbxLIhCoQrK+NrgW5Szuo6zzFEU/bqoohimyJ8IkETI3MXlYtLphlW/UVE8pv8UQ0IJ2HzxFpZ7Ldd0+bQ35A==", - "dev": true, - "requires": { - "@cloudflare/kv-asset-handler": "^0.3.0", - "@netlify/functions": "^2.0.2", - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^25.0.4", - "@rollup/plugin-inject": "^5.0.3", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.4.3", - "@rollup/plugin-wasm": "^6.1.3", - "@rollup/pluginutils": "^5.0.4", - "@types/http-proxy": "^1.17.11", - "@vercel/nft": "^0.23.1", - "archiver": "^6.0.0", - "c12": "^1.4.2", - "chalk": "^5.3.0", - "chokidar": "^3.5.3", - "citty": "^0.1.3", - "consola": "^3.2.3", - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "dot-prop": "^8.0.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "etag": "^1.8.1", - "fs-extra": "^11.1.1", - "globby": "^13.2.2", - "gzip-size": "^7.0.0", - "h3": "^1.8.1", - "hookable": "^5.5.3", - "httpxy": "^0.1.4", - "is-primitive": "^3.0.1", - "jiti": "^1.19.3", - "klona": "^2.0.6", - "knitwork": "^1.0.0", - "listhen": "^1.4.2", - "magic-string": "^0.30.3", - "mime": "^3.0.0", - "mlly": "^1.4.1", - "mri": "^1.2.0", - "node-fetch-native": "^1.4.0", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "openapi-typescript": "^6.5.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "pretty-bytes": "^6.1.1", - "radix3": "^1.1.0", - "rollup": "^3.28.1", - "rollup-plugin-visualizer": "^5.9.2", - "scule": "^1.0.0", - "semver": "^7.5.4", - "serve-placeholder": "^2.0.1", - "serve-static": "^1.15.0", - "std-env": "^3.4.3", - "ufo": "^1.3.0", - "uncrypto": "^0.1.3", - "unctx": "^2.3.1", - "unenv": "^1.7.4", - "unimport": "^3.2.0", - "unstorage": "^1.9.0" - }, - "dependencies": { - "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 - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", - "optional": true, - "requires": { - "semver": "^7.3.5" - } - }, - "node-addon-api": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", - "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==" - }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, - "node-fetch-native": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.4.0.tgz", - "integrity": "sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==" - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "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": { - "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" - } - }, - "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 - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "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" - } - } - } - }, - "node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "dev": true - }, - "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "dev": true, - "requires": { - "hosted-git-info": "^7.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==" - }, - "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.2.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.2.0.tgz", - "integrity": "sha512-744wat5wAAHsxa4590mWO0tJ8PKxR8ORZsH9wGpQc3nWTzozMAgBN/XyqYw7mg3yqLM8dLwEnwSfKMmXAjF69g==", - "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": "11.0.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.0.tgz", - "integrity": "sha512-D8sItaQ8n6VlBUFed3DLz2sCpkabRAjaiLkTamDppvh8lmmAPirzNfBuhJd/2rlmoxZ2S9mOHmIEvzV2z2jOeA==", - "dev": true, - "requires": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - } - }, - "npm-packlist": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.0.tgz", - "integrity": "sha512-ErAGFB5kJUciPy1mmx/C2YFbvxoJ0QJ9uwkCZOeR6CqLLISPZBOiFModAbSXnjjlwW5lOhuhXva+fURsSGJqyw==", - "dev": true, - "requires": { - "ignore-walk": "^6.0.0" - } - }, - "npm-pick-manifest": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz", - "integrity": "sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg==", - "dev": true, - "requires": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - } - }, - "npm-registry-fetch": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.0.0.tgz", - "integrity": "sha512-JFCpAPUpvpwfSydv99u85yhP68rNIxSFmDpNbNnRWKSe3gpjHnWL8v320gATwRzjtgmZ9Jfe37+ZPOLZPwz6BQ==", - "dev": true, - "requires": { - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" - }, - "dependencies": { - "make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "requires": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - } - } - } - }, - "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, - "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 - } - } - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "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" - } - }, - "nuxi": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/nuxi/-/nuxi-3.7.3.tgz", - "integrity": "sha512-Cg+ygRmhonE6PwAtDeKvKU/0VRqEyzmSSoJYfr0MzwIxQYrBSnLvw0z3UgJl/8MgFKjiZ5Y4wBUEiRsUw8O6uw==", - "dev": true, - "requires": { - "fsevents": "~2.3.3" - } - }, - "nuxt": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/nuxt/-/nuxt-3.7.0.tgz", - "integrity": "sha512-y0/xHYqwuJt20r26xezjpr74FLWR144dMpwSxZ/O2XXUrQUnyO7vHm3fEY4vi+miKbf343YMH5B78GXAELO/Vw==", - "dev": true, - "requires": { - "@nuxt/devalue": "^2.0.2", - "@nuxt/kit": "3.7.0", - "@nuxt/schema": "3.7.0", - "@nuxt/telemetry": "^2.4.1", - "@nuxt/ui-templates": "^1.3.1", - "@nuxt/vite-builder": "3.7.0", - "@unhead/dom": "^1.3.7", - "@unhead/ssr": "^1.3.7", - "@unhead/vue": "^1.3.7", - "@vue/shared": "^3.3.4", - "acorn": "8.10.0", - "c12": "^1.4.2", - "chokidar": "^3.5.3", - "cookie-es": "^1.0.0", - "defu": "^6.1.2", - "destr": "^2.0.1", - "devalue": "^4.3.2", - "esbuild": "^0.19.2", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "fs-extra": "^11.1.1", - "globby": "^13.2.2", - "h3": "^1.8.0", - "hookable": "^5.5.3", - "jiti": "^1.19.3", - "klona": "^2.0.6", - "knitwork": "^1.0.0", - "magic-string": "^0.30.3", - "mlly": "^1.4.1", - "nitropack": "^2.6.1", - "nuxi": "^3.7.0", - "nypm": "^0.3.1", - "ofetch": "^1.3.3", - "ohash": "^1.1.3", - "pathe": "^1.1.1", - "perfect-debounce": "^1.0.0", - "pkg-types": "^1.0.3", - "prompts": "^2.4.2", - "scule": "^1.0.0", - "std-env": "^3.4.3", - "strip-literal": "^1.3.0", - "ufo": "^1.3.0", - "ultrahtml": "^1.3.0", - "uncrypto": "^0.1.3", - "unctx": "^2.3.1", - "unenv": "^1.7.3", - "unimport": "^3.2.0", - "unplugin": "^1.4.0", - "unplugin-vue-router": "^0.6.4", - "untyped": "^1.4.0", - "vue": "^3.3.4", - "vue-bundle-renderer": "^2.0.0", - "vue-devtools-stub": "^0.1.0", - "vue-router": "^4.2.4" - }, - "dependencies": { - "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 - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "nypm": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.2.tgz", - "integrity": "sha512-a49F06faGtgflUVvqIkBmrYkijbbhjEoR40gzgw7I43J1p3DkHQegNcRhaGaHddIYQ0KwrmvD1W/h16jn/2puA==", - "dev": true, - "requires": { - "execa": "^8.0.1", - "ufo": "^1.3.0" - }, - "dependencies": { - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "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==" - }, - "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==" - }, - "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" - } - }, - "object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "ofetch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.3.3.tgz", - "integrity": "sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==", - "requires": { - "destr": "^2.0.1", - "node-fetch-native": "^1.4.0", - "ufo": "^1.3.0" - } - }, - "ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==" - }, - "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" - } - }, - "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": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.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" - }, - "dependencies": { - "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 - } - } - }, - "openapi-typescript": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-6.5.4.tgz", - "integrity": "sha512-ndNgrYIGSWSMrcXC8bFdx/voXRINB3dcHIm2+Sg9Tn7LJPXc7ufuaSr9E2eVucSwNxPu8oBbJxmMnxEZgT1lzA==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.3", - "fast-glob": "^3.3.1", - "js-yaml": "^4.1.0", - "supports-color": "^9.4.0", - "undici": "^5.23.0", - "yargs-parser": "^21.1.1" - } - }, - "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" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" - }, - "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": "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" - } - }, - "pacote": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.4.tgz", - "integrity": "sha512-eGdLHrV/g5b5MtD5cTPyss+JxOlaOloSMG3UwPMAvL8ywaLJ6beONPF40K4KKl/UI6q5hTKCJq5rCu8tkF+7Dg==", - "dev": true, - "requires": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - } - }, - "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-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", - "dev": true, - "requires": { - "git-config-path": "^2.0.0", - "ini": "^1.3.5" - }, - "dependencies": { - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - } - } - }, - "parse-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", - "dev": true, - "requires": { - "protocols": "^2.0.0" - } - }, - "parse-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", - "dev": true, - "requires": { - "parse-path": "^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 - }, - "patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.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==", - "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==", - "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": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "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" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "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" - } - } - } - }, - "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==" - }, - "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.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "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==" - }, - "pathe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", - "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==" - }, - "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 - }, - "perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "pinia": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz", - "integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==", - "requires": { - "@vue/devtools-api": "^6.5.0", - "vue-demi": ">=0.14.5" - }, - "dependencies": { - "vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "requires": {} - } - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "requires": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", - "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" - } - } - }, - "postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.0.tgz", - "integrity": "sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz", - "integrity": "sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz", - "integrity": "sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==", - "dev": true, - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz", - "integrity": "sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==", - "dev": true, - "requires": {} - }, - "postcss-discard-empty": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz", - "integrity": "sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==", - "dev": true, - "requires": {} - }, - "postcss-discard-overridden": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz", - "integrity": "sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==", - "dev": true, - "requires": {} - }, - "postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-import-resolver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-import-resolver/-/postcss-import-resolver-2.0.0.tgz", - "integrity": "sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==", - "requires": { - "enhanced-resolve": "^4.1.1" - }, - "dependencies": { - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "postcss-merge-longhand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz", - "integrity": "sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.0.0" - } - }, - "postcss-merge-rules": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz", - "integrity": "sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz", - "integrity": "sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz", - "integrity": "sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==", - "dev": true, - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz", - "integrity": "sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz", - "integrity": "sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-normalize-charset": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz", - "integrity": "sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==", - "dev": true, - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz", - "integrity": "sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz", - "integrity": "sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz", - "integrity": "sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz", - "integrity": "sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz", - "integrity": "sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz", - "integrity": "sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz", - "integrity": "sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz", - "integrity": "sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz", - "integrity": "sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==", - "dev": true, - "requires": { - "cssnano-utils": "^4.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz", - "integrity": "sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz", - "integrity": "sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.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-svgo": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.0.tgz", - "integrity": "sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.0.2" - } - }, - "postcss-unique-selectors": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz", - "integrity": "sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-url": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", - "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", - "dev": true, - "requires": { - "make-dir": "~3.1.0", - "mime": "~2.5.2", - "minimatch": "~3.0.4", - "xxhashjs": "~0.2.2" - }, - "dependencies": { - "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" - } - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - }, - "minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "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 - }, - "prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "optional": true, - "requires": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, - "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": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "dev": true - }, - "prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" - }, - "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": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "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==" - }, - "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.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "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==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "requires": { - "xtend": "^4.0.0" - } - }, - "protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true - }, - "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==" - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": 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==", - "dev": true - }, - "qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "radix3": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.0.tgz", - "integrity": "sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==" - }, - "ramda": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", - "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==" - }, - "ramda-adjunct": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-4.1.1.tgz", - "integrity": "sha512-BnCGsZybQZMDGram9y7RiryoRHS5uwx8YeGuUeDKuZuvK38XO6JJfmK85BwRWAKFA6pZ5nZBO/HBFtExVaf31w==", - "requires": {} - }, - "randexp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", - "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", - "requires": { - "drange": "^1.0.2", - "ret": "^0.2.0" - } - }, - "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" - } - }, - "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 - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "optional": true - }, - "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==", - "optional": true - } - } - }, - "rc9": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.1.tgz", - "integrity": "sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==", - "requires": { - "defu": "^6.1.2", - "destr": "^2.0.0", - "flat": "^5.0.2" - } - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-copy-to-clipboard": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", - "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", - "requires": { - "copy-to-clipboard": "^3.3.1", - "prop-types": "^15.8.1" - } - }, - "react-debounce-input": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", - "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", - "requires": { - "lodash.debounce": "^4", - "prop-types": "^15.8.1" - } - }, - "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "react-immutable-proptypes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", - "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", - "requires": { - "invariant": "^2.2.2" - } - }, - "react-immutable-pure-component": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", - "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", - "requires": {} - }, - "react-inspector": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", - "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", - "requires": {} - }, - "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==" - }, - "react-redux": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", - "integrity": "sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==", - "requires": { - "@babel/runtime": "^7.12.1", - "@types/hoist-non-react-statics": "^3.3.1", - "@types/use-sync-external-store": "^0.0.3", - "hoist-non-react-statics": "^3.3.2", - "react-is": "^18.0.0", - "use-sync-external-store": "^1.0.0" - }, - "dependencies": { - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - } - } - }, - "react-syntax-highlighter": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", - "requires": { - "@babel/runtime": "^7.3.1", - "highlight.js": "^10.4.1", - "lowlight": "^1.17.0", - "prismjs": "^1.27.0", - "refractor": "^3.6.0" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } - } - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "requires": { - "pify": "^2.3.0" - } - }, - "read-package-json": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.0.tgz", - "integrity": "sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg==", - "dev": true, - "requires": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.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" - } - }, - "glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "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" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "devOptional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-glob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", - "dev": true, - "requires": { - "minimatch": "^5.1.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": "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" - } - } - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "recast": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.4.tgz", - "integrity": "sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==", - "dev": true, - "requires": { - "assert": "^2.0.0", - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - } - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==" - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "requires": { - "redis-errors": "^1.0.0" - } - }, - "redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "requires": { - "@babel/runtime": "^7.9.2" - } - }, - "redux-immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", - "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", - "requires": {} - }, - "refractor": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", - "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", - "requires": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.27.0" - }, - "dependencies": { - "prismjs": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", - "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" - } - } - }, - "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "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" - } - }, - "remarkable": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", - "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", - "requires": { - "argparse": "^1.0.10", - "autolinker": "^3.11.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - } - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" - }, - "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 - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" - }, - "resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "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 - }, - "resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true - }, - "ret": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==" - }, - "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==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "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==", - "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" - } - } - } - }, - "rollup": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", - "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", - "devOptional": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-visualizer": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.9.2.tgz", - "integrity": "sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==", - "dev": true, - "requires": { - "open": "^8.4.0", - "picomatch": "^2.3.1", - "source-map": "^0.7.4", - "yargs": "^17.5.1" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, - "run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "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" - } - }, - "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" - } - }, - "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 - } - } - }, - "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==", - "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==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "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==" - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "sass": { - "version": "1.66.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", - "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", - "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - } - }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "scule": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/scule/-/scule-1.0.0.tgz", - "integrity": "sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==" - }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "dev": true, - "requires": { - "commander": "^2.8.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "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==", - "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==" - } - } - }, - "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 - } - } - }, - "serialize-error": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", - "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": { - "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==" - } - } - }, - "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-placeholder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-2.0.1.tgz", - "integrity": "sha512-rUzLlXk4uPFnbEaIz3SW8VISTxMuONas88nYWjAWaM2W9VDbt9tyFOr3lq8RhVOFrT3XISoBw8vni5una8qMnQ==", - "dev": true, - "requires": { - "defu": "^6.0.0" - } - }, - "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" - } - }, - "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==", - "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==" - }, - "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 - }, - "short-unique-id": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-4.4.4.tgz", - "integrity": "sha512-oLF1NCmtbiTWl2SqdXZQbo5KM1b7axdp0RgQLq8qCBBLoq+o3A5wmLrNM6bZIh54/a8BJ3l69kTXuxwZ+XCYuw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "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==" - }, - "sigstore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.1.0.tgz", - "integrity": "sha512-kPIj+ZLkyI3QaM0qX8V/nSsweYND3W448pwkDgS6CQ74MfhEkIR8ToK5Iyx46KJYRjseVcD3Rp9zAmUAj6ZjPw==", - "dev": true, - "requires": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" - } - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "optional": true - }, - "simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "optional": true, - "requires": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "simple-git": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.1.tgz", - "integrity": "sha512-Ck+rcjVaE1HotraRAS8u/+xgTvToTuoMkT9/l9lvuP5jftwnYUp6DwuJzsKErHgfyRk8IB8pqGHWEbM3tLgV1w==", - "dev": true, - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.4" - } - }, - "sirv": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", - "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", - "dev": true, - "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^3.0.0" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" - }, - "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 - }, - "smob": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", - "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", - "dev": true - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "devOptional": 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==" - }, - "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" - } - }, - "space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" - }, - "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 - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", - "dev": true, - "requires": { - "minipass": "^7.0.3" - } - }, - "stampit": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz", - "integrity": "sha512-pE2org1+ZWQBnIxRPrBM2gVupkuDD0TTNIo1H6GdT/vO82NXli2z8lRE8cu/nBIHrcOCXFBAHpb9ZldrB2/qOA==" - }, - "standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - }, - "std-env": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", - "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==" - }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true - }, - "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==", - "devOptional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "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" - }, - "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 - }, - "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" - } - } - } - }, - "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" - }, - "dependencies": { - "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 - } - } - }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "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-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-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "requires": { - "is-natural-number": "^4.0.1" - } - }, - "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 - }, - "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 - }, - "strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", - "requires": { - "acorn": "^8.10.0" - } - }, - "stylehacks": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.0.tgz", - "integrity": "sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - } - }, - "supports-color": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", - "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", - "dev": true - }, - "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 - }, - "svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "svgo": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", - "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.2.1", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "swagger-client": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.20.0.tgz", - "integrity": "sha512-5RLge2NIE1UppIT/AjUPEceT05hcBAzjiQkrXJYjpxsbFV/UDH3pp+fsrWbAeuZtgRdhNB9KDo+szLoUpzkydQ==", - "requires": { - "@babel/runtime-corejs3": "^7.20.13", - "@swagger-api/apidom-core": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-json-pointer": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=0.74.1 <1.0.0", - "@swagger-api/apidom-reference": ">=0.74.1 <1.0.0", - "cookie": "~0.5.0", - "cross-fetch": "^3.1.5", - "deepmerge": "~4.3.0", - "fast-json-patch": "^3.0.0-1", - "form-data-encoder": "^1.4.3", - "formdata-node": "^4.0.0", - "is-plain-object": "^5.0.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "qs": "^6.10.2", - "traverse": "~0.6.6", - "url": "~0.11.0" - } - }, - "swagger-ui": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-5.4.2.tgz", - "integrity": "sha512-EQtY7Ur53JWfn6GEU64x3xQEpJ2hfg79oplboR+2dhmqUjyeDZNFL5r8zfATjlREdkKI9IqzrcdK7CP5DNaBFg==", - "requires": { - "@babel/runtime-corejs3": "^7.22.10", - "@braintree/sanitize-url": "=6.0.4", - "base64-js": "^1.5.1", - "classnames": "^2.3.1", - "css.escape": "1.5.1", - "deep-extend": "0.6.0", - "dompurify": "=3.0.5", - "ieee754": "^1.2.1", - "immutable": "^3.x.x", - "js-file-download": "^0.4.12", - "js-yaml": "=4.1.0", - "lodash": "^4.17.21", - "patch-package": "^8.0.0", - "prop-types": "^15.8.1", - "randexp": "^0.5.3", - "randombytes": "^2.1.0", - "react": "=17.0.2", - "react-copy-to-clipboard": "5.1.0", - "react-debounce-input": "=3.3.0", - "react-dom": "=17.0.2", - "react-immutable-proptypes": "2.2.0", - "react-immutable-pure-component": "^2.2.0", - "react-inspector": "^6.0.1", - "react-redux": "^8.1.2", - "react-syntax-highlighter": "^15.5.0", - "redux": "^4.1.2", - "redux-immutable": "^4.0.0", - "remarkable": "^2.0.1", - "reselect": "^4.1.8", - "serialize-error": "^8.1.0", - "sha.js": "^2.4.11", - "swagger-client": "^3.20.0", - "url-parse": "^1.5.10", - "xml": "=1.0.1", - "xml-but-prettier": "^1.0.1", - "zenscroll": "^4.0.2" - }, - "dependencies": { - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==" - } - } - }, - "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==", - "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==", - "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==", - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "optional": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - }, - "dependencies": { - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "optional": 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" - } - } - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.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" - } - } - } - }, - "terser": { - "version": "5.19.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.3.tgz", - "integrity": "sha512-pQzJ9UJzM0IgmT4FAtYI6+VqFf0lj/to58AV0Xfgg0Up37RyPG7Al+1cepC6/BVuAxR9oNb41/DL4DEoHJvTdg==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - }, - "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 - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "dev": true - }, - "titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, - "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==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "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 - }, - "totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==" - }, - "tree-sitter": { - "version": "0.20.4", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz", - "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==", - "optional": true, - "requires": { - "nan": "^2.17.0", - "prebuild-install": "^7.1.1" - } - }, - "tree-sitter-json": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.0.tgz", - "integrity": "sha512-PteOLH+Tx6Bz4ZA/d40/DbkiSXXRM/gKahhHI8hQ1lWNfFvdknnz9k3Mz84ol5srRyLboJ8wp8GSkhZ6ht9EGQ==", - "optional": true, - "requires": { - "nan": "^2.14.1" - } - }, - "tree-sitter-yaml": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz", - "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, - "ts-api-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", - "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", - "dev": true, - "requires": {} - }, - "ts-toolbelt": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" - }, - "tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "tsx": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz", - "integrity": "sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==", - "dev": true, - "requires": { - "@esbuild-kit/cjs-loader": "^2.4.2", - "@esbuild-kit/core-utils": "^3.0.0", - "@esbuild-kit/esm-loader": "^2.5.5", - "fsevents": "~2.3.2" - } - }, - "tuf-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.1.0.tgz", - "integrity": "sha512-eD7YPPjVlMzdggrOeE8zwoegUaG/rt6Bt3jwoQPunRiNVzgcCE009UDFJKJjG+Gk9wFu6W/Vi+P5d/5QpdD9jA==", - "dev": true, - "requires": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" - }, - "dependencies": { - "make-fetch-happen": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", - "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", - "dev": true, - "requires": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - } - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "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": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "types-ramda": { - "version": "0.29.4", - "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.4.tgz", - "integrity": "sha512-XO/820iRsCDwqLjE8XE+b57cVGPyk1h+U9lBGpDWvbEky+NQChvHVwaKM05WnW1c5z3EVQh8NhXFmh2E/1YazQ==", - "requires": { - "ts-toolbelt": "^9.6.0" - } - }, - "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "devOptional": true - }, - "ufo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", - "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==" - }, - "ultrahtml": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.4.0.tgz", - "integrity": "sha512-2SbudS8oD4GNq4en+3ivp25JTCwP5O2soJhIBxGJrjojjLVaLcP84xVU6Xdf0wKMhZvr68rTtrXtO6uvEr2llQ==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "uncrypto": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", - "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==" - }, - "unctx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.3.1.tgz", - "integrity": "sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==", - "requires": { - "acorn": "^8.8.2", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.0", - "unplugin": "^1.3.1" - }, - "dependencies": { - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", - "dev": true, - "requires": { - "busboy": "^1.6.0" - } - }, - "unenv": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.7.4.tgz", - "integrity": "sha512-fjYsXYi30It0YCQYqLOcT6fHfMXsBr2hw9XC7ycf8rTG7Xxpe3ZssiqUnD0khrjiZEmkBXWLwm42yCSCH46fMw==", - "requires": { - "consola": "^3.2.3", - "defu": "^6.1.2", - "mime": "^3.0.0", - "node-fetch-native": "^1.4.0", - "pathe": "^1.1.1" - } - }, - "unhead": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/unhead/-/unhead-1.3.9.tgz", - "integrity": "sha512-vzWZJW8l6dlNM5egJs3c7NMHWZ+iw2x7jCZtU2rrhwFINlKCaA3J42fvOeDxx6t5QR9dfZ96HF2AeNlCcPT+bQ==", - "dev": true, - "requires": { - "@unhead/dom": "1.3.9", - "@unhead/schema": "1.3.9", - "@unhead/shared": "1.3.9", - "hookable": "^5.5.3" - } - }, - "unimport": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.2.0.tgz", - "integrity": "sha512-9buxPxkNwxwxAlH/RfOFHxtQTUrlmBGi9Ai9HezY2yYbkoOhgJTYPI6+WqxI1EZphoM9cw1SHoCFRkXSb8/fjQ==", - "requires": { - "@rollup/pluginutils": "^5.0.3", - "escape-string-regexp": "^5.0.0", - "fast-glob": "^3.3.1", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.3", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "scule": "^1.0.0", - "strip-literal": "^1.3.0", - "unplugin": "^1.4.0" - }, - "dependencies": { - "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==" - }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - }, - "unplugin": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.4.0.tgz", - "integrity": "sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==", - "requires": { - "acorn": "^8.9.0", - "chokidar": "^3.5.3", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.5.0" - } - }, - "unplugin-vue-router": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/unplugin-vue-router/-/unplugin-vue-router-0.6.4.tgz", - "integrity": "sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==", - "dev": true, - "requires": { - "@babel/types": "^7.21.5", - "@rollup/pluginutils": "^5.0.2", - "@vue-macros/common": "^1.3.1", - "ast-walker-scope": "^0.4.1", - "chokidar": "^3.5.3", - "fast-glob": "^3.2.12", - "json5": "^2.2.3", - "local-pkg": "^0.4.3", - "mlly": "^1.2.0", - "pathe": "^1.1.0", - "scule": "^1.0.0", - "unplugin": "^1.3.1", - "yaml": "^2.2.2" - } - }, - "unraw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", - "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==" - }, - "unstorage": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.9.0.tgz", - "integrity": "sha512-VpD8ZEYc/le8DZCrny3bnqKE4ZjioQxBRnWE+j5sGNvziPjeDlaS1NaFFHzl/kkXaO3r7UaF8MGQrs14+1B4pQ==", - "requires": { - "anymatch": "^3.1.3", - "chokidar": "^3.5.3", - "destr": "^2.0.1", - "h3": "^1.7.1", - "ioredis": "^5.3.2", - "listhen": "^1.2.2", - "lru-cache": "^10.0.0", - "mri": "^1.2.0", - "node-fetch-native": "^1.2.0", - "ofetch": "^1.1.1", - "ufo": "^1.2.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==" - } - } - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true - }, - "untun": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/untun/-/untun-0.1.2.tgz", - "integrity": "sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q==", - "requires": { - "citty": "^0.1.3", - "consola": "^3.2.3", - "pathe": "^1.1.1" - } - }, - "untyped": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.4.0.tgz", - "integrity": "sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==", - "requires": { - "@babel/core": "^7.22.9", - "@babel/standalone": "^7.22.9", - "@babel/types": "^7.22.5", - "defu": "^6.1.2", - "jiti": "^1.19.1", - "mri": "^1.2.0", - "scule": "^1.0.0" - } - }, - "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==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uqr": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", - "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==" - }, - "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" - } - }, - "url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", - "requires": { - "punycode": "^1.4.1", - "qs": "^6.11.0" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - } - } - }, - "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" - } - }, - "urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", - "dev": true - }, - "use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "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" - } - }, - "vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", - "dev": true, - "requires": { - "esbuild": "^0.18.10", - "fsevents": "~2.3.2", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "dependencies": { - "@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "dev": true, - "optional": true - }, - "esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - } - } - }, - "vite-node": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.33.0.tgz", - "integrity": "sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==", - "dev": true, - "requires": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0" - } - }, - "vite-plugin-checker": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.6.2.tgz", - "integrity": "sha512-YvvvQ+IjY09BX7Ab+1pjxkELQsBd4rPhWNw8WLBeFVxu/E7O+n6VYAqNsKdK/a2luFlX/sMpoWdGFfg4HvwdJQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "ansi-escapes": "^4.3.0", - "chalk": "^4.1.1", - "chokidar": "^3.5.1", - "commander": "^8.0.0", - "fast-glob": "^3.2.7", - "fs-extra": "^11.1.0", - "lodash.debounce": "^4.0.8", - "lodash.pick": "^4.4.0", - "npm-run-path": "^4.0.1", - "semver": "^7.5.0", - "strip-ansi": "^6.0.0", - "tiny-invariant": "^1.1.0", - "vscode-languageclient": "^7.0.0", - "vscode-languageserver": "^7.0.0", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-uri": "^3.0.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 - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "vite-plugin-inspect": { - "version": "0.7.38", - "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.7.38.tgz", - "integrity": "sha512-+p6pJVtBOLGv+RBrcKAFUdx+euizg0bjL35HhPyM0MjtKlqoC5V9xkCmO9Ctc8JrTyXqODbHqiLWJKumu5zJ7g==", - "dev": true, - "requires": { - "@antfu/utils": "^0.7.5", - "@rollup/pluginutils": "^5.0.2", - "debug": "^4.3.4", - "error-stack-parser-es": "^0.1.1", - "fs-extra": "^11.1.1", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "sirv": "^2.0.3" - }, - "dependencies": { - "define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true - }, - "open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "requires": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - } - } - } - }, - "vite-plugin-vue-inspector": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-3.6.0.tgz", - "integrity": "sha512-Fi+9JaMx/reuic+MWbrdw8g5TwZM5a/BmdBT8OKKZi3rK4Qw3wND9smT+Ld+Daitbgly17uvuCiull2KV/hEBQ==", - "dev": true, - "requires": { - "@babel/core": "^7.21.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.21.3", - "@vue/babel-plugin-jsx": "^1.1.1", - "@vue/compiler-dom": "^3.2.47", - "esno": "^0.16.3", - "kolorist": "^1.7.0", - "magic-string": "^0.30.0", - "shell-quote": "^1.8.0" - }, - "dependencies": { - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "vscode-jsonrpc": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", - "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", - "dev": true - }, - "vscode-languageclient": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", - "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "semver": "^7.3.4", - "vscode-languageserver-protocol": "3.16.0" - } - }, - "vscode-languageserver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", - "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.16.0" - } - }, - "vscode-languageserver-protocol": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", - "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", - "dev": true, - "requires": { - "vscode-jsonrpc": "6.0.0", - "vscode-languageserver-types": "3.16.0" - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz", - "integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==", - "dev": true - }, - "vscode-languageserver-types": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", - "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", - "dev": true - }, - "vscode-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", - "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==", - "dev": true - }, - "vue": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", - "requires": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "vue-bundle-renderer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vue-bundle-renderer/-/vue-bundle-renderer-2.0.0.tgz", - "integrity": "sha512-oYATTQyh8XVkUWe2kaKxhxKVuuzK2Qcehe+yr3bGiaQAhK3ry2kYE4FWOfL+KO3hVFwCdLmzDQTzYhTi9C+R2A==", - "dev": true, - "requires": { - "ufo": "^1.2.0" - } - }, - "vue-devtools-stub": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz", - "integrity": "sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==", - "dev": true - }, - "vue-eslint-parser": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz", - "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - } - }, - "vue-i18n": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz", - "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", - "devOptional": true, - "requires": { - "@intlify/core-base": "9.2.2", - "@intlify/shared": "9.2.2", - "@intlify/vue-devtools": "9.2.2", - "@vue/devtools-api": "^6.2.1" - }, - "dependencies": { - "@intlify/shared": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", - "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", - "devOptional": true - } - } - }, - "vue-router": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz", - "integrity": "sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==", - "devOptional": true, - "requires": { - "@vue/devtools-api": "^6.5.0" - } - }, - "vuetify": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.3.15.tgz", - "integrity": "sha512-n7GYBO31k8vA9UfvRwLNyBlkq1WoN3IJ9wNnIBFeV4axleSjFAzzR4WUw7rgj6Ba3q6N2hxXoyxJM21tseQTfQ==", - "requires": {} - }, - "wait-on": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.0.1.tgz", - "integrity": "sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==", - "dev": true, - "requires": { - "axios": "^0.27.2", - "joi": "^17.7.0", - "lodash": "^4.17.21", - "minimist": "^1.2.7", - "rxjs": "^7.8.0" - }, - "dependencies": { - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - } - } - }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "dev": true - }, - "web-tree-sitter": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz", - "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==", - "optional": true - }, - "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==" - }, - "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==" - }, - "webpack-virtual-modules": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz", - "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "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" - } - }, - "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-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "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" - } - }, - "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" - }, - "dependencies": { - "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 - }, - "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" - } - } - } - }, - "widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dev": true, - "requires": { - "string-width": "^5.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" - }, - "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 - }, - "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-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 - }, - "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 - }, - "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" - } - } - } - }, - "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==", - "dev": true, - "requires": {} - }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" - }, - "xml-but-prettier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", - "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", - "requires": { - "repeat-string": "^1.5.2" - } - }, - "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==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "dev": true, - "requires": { - "cuint": "^0.2.2" - } - }, - "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": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==" - }, - "yaml-eslint-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", - "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", - "requires": { - "eslint-visitor-keys": "^3.0.0", - "lodash": "^4.17.21", - "yaml": "^2.0.0" - } - }, - "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": { - "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 - }, - "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" - } - } - } - }, - "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 - }, - "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" - } - }, - "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 - }, - "zenscroll": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", - "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==" - }, - "zhead": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/zhead/-/zhead-2.0.10.tgz", - "integrity": "sha512-irug8fXNKjqazkA27cFQs7C6/ZD3qNiEzLC56kDyzQART/Z9GMGfg8h2i6fb9c8ZWnIx/QgOgFJxK3A/CYHG0g==", - "dev": true - }, - "zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "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" - } - } - } - }, - "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" - } - }, - "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" - } - } - } - } - } -} diff --git a/src/frontend/package.json b/src/frontend/package.json deleted file mode 100644 index 970d9e45..00000000 --- a/src/frontend/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "client", - "version": "1.3.4", - "private": true, - "scripts": { - "build": "nuxt build", - "dev": "rm -rf /tmp/nitro && nuxt dev", - "generate": "nuxt generate", - "preview": "nuxt preview", - "postinstall": "nuxt prepare", - "lint": "npm run lint:js", - "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", - "lintfix": "npm run lint:js --fix" - }, - "devDependencies": { - "@nuxt/devtools": "latest", - "@nuxt/eslint-config": "^0.2.0", - "eslint": "^8.48.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-vue": "^9.17.0", - "nuxt": "^3.7.0", - "vue-i18n": "^9.2.2" - }, - "dependencies": { - "@highlightjs/vue-plugin": "^2.1.0", - "@mdi/font": "^7.2.96", - "@nuxtjs/i18n": "^8.0.0-rc.2", - "@pinia/nuxt": "^0.4.11", - "axios": "^1.4.0", - "pinia": "^2.1.6", - "sass": "^1.65.1", - "swagger-ui": "^5.4.2", - "vuetify": "^3.3.14" - } -} diff --git a/src/frontend/plugins/health.js b/src/frontend/plugins/health.js deleted file mode 100644 index 5f01859e..00000000 --- a/src/frontend/plugins/health.js +++ /dev/null @@ -1,16 +0,0 @@ -import axios from 'axios'; -import { defineNuxtPlugin } from '#imports'; - -export default defineNuxtPlugin((nuxtApp) => { - const { healthHost } = nuxtApp.$config.public; - - const health = axios.create({ - baseURL: healthHost, - }); - - return { - provide: { - health, - }, - }; -}); diff --git a/src/frontend/public/example.csv b/src/frontend/public/example.csv deleted file mode 100644 index 2d6b295e..00000000 --- a/src/frontend/public/example.csv +++ /dev/null @@ -1,1011 +0,0 @@ -doi -10.3390/s19071619 -10.3390/su8090895 -10.3989/ris.2013.i1.505 -10.1007/s004390050363 -10.4000/studifrancesi.30097 -10.17576/geo-2019-1502-09 -10.4055/cios.2014.6.1.62 -10.22203/ecm.v006a02 -10.1253/circj.cj-17-1281 -10.22201/fq.18708404e.2018.4.64701 -10.1590/s0103-90162013000500006 -10.22201/fq.18708404e.2018.4.65745 -10.22201/ia.01851101p.2019.55.01.02 -10.22201/ia.14052059p.2019.51.06 -10.3389/fnins.2021.652552 -10.22201/ib.20078706e.2008.002.563 -10.5771/9783748909620 -10.1103/physrevstab.6.114801 -10.22201/ib.9786070271854e2015 -10.22201/ie.20074484e.1997.2.1.115 -10.1103/physrevlett.104.184502 -10.22201/ie.20074484e.1997.2.1.117 -10.1016/j.aspen.2020.10.009 -10.1002/bjs.1800570627 -10.1016/j.jeconom.2010.03.007 -10.1007/s41970-018-0045-2 -10.1051/0004-6361/201220248 -10.1051/0004-6361/201220256 -10.22201/ie.20074484e.1997.2.1.119 -10.1128/aem.01914-12 -10.21203/rs.3.rs-198787/v1 -10.1128/aem.01931-07 -10.1128/aem.01943-08 -10.1128/aem.01945-06 -10.1128/aem.01954-12 -10.1128/ec.05184-11 -10.1128/genomea.00376-14 -10.1128/genomea.01005-13 -10.1051/0004-6361/201321695 -10.1088/0004-637x/804/2/117 -10.1515/ahr-2016-0012 -10.15381/rivep.v30i1.15673 -10.7202/016182ar -10.22201/ie.20074484e.1997.2.1.75 -10.1128/genomea.01019-15 -10.4000/studifrancesi.32957 -10.1128/genomea.01542-17 -10.1590/s0102-79722001000200009 -10.3390/s16020266 -10.1093/molbev/msaa311 -10.3989/egeol.91473-4419 -10.1371/journal.pone.0248369 -10.1111/1759-7714.13706 -10.4102/aveh.v70i4.117 -10.1016/j.tet.2013.06.052 -10.4000/studifrancesi.29881 -10.4000/studifrancesi.30267 -10.22201/ie.20074484e.1998.3.1.59 -10.5040/9781350032675.ch-013 -10.1007/s10489-021-02291-9 -10.22201/ie.20074484e.1998.3.1.67 -10.1016/j.envpol.2019.112976 -10.1126/science.aau8461 -10.1016/j.respe.2019.08.002 -10.22201/ie.20074484e.1999.4.1.77 -10.1128/aac.01818-09 -10.21236/ada400633 -10.1093/sleep/zsaa030 -10.1021/la903052t -10.4000/studifrancesi.30251 -10.1016/j.foodres.2019.108737 -10.22260/isarc2016/0120 -10.1128/jb.00791-15 -10.22260/isarc2017/0001 -10.46743/2160-3715/2018.2934 -10.1128/jb.00798-10 -10.1128/jb.00801-10 -10.4000/studifrancesi.30438 -10.1128/jb.00838-08 -10.22260/isarc2017/0009 -10.1093/humrep/dep308 -10.22260/isarc2017/0010 -10.46743/2160-3715/2018.3118 -10.46743/2160-3715/2018.3169 -10.22260/isarc2017/0016 -10.3390/app9091843 -10.22260/isarc2017/0020 -10.1128/jb.00847-06 -10.22260/isarc2017/0022 -10.46743/2160-3715/2018.3180 -10.4000/studifrancesi.30436 -10.46743/2160-3715/2018.3209 -10.46743/2160-3715/2018.3242 -10.1371/journal.pcbi.1008854.s008 -10.5220/0006422104370443 -10.46743/2160-3715/2018.3259 -10.1002/cjoc.201200189 -10.46743/2160-3715/2018.3297 -10.1021/ct500566k -10.1016/j.jcis.2019.01.109 -10.46743/2160-3715/2018.3312 -10.22260/isarc2017/0024 -10.46743/2160-3715/2018.3358 -10.5860/choice.46-6298 -10.22260/isarc2017/0032 -10.1021/la9510745 -10.1128/jb.179.14.4513-4522.1997 -10.14712/23363398.2017.22 -10.5194/amt-11-5489-2018 -10.22260/isarc2017/0038 -10.4000/studifrancesi.32963 -10.5194/bg-2018-207 -10.5194/bg-5-407-2008 -10.1128/jb.179.15.4741-4746.1997 -10.22260/isarc2017/0040 -10.22260/isarc2017/0044 -10.22260/isarc2017/0046 -10.5194/bg-5-523-2008 -10.22260/isarc2017/0053 -10.5194/bgd-10-8611-2013 -10.1055/s-0033-1358369 -10.22260/isarc2017/0059 -10.7554/elife.43676 -10.22260/isarc2017/0060 -10.22260/isarc2017/0064 -10.4000/studifrancesi.30058 -10.1128/jcm.02861-13 -10.22260/isarc2017/0070 -10.4000/studifrancesi.30091 -10.1128/jcm.03068-13 -10.22260/isarc2017/0075 -10.22260/isarc2017/0078 -10.4000/studifrancesi.30153 -10.1111/j.1095-8339.1996.tb00757.x -10.1128/jcm.03094-14 -10.1128/jcm.03105-15 -10.1006/jmaa.2000.7104 -10.1128/jcm.03108-14 -10.1111/j.1708-8305.1994.tb00602.x -10.22260/isarc2017/0080 -10.1016/j.msea.2009.03.078 -10.22260/isarc2017/0081 -10.3389/fpubh.2018.00054 -10.22260/isarc2017/0085 -10.1128/jcm.39.2.631-635.2001 -10.3389/fchem.2019.00373 -10.1007/978-3-642-13495-1_52 -10.2166/9781789062106_xxi -10.1016/j.colsurfa.2019.124166 -10.1111/ppl.13413 -10.22260/isarc2017/0089 -10.1128/jcm.39.3.990-994.2001 -10.1128/jcm.42.9.4209-4213.2004 -10.3390/bios6030041 -10.1128/jcm.42.9.4329-4331.2004 -10.1128/jcm.44.4.1224-1228.2006 -10.3390/bios7030033 -10.1136/bmj.j3932 -10.14199/ppp-2015-005 -10.1051/0004-6361/201014837 -10.1128/jcm.44.4.1509-1518.2006 -10.22260/isarc2017/0095 -10.1140/epjh/e2013-40018-4 -10.1128/jmbe.v17i3.1243 -10.2169/internalmedicine.55.4418 -10.1143/jpsj.81.064711 -10.22260/isarc2017/0097 -10.3390/medsci7040056 -10.1055/b-006-160132 -10.1128/jmbe.v19i1.1435 -10.1073/pnas.76.6.2522 -10.22260/isarc2017/0101 -10.1128/jmbe.v20i1.1635 -10.7903/cmr.409 -10.22260/isarc2017/0107 -10.22260/isarc2017/0109 -10.1128/jvi.00644-11 -10.1128/jvi.00652-13 -10.22260/isarc2017/0111 -10.22260/isarc2017/0117 -10.22260/isarc2017/0124 -10.1051/0004-6361/201014922 -10.22260/isarc2017/0130 -10.22260/isarc2017/0132 -10.2139/ssrn.310240 -10.22260/isarc2017/0134 -10.22260/isarc2017/0139 -10.1128/jvi.00661-06 -10.29171/azu_acku_ds485_b21_t467_1876 -10.1128/jvi.01865-18 -10.1128/mcb.00917-10 -10.1128/mcb.00922-10 -10.11646/zootaxa.3613.5.5 -10.30837/2522-9818.2019.7.113 -10.22260/isarc2017/0143 -10.3390/ijms20071672 -10.22260/isarc2017/0149 -10.19062/2247-3173.2017.19.2.31 -10.22260/isarc2018/0003 -10.1371/journal.pone.0248369.s002 -10.5935/0103-507x.20190014 -10.22260/isarc2018/0005 -10.22260/isarc2018/0008 -10.1155/2020/6435043 -10.22260/isarc2018/0011 -10.22260/isarc2018/0018 -10.22260/isarc2018/0020 -10.1177/097380100800200404 -10.22260/isarc2018/0022 -10.22260/isarc2018/0025 -10.1002/9781119081418.ch44 -10.1177/1715163521992037 -10.3390/cryst8110401 -10.1055/s-0034-1373782 -10.22260/isarc2018/0028 -10.3389/fspas.2017.00049 -10.33830/jp.v22i1.1431.2021 -10.22260/isarc2018/0030 -10.22260/isarc2018/0032 -10.1016/j.asr.2019.03.031 -10.1016/j.jsat.2012.08.005 -10.22260/isarc2018/0034 -10.3897/zookeys.609.8852 -10.3897/zookeys.506.9796 -10.22260/isarc2018/0039 -10.22260/isarc2018/0041 -10.22260/isarc2018/0045 -10.22260/isarc2018/0048 -10.22260/isarc2018/0051 -10.22260/isarc2018/0054 -10.2754/avb201483s10s45 -10.22260/isarc2018/0056 -10.1021/ja9100886 -10.5194/acp-17-13017-2017 -10.1289/ehp.01109983 -10.1051/0004-6361/201937362 -10.1007/s00199-013-0796-5 -10.24138/jcomss.v7i3.175 -10.1029/2000gl011599 -10.29407/jetar.v1i1.277 -10.22260/isarc2018/0058 -10.1002/anie.201801122 -10.1111/j.1757-1707.2010.01031.x -10.1063/1.5050633 -10.1111/nph.12381 -10.22260/isarc2018/0060 -10.5186/aasfm.2010.3523 -10.5194/acp-3-1999-2003 -10.5194/acpd-14-21659-2014 -10.1016/j.arabjc.2021.103149 -10.22260/isarc2018/0062 -10.22260/isarc2018/0066 -10.22260/isarc2018/0069 -10.5194/bg-2019-489 -10.22260/isarc2018/0073 -10.3329/baj.v18i2.28899 -10.5194/nhess-1-93-2001 -10.5194/nhess-18-1279-2018 -10.5194/nhess-18-1617-2018 -10.1016/j.idcr.2021.e01115 -10.5194/nhessd-3-3761-2015 -10.5194/osd-6-429-2009 -10.2307/1565632 -10.3892/ol.2015.3845 -10.1088/0004-6256/150/1/13 -10.22260/isarc2018/0077 -10.3390/cryst8110431 -10.22260/isarc2018/0086 -10.1002/psp.2018 -10.1016/j.tws.2014.07.002 -10.1007/978-3-319-67615-9_2 -10.1080/03031853.2001.9524950 -10.5194/acpd-4-1449-2004 -10.22260/isarc2018/0088 -10.1063/1.3517251 -10.22260/isarc2018/0097 -10.22260/isarc2018/0099 -10.1161/01.hyp.24.5.633 -10.1371/journal.pntd.0001204 -10.22260/isarc2018/0103 -10.18632/oncotarget.6737 -10.1049/iet-map.2020.0415 -10.1053/euhj.1998.1351 -10.22260/isarc2018/0106 -10.1371/journal.pone.0214672 -10.1086/377027 -10.22260/isarc2018/0108 -10.22260/isarc2018/0112 -10.1007/10704703_3 -10.22260/isarc2018/0116 -10.6000/2292-2598.2020.08.03.25 -10.3389/fvets.2018.00024 -10.3390/f10040310 -10.1021/acs.langmuir.6b02927 -10.22260/isarc2018/0118 -10.5012/bkcs.2003.24.5.653 -10.22266/ijies2012.1231.01 -10.22266/ijies2012.1231.03 -10.33476/jky.v27i1.647 -10.5114/aoms.2016.62905 -10.1017/s135048270200110x -10.1016/s0006-3495(93)81340-7 -10.22260/isarc2018/0121 -10.22260/isarc2018/0123 -10.1029/2000gl011533 -10.22260/isarc2018/0129 -10.22260/isarc2018/0134 -10.1038/s41586-018-0222-z -10.3346/jkms.1986.1.1.37 -10.1108/s1479-364420150000017015 -10.22260/isarc2018/0136 -10.22260/isarc2018/0138 -10.22260/isarc2018/0141 -10.22260/isarc2018/0143 -10.1088/1126-6708/2008/04/069 -10.1155/2013/438384 -10.22260/isarc2018/0145 -10.5194/acp-3-1981-2003 -10.5194/acp-8-3149-2008 -10.5194/amt-11-5507-2018 -10.22260/isarc2018/0146 -10.22260/isarc2018/0149 -10.5194/amt-11-5549-2018 -10.5194/amt-11-5687-2018 -10.5194/bg-2018-198 -10.22260/isarc2018/0151 -10.22260/isarc2018/0153 -10.1007/s11214-017-0449-2 -10.5194/esdd-4-279-2013 -10.1111/j.1444-0938.1941.tb01195.x -10.5194/fr-21-67-2018 -10.5194/nhess-18-1351-2018 -10.5194/nhess-18-1427-2018 -10.22260/isarc2018/0154 -10.5194/nhess-19-41-2019 -10.1155/2020/5123830 -10.5194/nhessd-3-319-2015 -10.22260/isarc2018/0157 -10.22260/isarc2018/0158 -10.22266/ijies2012.9030.02 -10.4000/ree.3013 -10.22266/ijies2013.0331.01 -10.22266/ijies2013.0630.01 -10.21272/mmi.2019.4-29 -10.1007/978-3-319-55486-0_2 -10.22260/isarc2018/0160 -10.1080/1354750x.2021.1910343 -10.1038/ncomms10776 -10.4000/books.editionscnrs.2984 -10.1371/journal.pcbi.1008847.s001 -10.22260/isarc2018/0163 -10.22260/isarc2018/0166 -10.22260/isarc2018/0169 -10.2307/j.ctvwrm691.28 -10.22260/isarc2019/0001 -10.1128/aac.01120-16 -10.1128/aac.01124-10 -10.1128/aac.01129-17 -10.1128/aac.01136-15 -10.22260/isarc2019/0003 -10.1155/2017/6301026 -10.1128/aac.01479-15 -10.1128/aac.01481-13 -10.1155/s0161171203210516 -10.22260/isarc2019/0008 -10.1080/03066150.2016.1176023 -10.3390/e21040365 -10.5958/2349-2996.2018.00056.3 -10.1109/mcc.2000.846196 -10.3390/ani9030096 -10.1128/aac.01508-09 -10.35848/1347-4065/abe0a0 -10.1128/aac.01597-08 -10.1128/aac.01600-08 -10.1016/j.ijepes.2019.03.065 -10.1289/ehp.0800126 -10.1111/j.1574-6941.2012.01367.x -10.22260/isarc2019/0010 -10.22260/isarc2019/0016 -10.2131/jts.34.611 -10.1128/aem.00120-10 -10.22260/isarc2019/0021 -10.22260/isarc2019/0024 -10.22260/isarc2019/0027 -10.1128/aem.01905-15 -10.1128/aem.01912-08 -10.1128/aem.01944-08 -10.13172/2052-7829-1-3-846 -10.22266/ijies2014.0630.02 -10.1128/aem.01952-09 -10.1128/ec.05106-11 -10.1103/physrevd.99.096018 -10.1128/ec.2.4.678-689.2003 -10.1128/ec.3.1.91-99.2004 -10.1128/genomea.00368-18 -10.1128/genomea.01012-15 -10.1128/genomea.01329-14 -10.1128/genomea.01331-15 -10.1128/genomea.01539-16 -10.22266/ijies2014.1231.02 -10.3928/01477447-20190906-05 -10.1128/iai.00416-15 -10.1128/iai.00423-07 -10.1128/iai.00429-18 -10.1128/iai.00442-07 -10.1128/iai.00473-12 -10.1128/jb.00304-15 -10.1128/jb.00390-09 -10.1016/j.janxdis.2006.10.004 -10.1128/jb.01492-08 -10.1042/bj20101427 -10.18413/2712-746x-2020-45-4-623-632 -10.22260/isarc2019/0031 -10.1155/2019/8054640 -10.22260/isarc2019/0033 -10.22260/isarc2019/0038 -10.4000/clio.112 -10.1051/0004-6361/201116548 -10.2340/00015555-0919 -10.1161/jaha.118.009442 -10.22260/isarc2019/0044 -10.1099/jmm.0.45997-0 -10.22266/ijies2015.0930.01 -10.3889/oamjms.2019.617 -10.22260/isarc2019/0046 -10.1201/b16378-7 -10.4236/wjv.2015.51002 -10.1002/mbo3.941 -10.22260/isarc2019/0048 -10.1093/aje/kwq197 -10.1016/0029-554x(70)90052-2 -10.22260/isarc2019/0050 -10.22260/isarc2019/0054 -10.7202/902095ar -10.1371/journal.pone.0065137 -10.1371/journal.pgen.1007774 -10.22260/isarc2019/0056 -10.22260/isarc2019/0061 -10.1371/journal.pmed.1002257 -10.14507/epaa.v23.1915 -10.1371/journal.pmed.1002260 -10.14789/jmj.62.s78 -10.18011/bioeng2014v8n1p65-72 -10.20431/2347-3134.0506001 -10.1016/j.scitotenv.2018.10.259 -10.22260/isarc2019/0063 -10.20546/ijcmas.2019.807.213 -10.1371/journal.pmed.1002807 -10.22266/ijies2015.1231.01 -10.22260/isarc2019/0067 -10.1016/0197-4580(91)90081-t -10.22260/isarc2019/0069 -10.2136/sh1978.1.0013 -10.1371/journal.pone.0186465 -10.1371/journal.pone.0050219 -10.22260/isarc2019/0075 -10.5794/jjoms.41.705 -10.4319/lo.2007.52.2.0912 -10.1371/journal.pone.0210031 -10.5194/acp-8-2975-2008 -10.5194/acp-9-9349-2009 -10.1007/3-540-56282-6_20 -10.1007/s10068-020-00875-8 -10.5194/acpd-14-22045-2014 -10.4236/jmmce.2012.1110097 -10.5194/amt-11-5673-2018 -10.5194/amt-11-569-2018 -10.1190/geo2015-0387.1 -10.3390/brainsci3010344 -10.22266/ijies2015.1231.03 -10.22266/ijies2016.0930.01 -10.1093/hmg/ddab105 -10.22260/isarc2019/0077 -10.22260/isarc2019/0084 -10.22260/isarc2019/0086 -10.5194/bg-2018-201 -10.1088/2058-6272/aab490 -10.1128/aac.01249-16 -10.1051/matecconf/201819401034 -10.5194/bg-2019-476 -10.5194/bg-5-707-2008 -10.5040/9781628927139 -10.22260/isarc2019/0088 -10.1152/ajpheart.2000.279.5.h2124 -10.1088/1757-899x/777/1/011001 -10.22260/isarc2019/0091 -10.1558/eph.v20i2.105 -10.22260/isarc2019/0095 -10.12927/hcq.2016.24703 -10.1093/icvts/ivx352 -10.1155/2015/764187 -10.1371/journal.pntd.0008298 -10.22260/isarc2019/0106 -10.1051/0004-6361/201015251 -10.20944/preprints202102.0379.v1 -10.1002/cjce.5450730418 -10.1128/jb.00605-07 -10.1039/b918311f -10.5369/jsst.2012.21.1.59 -10.22260/isarc2019/0109 -10.1371/journal.pone.0201390 -10.22260/isarc2019/0119 -10.1128/jb.179.1.135-140.1997 -10.22260/isarc2019/0121 -10.22260/isarc2019/0123 -10.1128/jb.183.24.7094-7101.2001 -10.22266/ijies2016.0930.02 -10.18041/entramado.2016v12n1.23124 -10.1002/jcu.1870210903 -10.22266/ijies2016.0930.03 -10.22266/ijies2016.0930.05 -10.21203/rs.3.rs-238650/v1 -10.1155/2020/6662389 -10.21203/rs.2.23128/v5 -10.22260/isarc2019/0127 -10.1016/j.jalgebra.2016.09.019 -10.1371/journal.pone.0011574 -10.1155/2020/4360184 -10.22260/isarc2019/0129 -10.22260/isarc2019/0132 -10.3390/catal8020058 -10.22260/isarc2019/0135 -10.1073/pnas.80.17.5330 -10.1016/j.ocecoaman.2019.104864 -10.1021/acs.langmuir.9b01833 -10.1121/1.3249303 -10.1128/jb.00553-16 -10.22260/isarc2019/0138 -10.22260/isarc2019/0139 -10.22260/isarc2019/0146 -10.22260/isarc2019/0152 -10.1126/sciadv.aay8507 -10.22260/isarc2019/0155 -10.22260/isarc2019/0158 -10.1126/science.1056496 -10.3745/jips.2005.1.1.009 -10.1523/jneurosci.15-10-06846.1995 -10.1126/science.1057022 -10.1371/journal.pone.0040655 -10.3329/jce.v30i1.34793 -10.22260/isarc2019/0160 -10.3390/cells6040037 -10.1371/journal.pone.0135360 -10.1126/science.1142021 -10.1061/(asce)0899-1561(2009)21:6(286) -10.21032/jhis.2018.43.4.274 -10.1126/science.1216556 -10.22203/ecm.v031a21 -10.1002/jlcr.2580220809 -10.1007/978-3-540-70575-8_5 -10.1155/2013/569161 -10.1007/s00041-002-0001-x -10.21203/rs.3.rs-221618/v1 -10.1126/science.270.5240.1347 -10.1155/2020/1346051 -10.1080/10852352.2014.881172 -10.1126/science.270.5242.1633 -10.1016/j.nima.2019.03.071 -10.3390/ijms21249669 -10.22260/isarc2019/0164 -10.22260/isarc2019/0177 -10.22260/isarc2019/0179 -10.22263/2312-4156.2016.4.18 -10.22266/ijies2008.0331.05 -10.1017/s0074180900158371 -10.22266/ijies2008.0630.01 -10.22266/ijies2008.0630.03 -10.1172/jci38468 -10.1128/aem.71.4.1865-1869.2005 -10.5040/9781350052444-0789 -10.2478/ijame-2019-0004 -10.22266/ijies2008.0630.05 -10.1128/aem.71.4.1941-1945.2005 -10.22266/ijies2008.0930.01 -10.1128/cvi.00275-09 -10.1128/cvi.00457-14 -10.5916/jkosme.2018.42.9.719 -10.1128/ec.00065-08 -10.1128/ec.00267-09 -10.4314/jab.v81i1.3 -10.1128/ec.4.7.1203-1210.2005 -10.22266/ijies2008.1231.01 -10.1128/genomea.00173-13 -10.1038/ncomms4130 -10.1128/genomea.00174-17 -10.1093/oxfordjournals.jhered.a023131 -10.1128/genomea.00175-17 -10.1128/genomea.00311-17 -10.1371/journal.pone.0068127 -10.22266/ijies2009.0331.02 -10.22266/ijies2009.0630.01 -10.1093/plankt/21.9.1725 -10.22266/ijies2009.0630.04 -10.1128/jb.01946-14 -10.1103/physrevb.87.174412 -10.1103/physrevlett.95.117005 -10.1128/jb.01956-05 -10.1111/j.1467-9469.2011.00738.x -10.22266/ijies2010.0331.01 -10.1136/bmj.301.6766.1480 -10.1016/j.ecolecon.2019.106426 -10.22266/ijies2010.0331.03 -10.12681/eadd/25784 -10.22266/ijies2010.0630.02 -10.22266/ijies2010.1231.01 -10.22266/ijies2010.1231.03 -10.22266/ijies2010.1231.05 -10.1016/j.apcata.2021.118139 -10.1016/j.apcata.2021.118143 -10.22266/ijies2011.0331.04 -10.4236/ce.2015.613147 -10.1016/j.apcatb.2021.120203 -10.5040/9781472546395.0009 -10.1038/nbt.2601 -10.22266/ijies2011.0630.01 -10.1073/pnas.1304097110 -10.22266/ijies2011.0630.05 -10.1108/00346659910290222 -10.1016/j.apcatb.2021.120207 -10.22266/ijies2011.0930.03 -10.22266/ijies2012.0331.03 -10.1007/s11060-012-0973-6 -10.22266/ijies2012.0630.02 -10.22266/ijies2012.1231.02 -10.13187/ejced.2019.1.136 -10.1371/journal.pbio.2001307 -10.5580/d9b -10.1128/jb.184.7.2045-2049.2002 -10.22266/ijies2013.0630.02 -10.1128/jcm.00619-11 -10.22266/ijies2014.0331.01 -10.22266/ijies2014.1231.01 -10.22266/ijies2014.9030.01 -10.1063/1.1306910 -10.1073/pnas.2008791117 -10.1042/cs20060043 -10.1128/jcm.01061-10 -10.4236/ojms.2015.51012 -10.25047/jtit.v5i1.73 -10.22266/ijies2015.0630.02 -10.22266/ijies2015.1231.02 -10.22260/isarc2016/0052 -10.22260/isarc2016/0053 -10.22260/isarc2016/0058 -10.1371/journal.pgen.1005041 -10.1371/journal.pmed.1002245 -10.1371/journal.pmed.1002781 -10.1484/j.rea.5.104103 -10.22260/isarc2016/0061 -10.3727/096504018x15267574931782 -10.22260/isarc2016/0071 -10.1590/s0104-06182012000100002 -10.22260/isarc2016/0080 -10.22260/isarc2016/0081 -10.22260/isarc2016/0087 -10.1021/acs.energyfuels.0c03860 -10.15448/1980-6523.2014.2.12666 -10.1590/s1415-43662013000700001 -10.5713/ajas.18.0264 -10.3847/1538-3881/aab1f6 -10.1128/genomea.00188-14 -10.22260/isarc2016/0090 -10.22266/ijies2016.0930.06 -10.1371/journal.pone.0152394 -10.1371/journal.pntd.0004076 -10.1007/978-3-0348-0043-3_4 -10.1161/jaha.112.002832 -10.1002/cphc.201402895 -10.2134/agronj2008.0139s -10.22260/isarc2016/0095 -10.22260/isarc2016/0100 -10.22260/isarc2016/0105 -10.22266/ijies2016.0930.07 -10.1051/0004-6361/201015772 -10.1037/a0014611 -10.4054/demres.2004.s3.1 -10.1117/12.632157 -10.22260/isarc2016/0114 -10.30837/2522-9818.2019.7.059 -10.22260/isarc2016/0116 -10.22260/isarc2016/0119 -10.5130/cjlg.v0i6.1623 -10.1016/j.parco.2018.12.007 -10.22260/isarc2016/0125 -10.3390/sym11040460 -10.1287/mnsc.1080.0886 -10.22260/isarc2016/0126 -10.1088/1361-6420/abd29a -10.22260/isarc2016/0128 -10.22260/isarc2016/0130 -10.22260/isarc2016/0132 -10.22260/isarc2017/0003 -10.22260/isarc2017/0004 -10.5465/amj.2011.59215082 -10.1073/pnas.39.9.924 -10.22260/isarc2017/0006 -10.22260/isarc2017/0015 -10.22260/isarc2017/0021 -10.1122/1.1567751 -10.1126/science.1217416 -10.21608/resoncol.2017.656.1016 -10.22260/isarc2017/0023 -10.3389/fpls.2017.01539 -10.1126/scisignal.aaf2223 -10.1128/aac.02175-18 -10.22260/isarc2017/0025 -10.22260/isarc2017/0030 -10.3389/fpsyg.2019.00588 -10.5799/ahinjs.01.2014.02.0416 -10.22260/isarc2017/0037 -10.1021/jp025626l -10.1073/pnas.1602214113 -10.22260/isarc2017/0039 -10.32725/jab.2006.011 -10.1016/j.trc.2014.09.015 -10.1039/c8cp06992a -10.22260/isarc2017/0041 -10.1128/aac.37.2.178 -10.22260/isarc2017/0047 -10.22586/csp.v52i3.11167 -10.1109/cvpr.2018.00132 -10.1021/acsenergylett.9b02478 -10.22260/isarc2017/0055 -10.3928/15428877-20120920-02 -10.1063/5.0021818 -10.1128/aac.37.4.775 -10.22260/isarc2017/0058 -10.1051/rnd:19940364 -10.11118/actaun201260040165 -10.22260/isarc2017/0069 -10.1016/j.conbuildmat.2019.08.019 -10.1016/j.drugalcdep.2019.01.020 -10.1016/j.nima.2019.03.035 -10.14720/aas.2018.111.2.07 -10.18616/ce.v0i0.2946 -10.1128/cvi.00133-10 -10.1128/ec.00113-07 -10.1128/genomea.00163-14 -10.1093/intqhc/mzv026 -10.1128/genomea.01082-15 -10.22260/isarc2017/0071 -10.1190/geo2012-0334.1 -10.1093/fampra/cml054 -10.3989/aeamer.2002.v59.i2.189 -10.22260/isarc2017/0083 -10.1177/2324709612473274 -10.1016/j.ymssp.2019.02.018 -10.1099/00207713-46-3-792 -10.1177/2042098616646726 -10.6113/jpe.2016.16.2.786 -10.22260/isarc2017/0086 -10.1890/10-0318.1 -10.22260/isarc2017/0088 -10.22260/isarc2017/0093 -10.1042/bj20101360 -10.22260/isarc2017/0096 -10.22260/isarc2017/0098 -10.22260/isarc2017/0103 -10.1140/epjs/s11734-021-00082-4 -10.22260/isarc2017/0110 -10.1007/jhep02(2021)163 -10.22260/isarc2017/0120 -10.1016/j.tcs.2017.01.028 -10.22260/isarc2017/0125 -10.1016/j.enconman.2007.01.023 -10.22260/isarc2017/0137 -10.22260/isarc2017/0147 -10.22260/isarc2017/0151 -10.1161/01.str.30.9.1875 -10.3390/12071410 -10.1177/0192512107088390 -10.22260/isarc2018/0004 -10.22260/isarc2018/0007 -10.22260/isarc2018/0009 -10.1080/15384047.2015.1056416 -10.22260/isarc2018/0012 -10.33588/fem.62.258 -10.22260/isarc2018/0016 -10.22260/isarc2018/0021 -10.1128/iai.69.4.2621-2629.2001 -10.1017/s1748499517000124 -10.1128/iai.69.5.3110-3119.2001 -10.22260/isarc2018/0024 -10.1677/joe-06-0076 -10.1128/iai.69.5.3295-3304.2001 -10.2134/jeq2007.0310 -10.1163/9789004217881_020 -10.22260/isarc2018/0027 -10.22260/isarc2018/0029 -10.22260/isarc2018/0031 -10.5802/smai-jcm.52 -10.22260/isarc2018/0033 -10.1007/978-3-319-57123-2_4 -10.1128/jb.182.19.5606-5610.2000 -10.22260/isarc2018/0035 -10.1128/jb.187.18.6281-6289.2005 -10.1128/jcm.01231-14 -10.22260/isarc2018/0040 -10.1056/nejmoa1005372 -10.1128/jcm.01245-11 -10.1128/jcm.01248-12 -10.22260/isarc2018/0044 -10.1128/jcm.01250-09 -10.22260/isarc2018/0047 -10.1128/jcm.01849-09 -10.1128/jcm.01854-07 -10.22260/isarc2018/0049 -10.1128/jcm.02483-14 -10.22260/isarc2018/0053 -10.1049/el:20070162 -10.1007/s11442-015-1184-9 -10.3928/00220124-20070901-09 -10.1128/jcm.06221-11 -10.22266/ijies2016.0930.08 -10.1159/000381911 -10.1128/jvi.00713-10 -10.22266/ijies2016.0930.10 -10.1128/mcb.19.8.5685 -10.22266/ijies2016.0930.11 -10.22260/isarc2018/0055 -10.1016/j.smrv.2021.101490 -10.22260/isarc2018/0057 -10.1016/0020-711x(80)90151-2 -10.1371/journal.pone.0137890 -10.1137/090772514 -10.1016/j.jallcom.2021.159740 -10.22260/isarc2018/0061 -10.22260/isarc2018/0064 -10.22260/isarc2018/0067 -10.22260/isarc2018/0072 -10.1016/j.wombi.2018.11.012 -10.22260/isarc2018/0074 -10.24310/abm.v30i0.7209 -10.1130/g23860a.1 -10.22260/isarc2018/0084 -10.1134/s0001434619070034 -10.22260/isarc2018/0087 -10.22260/isarc2018/0091 -10.1016/j.tcm.2021.04.001 -10.22260/isarc2018/0098 -10.14348/molcells.2015.0052 -10.22260/isarc2018/0100 -10.22260/isarc2018/0105 -10.1590/s0103-166x2013000200011 -10.3406/cea.1989.2142 -10.22260/isarc2018/0107 -10.18535/ijecs/v5i8.54 -10.18542/amazonica.v2i1.347 -10.1590/s0037-86821980000100008 -10.1038/063396c0 -10.1051/0004-6361/202039071 -10.2147/jpr.s118945 -10.22260/isarc2018/0109 -10.22260/isarc2018/0117 -10.22260/isarc2018/0120 -10.4000/laboratoireitalien.72 -10.17721/2227-1481.7.23-29 -10.22260/isarc2018/0122 -10.1007/s10751-016-1374-6 -10.23865/noasp.74 -10.4103/0975-1483.62213 -10.1007/s41906-021-1006-x -10.22260/isarc2018/0124 -10.1006/jagm.1995.1041 -10.22260/isarc2018/0127 -10.22260/isarc2018/0135 -10.22260/isarc2018/0137 -10.3928/01477447-20190906-02 -10.22260/isarc2018/0140 -10.22260/isarc2018/0144 -10.1541/ieejeiss.129.1949 -10.1126/scirobotics.aaw6326 -10.22260/isarc2018/0147 -10.1128/aac.00829-05 -10.1001/archotol.134.10.1094 -10.1128/aac.00829-19 -10.22260/isarc2018/0152 -10.22260/isarc2018/0156 -10.1128/aem.06444-11 -10.1128/aem.69.9.5463-5471.2003 -10.1128/genomea.01115-16 -10.1128/iai.02016-05 -10.22260/isarc2018/0159 -10.1128/iai.02020-14 -10.1042/bj20101769 -10.1080/01402380902779048 -10.22260/isarc2018/0161 -10.1128/iai.06174-11 -10.1128/iai.06176-11 -10.22260/isarc2018/0167 -10.1093/ageing/27.2.123 -10.1073/pnas.1313548110 -10.22260/isarc2019/0002 -10.13065/jksdh.2012.12.1.157 -10.1080/0141620910140108 -10.22260/isarc2019/0007 -10.22266/ijies2016.0930.15 -10.3390/computation3030479 -10.1128/iai.06184-11 -10.22260/isarc2019/0015 -10.1128/iai.06308-11 -10.1097/sla.0b013e3182891efb -10.22266/ijies2016.0930.16 -10.1093/comjnl/bxs137 -10.22260/isarc2019/0022 -10.22260/isarc2019/0025 -10.22266/ijies2016.1231.02 -10.1111/j.1527-3458.1998.tb00073.x -10.1128/iai.36.2.450-454.1982 -10.1128/iai.71.6.3357-3360.2003 -10.1504/ijemr.2018.10009113 -10.1890/0012-9658(2003)084[0791:eopsap]2.0.co;2 -10.1136/bjsm.2004.015271 -10.1128/iai.71.6.3512-3520.2003 -10.1155/2008/782358 -10.22266/ijies2016.1231.03 -10.1128/iai.72.7.3914-3924.2004 -10.1128/iai.72.7.3932-3940.2004 -10.1128/iai.72.7.4240-4248.2004 -10.22266/ijies2016.1231.04 -10.1128/iai.72.8.4401-4409.2004 -10.1128/iai.72.8.4432-4438.2004 -10.22266/ijies2016.1231.05 -10.1128/jcm.42.9.4386-4389.2004 -10.1111/j.1365-246x.2012.05533.x -10.1111/jvim.15287 -10.1111/jvim.15291 -10.1128/jcm.44.4.1347-1351.2006 -10.1128/jmbe.v20i1.1669 -10.3390/a10030082 -10.11606/2179-0892.ra.2017.137322 -10.22260/isarc2019/0030 -10.1101/819987 -10.22260/isarc2019/0037 -10.21500/16578031.220 -10.4148/2334-4415.1197 -10.22260/isarc2019/0040 -10.1186/s13550-021-00771-0 -10.22260/isarc2019/0045 -10.1128/jvi.01853-16 -10.1128/jvi.01868-17 -10.2514/6.1991-4090 -10.1128/mbio.00098-13 -10.1128/mbio.00103-12 -10.22260/isarc2019/0047 -10.1128/mbio.00105-15 -10.1128/mbio.00114-15 -10.1128/mbio.00115-13 -10.1128/mbio.00118-12 -10.4236/ojs.2016.65070 -10.1128/mbio.00129-15 -10.1128/mbio.00139-12 -10.1128/mbio.00144-13 -10.23865/noasp.80 -10.1128/mcb.00086-19 -10.1016/j.cortex.2020.04.002 -10.1128/mcb.00087-14 -10.1128/mcb.00266-15 -10.1128/mcb.00420-13 -10.1371/journal.pone.0077108 -10.22260/isarc2019/0049 -10.1093/hmg/ddab103 -10.22260/isarc2019/0053 -10.1016/j.dsr.2020.103227 -10.3847/1538-4357/aab719 -10.1051/epjconf/20136205005 -10.1542/peds.101.5.e12 -10.1016/j.envint.2020.106248 -10.1155/2013/260351 -10.1016/j.lpm.2019.04.005 -10.1016/j.jcrc.2018.06.002 -10.1016/j.ijpvp.2019.02.011 -10.3889/oamjms.2018.182 -10.1016/j.conbuildmat.2019.117340 -10.1155/2020/1062325 -10.22260/isarc2019/0055 -10.31618/esu.2413-9335.2020.5.81.1166 -10.22260/isarc2019/0059 -10.1249/mss.0b013e3181677530 -10.22260/isarc2019/0062 -10.22260/isarc2019/0066 -10.21236/ada247549 -10.1364/oe.18.015484 -10.3389/fphar.2018.00348 -10.1590/s0103-84782014000600010 -10.22260/isarc2019/0068 -10.1590/s1414-462x2013000200009 -10.22260/isarc2019/0073 -10.5944/rppc.vol.2.num.2.1997.3837 -10.22260/isarc2019/0076 -10.1155/2021/5529486 -10.22146/gamaijb.9292 -10.22260/isarc2019/0078 -10.1177/2514848620945310 -10.1002/lt.25925 -10.1074/jbc.ra119.011766 -10.1111/j.1440-1797.2009.01116.x -10.22260/isarc2019/0081 -10.22260/isarc2019/0085 -10.3390/ijerph13040364 -10.1093/aje/kwn279 -10.3390/en6020748 -10.3390/en6020884 -10.22260/isarc2019/0087 -10.1042/bj20150325 -10.22260/isarc2019/0090 -10.1128/jb.173.9.2800-2808.1991 -10.1523/jneurosci.0860-20.2020 -10.22260/isarc2019/0093 -10.22260/isarc2019/0098 \ No newline at end of file diff --git a/src/frontend/public/example.jsonl b/src/frontend/public/example.jsonl deleted file mode 100644 index 478344ef..00000000 --- a/src/frontend/public/example.jsonl +++ /dev/null @@ -1,1025 +0,0 @@ -{ "doi": "10.22260/isarc2019/0068" } -{ "doi": "10.1590/s1414-462x2013000200009" } -{ "doi": "10.22260/isarc2019/0073" } -{ "doi": "10.5944/rppc.vol.2.num.2.1997.3837" } -{ "doi": "10.22260/isarc2019/0076" } -{ "doi": "10.1155/2021/5529486" } -{ "doi": "10.22146/gamaijb.9292" } -{ "doi": "10.22260/isarc2019/0078" } -{ "doi": "10.1177/2514848620945310" } -{ "doi": "10.1002/lt.25925" } -{ "doi": "10.1074/jbc.ra119.011766" } -{ "doi": "10.1111/j.1440-1797.2009.01116.x" } -{ "doi": "10.22260/isarc2019/0081" } -{ "doi": "10.22260/isarc2019/0085" } -{ "doi": "10.3390/ijerph13040364" } -{ "doi": "10.1093/aje/kwn279" } -{ "doi": "10.3390/en6020748" } -{ "doi": "10.3390/en6020884" } -{ "doi": "10.22260/isarc2019/0087" } -{ "doi": "10.1042/bj20150325" } -{ "doi": "10.22260/isarc2019/0090" } -{ "doi": "10.1128/jb.173.9.2800-2808.1991" } -{ "doi": "10.1523/jneurosci.0860-20.2020" } -{ "doi": "10.22260/isarc2019/0093" } -{ "doi": "10.22260/isarc2019/0098" } -{ "doi": "10.3389/fnhum.2014.00785" } -{ "doi": "10.1002/uog.23647" } -{ "doi": "10.1128/jb.174.4.1179-1188.1992" } -{ "doi": "10.22260/isarc2019/0113" } -{ "doi": "10.22260/isarc2019/0115" } -{ "doi": "10.22260/isarc2019/0120" } -{ "doi": "10.31235/osf.io/dgq23" } -{ "doi": "10.31235/osf.io/y943w" } -{ "doi": "10.23865/noasp.89" } -{ "doi": "10.1049/iet-rsn.2016.0063" } -{ "doi": "10.22260/isarc2019/0122" } -{ "doi": "10.1038/s41598-017-05475-x" } -{ "doi": "10.1093/infdis/53.3.312" } -{ "doi": "10.1016/j.geomphys.2018.05.014" } -{ "doi": "10.1088/2515-7620/abef5d" } -{ "doi": "10.22260/isarc2019/0126" } -{ "doi": "10.1128/jb.175.2.503-509.1993" } -{ "doi": "10.1037/a0018912" } -{ "doi": "10.22260/isarc2019/0128" } -{ "doi": "10.22260/isarc2019/0131" } -{ "doi": "10.1093/shm/hkr051" } -{ "doi": "10.1088/0004-637x/693/2/l118" } -{ "doi": "10.1364/oe.22.028997" } -{ "doi": "10.1098/rstl.1686.0023" } -{ "doi": "10.22260/isarc2019/0133" } -{ "doi": "10.22260/isarc2019/0136" } -{ "doi": "10.1109/tip.2021.3058783" } -{ "doi": "10.22260/isarc2019/0140" } -{ "doi": "10.22260/isarc2019/0150" } -{ "doi": "10.22260/isarc2019/0151" } -{ "doi": "10.22260/isarc2019/0154" } -{ "doi": "10.5194/isprsarchives-xl-8-745-2014" } -{ "doi": "10.22260/isarc2019/0156" } -{ "doi": "10.22260/isarc2019/0159" } -{ "doi": "10.5539/gjhs.v7n5p208" } -{ "doi": "10.33767/osf.io/9frgd" } -{ "doi": "10.1002/chin.198919124" } -{ "doi": "10.1109/rivf48685.2020.9140776" } -{ "doi": "10.3389/fonc.2020.595527" } -{ "doi": "10.18260/1-2--6466" } -{ "doi": "10.1128/jvi.01356-06" } -{ "doi": "10.3389/fonc.2021.626659" } -{ "doi": "10.22260/isarc2019/0163" } -{ "doi": "10.1364/oe.15.005966" } -{ "doi": "10.1128/jb.177.21.6118-6125.1995" } -{ "doi": "10.1158/0008-5472.can-07-1356" } -{ "doi": "10.22260/isarc2019/0166" } -{ "doi": "10.22260/isarc2019/0169" } -{ "doi": "10.1063/5.0029716" } -{ "doi": "10.22260/isarc2019/0173" } -{ "doi": "10.1016/j.agsy.2019.102668" } -{ "doi": "10.22260/isarc2019/0178" } -{ "doi": "10.22263/2312-4156.2016.1.93" } -{ "doi": "10.1038/509030a" } -{ "doi": "10.7554/elife.19484" } -{ "doi": "10.1016/j.nutres.2007.03.006" } -{ "doi": "10.1007/s11614-020-00408-x" } -{ "doi": "10.4236/ojps.2021.111008" } -{ "doi": "10.1088/0004-637x/746/2/119" } -{ "doi": "10.22201/iij.24484873e.2016.146.10511" } -{ "doi": "10.1016/j.evolhumbehav.2016.05.001" } -{ "doi": "10.22201/iij.24484873e.2016.146.10515" } -{ "doi": "10.22201/iij.24484873e.2016.146.10516" } -{ "doi": "10.1088/0953-8984/24/30/305402" } -{ "doi": "10.22201/iij.24484881e.2017.36.10857" } -{ "doi": "10.22201/iij.24487872e.2016.16.521" } -{ "doi": "10.1093/bioinformatics/btu153" } -{ "doi": "10.1007/978-1-4419-5906-5_824" } -{ "doi": "10.1021/jo100462w" } -{ "doi": "10.22201/iij.24487872e.2018.18.12110" } -{ "doi": "10.5902/198050981650" } -{ "doi": "10.22201/iij.24487899e.2017.24.10815" } -{ "doi": "10.1016/j.spmi.2017.11.007" } -{ "doi": "10.22201/iij.24487899e.2017.24.10818" } -{ "doi": "10.1128/jb.184.24.6760-6767.2002" } -{ "doi": "10.22201/iij.24487910e.2013.3.10011" } -{ "doi": "10.1128/jb.184.24.6906-6917.2002" } -{ "doi": "10.5194/amt-11-2523-2018" } -{ "doi": "10.22201/iij.24487910e.2013.4.10037" } -{ "doi": "10.1128/jb.186.12.3777-3784.2004" } -{ "doi": "10.1128/jb.186.12.4046-4050.2004" } -{ "doi": "10.22201/iij.24487910e.2013.4.10041" } -{ "doi": "10.22201/iij.24487910e.2014.5.10052" } -{ "doi": "10.1136/jnnp.2003.026542" } -{ "doi": "10.22201/iij.24487910e.2014.6.10067" } -{ "doi": "10.1038/s41598-018-23915-0" } -{ "doi": "10.1061/(asce)mt.1943-5533.0002511" } -{ "doi": "10.1016/j.electacta.2018.10.184" } -{ "doi": "10.1016/s0168-9002(02)00430-8" } -{ "doi": "10.1103/physrevd.90.112016" } -{ "doi": "10.22201/iij.24487910e.2014.6.10078" } -{ "doi": "10.1109/ipdpsw.2012.11" } -{ "doi": "10.22201/iij.24487910e.2016.9.10100" } -{ "doi": "10.1002/mmng.200900010" } -{ "doi": "10.1111/nph.12375" } -{ "doi": "10.1109/wowmom.2011.5986202" } -{ "doi": "10.22201/iij.24487937e.2007.1.8030" } -{ "doi": "10.1140/epjc/s10052-019-7399-7" } -{ "doi": "10.1111/j.1151-2916.1988.tb05935.x" } -{ "doi": "10.1111/j.1444-0938.1973.tb00721.x" } -{ "doi": "10.22201/iij.24487937e.2007.1.8033" } -{ "doi": "10.22201/iij.24487937e.2007.1.8037" } -{ "doi": "10.1007/978-3-319-74412-4_7" } -{ "doi": "10.1103/physrevlett.94.147004" } -{ "doi": "10.22201/iij.24487937e.2008.2.8049" } -{ "doi": "10.22263/2312-4156.2016.4.65" } -{ "doi": "10.1109/iccet.2019.8726910" } -{ "doi": "10.11646/zootaxa.3957.5.2" } -{ "doi": "10.22266/ijies2008.0331.02" } -{ "doi": "10.1121/1.3249486" } -{ "doi": "10.22201/iij.24487937e.2008.2.8054" } -{ "doi": "10.1121/1.3257203" } -{ "doi": "10.1017/cbo9780511660108.003" } -{ "doi": "10.1021/ac101453s" } -{ "doi": "10.1073/pnas.1513718112" } -{ "doi": "10.1073/pnas.1617636114" } -{ "doi": "10.1039/c4nr06069e" } -{ "doi": "10.1371/journal.pone.0248967" } -{ "doi": "10.3389/feart.2019.00134" } -{ "doi": "10.1002/cbic.202000122" } -{ "doi": "10.1515/ordo-2019-0004" } -{ "doi": "10.15621/ijphy/2019/v6i4/185417" } -{ "doi": "10.1126/sciadv.aay8299" } -{ "doi": "10.5194/bg-2018-324" } -{ "doi": "10.1126/science.1057726" } -{ "doi": "10.1088/1742-6596/405/1/012023" } -{ "doi": "10.1126/science.1215985" } -{ "doi": "10.1126/science.1216682" } -{ "doi": "10.3390/ani10050803" } -{ "doi": "10.1126/science.1216765" } -{ "doi": "10.1302/1863-2548.15.200169" } -{ "doi": "10.1093/isle/isaa158" } -{ "doi": "10.22201/iij.24487937e.2008.2.8059" } -{ "doi": "10.1126/science.41.1054.404" } -{ "doi": "10.22201/iij.24487937e.2009.3.8071" } -{ "doi": "10.1128/aem.71.4.1899-1908.2005" } -{ "doi": "10.1371/journal.pone.0248967.s001" } -{ "doi": "10.1186/s41687-020-00231-8" } -{ "doi": "10.22201/iij.24487937e.2009.3.8074" } -{ "doi": "10.22266/ijies2008.0331.04" } -{ "doi": "10.22201/iij.24487937e.2009.3.8080" } -{ "doi": "10.1289/ehp.9272" } -{ "doi": "10.22201/iij.24487937e.2010.4.8089" } -{ "doi": "10.1371/journal.pone.0248967.s002" } -{ "doi": "10.22201/iij.24487937e.2011.5.8100" } -{ "doi": "10.22201/iij.24487937e.2011.5.8110" } -{ "doi": "10.1128/aem.71.4.1959-1963.2005" } -{ "doi": "10.22201/iij.24487937e.2011.5.8118" } -{ "doi": "10.1128/cvi.05630-11" } -{ "doi": "10.22201/iij.24487937e.2012.6.8136" } -{ "doi": "10.1128/ec.00242-09" } -{ "doi": "10.1128/ec.00271-09" } -{ "doi": "10.1128/ec.4.6.991-998.2005" } -{ "doi": "10.1128/ec.4.7.1211-1220.2005" } -{ "doi": "10.1128/genomea.00146-13" } -{ "doi": "10.1371/journal.pone.0248967.s003" } -{ "doi": "10.1371/journal.pone.0248967.s004" } -{ "doi": "10.1128/genomea.00147-15" } -{ "doi": "10.1128/genomea.00150-15" } -{ "doi": "10.1183/09059180.00010101" } -{ "doi": "10.1371/journal.pone.0248967.s005" } -{ "doi": "10.19168/jyasar.801080" } -{ "doi": "10.24269/jin.v4n1.2019.pp75-87" } -{ "doi": "10.1371/journal.pone.0248967.s006" } -{ "doi": "10.22266/ijies2008.0331.06" } -{ "doi": "10.22266/ijies2008.0630.02" } -{ "doi": "10.22266/ijies2008.0630.04" } -{ "doi": "10.22201/iij.24487937e.2013.7.8150" } -{ "doi": "10.1371/journal.pone.0248967.s009" } -{ "doi": "10.1371/journal.pone.0248967.s010" } -{ "doi": "10.3390/pharmaceutics11040166" } -{ "doi": "10.1088/1742-6596/1129/1/012015" } -{ "doi": "10.22266/ijies2008.0930.02" } -{ "doi": "10.22266/ijies2008.1231.02" } -{ "doi": "10.1371/journal.pone.0248967.s012" } -{ "doi": "10.3847/1538-4357/aab366" } -{ "doi": "10.22266/ijies2009.0331.01" } -{ "doi": "10.1371/journal.pone.0248967.s013" } -{ "doi": "10.22266/ijies2009.0331.04" } -{ "doi": "10.1103/physrevd.91.024025" } -{ "doi": "10.1371/journal.pone.0248967.s015" } -{ "doi": "10.22201/iij.24487937e.2015.9.8180" } -{ "doi": "10.9790/487x-0351316" } -{ "doi": "10.7202/032878ar" } -{ "doi": "10.1104/pp.104.058719" } -{ "doi": "10.1128/jb.174.23.7791-7797.1992" } -{ "doi": "10.22201/iij.24487937e.2015.9.8182" } -{ "doi": "10.22201/iij.24487937e.2017.11.11079" } -{ "doi": "10.22201/iij.24487937e.2018.12.12443" } -{ "doi": "10.1093/oso/9780198814153.003.0012" } -{ "doi": "10.22201/iij.9683695272e.2016" } -{ "doi": "10.11646/zootaxa.3820.1.1" } -{ "doi": "10.1046/j.1464-410x.1998.00683.x" } -{ "doi": "10.1002/adom.201801816" } -{ "doi": "10.1128/jb.182.2.546-550.2000" } -{ "doi": "10.2478/fcds-2019-0016" } -{ "doi": "10.1128/jb.183.1.328-335.2001" } -{ "doi": "10.22201/iisue.20072872e.2010.1.13" } -{ "doi": "10.22201/iisue.20072872e.2010.2.7" } -{ "doi": "10.22201/iisue.20072872e.2011.5.47" } -{ "doi": "10.22201/iisue.20072872e.2012.7.68" } -{ "doi": "10.22201/iisue.20072872e.2016.20.199" } -{ "doi": "10.1128/jcm.01048-14" } -{ "doi": "10.1016/j.enpol.2016.03.017" } -{ "doi": "10.22201/iisue.20072872e.2016.20.203" } -{ "doi": "10.1051/0004-6361/201118622" } -{ "doi": "10.1016/j.infsof.2020.106318" } -{ "doi": "10.22201/iisue.20072872e.2016.20.207" } -{ "doi": "10.1002/anie.201609690" } -{ "doi": "10.1083/jcb.200711167" } -{ "doi": "10.22201/iisue.20072872e.2017.21.217" } -{ "doi": "10.22586/csp.v52i3.11064" } -{ "doi": "10.1007/978-3-662-45803-7_14" } -{ "doi": "10.1128/jcm.01056-18" } -{ "doi": "10.2139/ssrn.1067241" } -{ "doi": "10.1183/23120541.00578-2020" } -{ "doi": "10.22201/iisue.20072872e.2017.23.3010" } -{ "doi": "10.1190/1.2944165" } -{ "doi": "10.22201/iisue.20072872e.2017.23.3013" } -{ "doi": "10.1130/g22421.1" } -{ "doi": "10.1080/09518398.2015.1077402" } -{ "doi": "10.1128/jcm.01065-08" } -{ "doi": "10.2307/590742" } -{ "doi": "10.1128/jcm.01176-10" } -{ "doi": "10.22201/iisue.20072872e.2018.25.282" } -{ "doi": "10.1002/ejoc.202000503" } -{ "doi": "10.1128/jcm.01196-07" } -{ "doi": "10.1371/journal.pone.0218033" } -{ "doi": "10.1161/jaha.118.009169" } -{ "doi": "10.1103/physreve.89.052136" } -{ "doi": "10.22201/iisue.20072872e.2018.25.285" } -{ "doi": "10.1537/ase1911.55.370" } -{ "doi": "10.3945/ajcn.2010.28674j" } -{ "doi": "10.3390/en9070490" } -{ "doi": "10.22201/iisue.20072872e.2018.26.298" } -{ "doi": "10.22201/iisue.20072872e.2018.26.300" } -{ "doi": "10.26444/ms/133102" } -{ "doi": "10.5114/dr.2014.45121" } -{ "doi": "10.1186/s13148-020-0813-z" } -{ "doi": "10.5552/nms.2020.2" } -{ "doi": "10.1007/s00421-020-04415-4" } -{ "doi": "10.1128/aac.02143-15" } -{ "doi": "10.1177/0967010616671642" } -{ "doi": "10.1021/acs.jpcc.6b03237.s001" } -{ "doi": "10.22201/iisue.20072872e.2019.27.341" } -{ "doi": "10.22201/iisue.20072872e.2019.27.345" } -{ "doi": "10.22201/iisue.20072872e.2019.27.347" } -{ "doi": "10.22201/iisue.20072872e.2019.28.430" } -{ "doi": "10.22201/iisue.20072872e.2019.28.432" } -{ "doi": "10.1016/j.ijrobp.2016.08.015" } -{ "doi": "10.1038/srep30155" } -{ "doi": "10.1590/0037-8682-0259-2017" } -{ "doi": "10.20868/upm.thesis.43487" } -{ "doi": "10.1071/wf13086" } -{ "doi": "10.21037/cdt.2018.04.04" } -{ "doi": "10.21608/jfabsu.2020.92406" } -{ "doi": "10.1890/09-1172.1" } -{ "doi": "10.1057/978-1-137-40808-2_8" } -{ "doi": "10.1002/ccr3.260" } -{ "doi": "10.1038/ncomms13916" } -{ "doi": "10.3892/ijo.2016.3499" } -{ "doi": "10.29327/212070.7.2-20" } -{ "doi": "10.22201/ppela.24487988e.2016.6.58438" } -{ "doi": "10.3389/fpsyt.2019.00125" } -{ "doi": "10.22201/ppela.24487988e.2018.10.67370" } -{ "doi": "10.1038/s41377-020-0288-x" } -{ "doi": "10.22201/ppela.24487988e.2018.9.64764" } -{ "doi": "10.1123/jpah.2012-0238" } -{ "doi": "10.1039/b612671e" } -{ "doi": "10.1016/j.biochi.2019.07.019" } -{ "doi": "10.22202/bc.2017.v3i1.2723" } -{ "doi": "10.1016/j.anplas.2019.01.007" } -{ "doi": "10.1126/scisignal.aae0374" } -{ "doi": "10.22202/bc.2017.v3i2.2765" } -{ "doi": "10.22202/bc.2018.v4i2.3016" } -{ "doi": "10.1128/aac.37.10.2132" } -{ "doi": "10.22202/js.v4i1.1870" } -{ "doi": "10.1590/s1415-43662006000300025" } -{ "doi": "10.21273/hortsci.36.6.1022" } -{ "doi": "10.4000/studifrancesi.30573" } -{ "doi": "10.3390/f9100630" } -{ "doi": "10.22203/ecm.v001a03" } -{ "doi": "10.1039/c5sc04920b" } -{ "doi": "10.31899/rh6.1011" } -{ "doi": "10.4000/studifrancesi.32912" } -{ "doi": "10.1155/2016/8713924" } -{ "doi": "10.1017/jpr.2019.9" } -{ "doi": "10.22203/ecm.v001a07" } -{ "doi": "10.3762/bjnano.6.68" } -{ "doi": "10.4000/studifrancesi.33022" } -{ "doi": "10.4000/studifrancesi.30033" } -{ "doi": "10.4000/books.cths.5008" } -{ "doi": "10.4000/conflits.399" } -{ "doi": "10.1016/j.fusengdes.2019.02.050" } -{ "doi": "10.22203/ecm.v002a02" } -{ "doi": "10.4000/laboreal.14098" } -{ "doi": "10.1128/aac.37.2.218" } -{ "doi": "10.1021/es9914083" } -{ "doi": "10.1086/599707" } -{ "doi": "10.22203/ecm.v002a06" } -{ "doi": "10.1038/ncomms3479" } -{ "doi": "10.4236/ajcm.2019.92002" } -{ "doi": "10.22203/ecm.v003a02" } -{ "doi": "10.1109/iccvw.2015.79" } -{ "doi": "10.5040/9781350052437-0338" } -{ "doi": "10.1177/1368431008099643" } -{ "doi": "10.1128/aac.37.2.371" } -{ "doi": "10.1128/aac.37.5.1025" } -{ "doi": "10.1109/tpwrd.2019.2955007" } -{ "doi": "10.22203/ecm.v003a04" } -{ "doi": "10.4000/studifrancesi.32967" } -{ "doi": "10.22203/ecm.v004a02" } -{ "doi": "10.1093/eurpub/ckq097" } -{ "doi": "10.1029/2000pa000528" } -{ "doi": "10.1016/j.rchic.2016.10.012" } -{ "doi": "10.3233/jpd-150712" } -{ "doi": "10.22266/ijies2009.0630.02" } -{ "doi": "10.1136/bmj.2.1766.994" } -{ "doi": "10.1136/thx.47.5.393" } -{ "doi": "10.22203/ecm.v004a05" } -{ "doi": "10.22203/ecm.v005a05" } -{ "doi": "10.1142/s0218216503002585" } -{ "doi": "10.22203/ecm.v006a04" } -{ "doi": "10.22203/ecm.v006a06" } -{ "doi": "10.22203/ecm.v007a02" } -{ "doi": "10.1103/physrevc.78.045205" } -{ "doi": "10.22203/ecm.v007a04" } -{ "doi": "10.1128/genomea.00346-16" } -{ "doi": "10.1128/iai.00340-08" } -{ "doi": "10.22203/ecm.v007a05" } -{ "doi": "10.22203/ecm.v008a02" } -{ "doi": "10.22203/ecm.v008a04" } -{ "doi": "10.1101/lm.810208" } -{ "doi": "10.3389/fnhum.2016.00585" } -{ "doi": "10.1194/jlr.m300431-jlr200" } -{ "doi": "10.1128/iai.58.5.1141-1145.1990" } -{ "doi": "10.1103/physrevd.78.123513" } -{ "doi": "10.22260/isarc2016/0046" } -{ "doi": "10.1108/jd-10-2017-0139" } -{ "doi": "10.1002/ece3.4459" } -{ "doi": "10.4314/wsa.v39i2.14" } -{ "doi": "10.22260/isarc2016/0049" } -{ "doi": "10.1073/pnas.1001673107" } -{ "doi": "10.1128/jb.175.7.2060-2066.1993" } -{ "doi": "10.22260/isarc2016/0051" } -{ "doi": "10.1128/jcm.01236-14" } -{ "doi": "10.1128/jcm.01237-15" } -{ "doi": "10.22266/ijies2009.0930.01" } -{ "doi": "10.1120/jacmp.v5i1.1944" } -{ "doi": "10.1120/jacmp.v6i2.2083" } -{ "doi": "10.1128/jcm.01248-07" } -{ "doi": "10.2174/1874120701509010256" } -{ "doi": "10.1128/jcm.01855-09" } -{ "doi": "10.22260/isarc2016/0055" } -{ "doi": "10.1128/jcm.02483-05" } -{ "doi": "10.1128/jcm.02489-06" } -{ "doi": "10.22260/isarc2016/0056" } -{ "doi": "10.1021/cm901772q" } -{ "doi": "10.1128/jcm.06133-11" } -{ "doi": "10.22260/isarc2016/0065" } -{ "doi": "10.1128/jcm.37.5.1573-1574.1999" } -{ "doi": "10.1128/jvi.00715-09" } -{ "doi": "10.1057/9780230524071_4" } -{ "doi": "10.1128/jvi.00743-08" } -{ "doi": "10.22260/isarc2016/0068" } -{ "doi": "10.1128/jvi.00746-16" } -{ "doi": "10.4067/s0718-22442013000100006" } -{ "doi": "10.1128/jvi.02116-08" } -{ "doi": "10.1128/mcb.1.9.797" } -{ "doi": "10.22260/isarc2016/0072" } -{ "doi": "10.22260/isarc2016/0078" } -{ "doi": "10.2169/internalmedicine.56.8300" } -{ "doi": "10.1109/ms.2017.3" } -{ "doi": "10.22266/ijies2009.1231.04" } -{ "doi": "10.1111/j.1365-2028.2006.00657.x" } -{ "doi": "10.22260/isarc2016/0085" } -{ "doi": "10.1080/00036846.2016.1158917" } -{ "doi": "10.22260/isarc2016/0088" } -{ "doi": "10.22260/isarc2016/0089" } -{ "doi": "10.4000/studifrancesi.30483" } -{ "doi": "10.22260/isarc2016/0092" } -{ "doi": "10.22260/isarc2016/0099" } -{ "doi": "10.4000/studifrancesi.30162" } -{ "doi": "10.22260/isarc2016/0101" } -{ "doi": "10.1177/1471301214532111" } -{ "doi": "10.22260/isarc2016/0104" } -{ "doi": "10.3390/math9010055" } -{ "doi": "10.4000/studifrancesi.29938" } -{ "doi": "10.1371/journal.pone.0151514" } -{ "doi": "10.4000/studifrancesi.30222" } -{ "doi": "10.1158/1078-0432.ccr-07-1124" } -{ "doi": "10.22266/ijies2010.0630.01" } -{ "doi": "10.22266/ijies2010.0630.03" } -{ "doi": "10.1051/0004-6361:20078318" } -{ "doi": "10.22266/ijies2010.0930.01" } -{ "doi": "10.15452/studiagermanistica.2020.27.0005" } -{ "doi": "10.22266/ijies2010.0930.02" } -{ "doi": "10.3944/aott.2009.412" } -{ "doi": "10.1002/edm2.235" } -{ "doi": "10.1093/cid/cit360" } -{ "doi": "10.22266/ijies2010.0930.06" } -{ "doi": "10.22266/ijies2011.0331.03" } -{ "doi": "10.30631/al-risalah.v13i02.410" } -{ "doi": "10.1093/mnras/stu830" } -{ "doi": "10.17265/2162-5263/2015.12.001" } -{ "doi": "10.22266/ijies2011.0630.02" } -{ "doi": "10.1103/physreva.97.032305" } -{ "doi": "10.7202/1022886ar" } -{ "doi": "10.22266/ijies2011.0630.06" } -{ "doi": "10.1016/j.acra.2021.01.002" } -{ "doi": "10.1016/j.jhealeco.2015.08.001" } -{ "doi": "10.22266/ijies2011.0930.02" } -{ "doi": "10.22266/ijies2011.1231.04" } -{ "doi": "10.1002/anie.201804068" } -{ "doi": "10.2139/ssrn.2722712" } -{ "doi": "10.2134/agronj2008.0182s" } -{ "doi": "10.22260/isarc2016/0107" } -{ "doi": "10.3390/ijgi8080358" } -{ "doi": "10.1128/genomea.01234-15" } -{ "doi": "10.22260/isarc2016/0113" } -{ "doi": "10.1128/iai.01685-06" } -{ "doi": "10.22260/isarc2016/0115" } -{ "doi": "10.4000/studifrancesi.30118" } -{ "doi": "10.4000/studifrancesi.30307" } -{ "doi": "10.1128/iai.69.6.3800-3808.2001" } -{ "doi": "10.1128/iai.69.6.3860-3868.2001" } -{ "doi": "10.1128/iai.69.6.3947-3953.2001" } -{ "doi": "10.1042/bj20060705" } -{ "doi": "10.1128/iai.69.6.4007-4018.2001" } -{ "doi": "10.1128/iai.70.12.6592-6596.2002" } -{ "doi": "10.2215/cjn.01840506" } -{ "doi": "10.1155/2009/385757" } -{ "doi": "10.2215/cjn.01870309" } -{ "doi": "10.1080/09639489.2017.1375649" } -{ "doi": "10.2215/cjn.01880310" } -{ "doi": "10.22271/ortho.2017.v3.i3a.07" } -{ "doi": "10.2215/cjn.01880606" } -{ "doi": "10.1192/bjp.157.6.853" } -{ "doi": "10.1103/physrevd.75.037301" } -{ "doi": "10.2215/cjn.01891105" } -{ "doi": "10.2215/cjn.01900309" } -{ "doi": "10.1128/jb.174.8.2431-2439.1992" } -{ "doi": "10.22271/ortho.2017.v3.i3a.08" } -{ "doi": "10.2215/cjn.01950606" } -{ "doi": "10.21622/resd.2017.03.2.185" } -{ "doi": "10.22178/pos.41-6" } -{ "doi": "10.1136/adc.2002.021154" } -{ "doi": "10.1007/s00414-016-1432-2" } -{ "doi": "10.1007/978-3-531-92886-9_4" } -{ "doi": "10.2215/cjn.01961205" } -{ "doi": "10.2215/cjn.01970309" } -{ "doi": "10.2215/cjn.01970507" } -{ "doi": "10.1103/physrevd.89.102001" } -{ "doi": "10.2215/cjn.01990213" } -{ "doi": "10.2215/cjn.02000507" } -{ "doi": "10.1364/josaa.20.001371" } -{ "doi": "10.3390/12030607" } -{ "doi": "10.1371/journal.pone.0012585" } -{ "doi": "10.1007/978-3-319-17043-5_3" } -{ "doi": "10.1371/journal.pone.0012589" } -{ "doi": "10.2215/cjn.02010606" } -{ "doi": "10.2215/cjn.02020309" } -{ "doi": "10.2215/cjn.02021205" } -{ "doi": "10.1371/journal.pone.0012836" } -{ "doi": "10.1371/journal.pone.0041427" } -{ "doi": "10.2215/cjn.02030606" } -{ "doi": "10.1371/journal.pone.0015106" } -{ "doi": "10.2215/cjn.02040408" } -{ "doi": "10.2215/cjn.02090212" } -{ "doi": "10.1016/j.mednuc.2007.03.011" } -{ "doi": "10.1016/j.tibs.2018.09.003" } -{ "doi": "10.2215/cjn.02120508" } -{ "doi": "10.1016/s0008-6363(99)00337-5" } -{ "doi": "10.2215/cjn.02160311" } -{ "doi": "10.1115/detc2006-99483" } -{ "doi": "10.2215/cjn.02180606" } -{ "doi": "10.1161/01.cir.15.4.481" } -{ "doi": "10.1161/01.cir.47.4.681" } -{ "doi": "10.1094/pdis.2004.88.1.63" } -{ "doi": "10.1182/blood-2013-08-521419" } -{ "doi": "10.2215/cjn.02190216" } -{ "doi": "10.1371/journal.pone.0024817" } -{ "doi": "10.1016/j.automatica.2011.03.001" } -{ "doi": "10.2215/cjn.02190314" } -{ "doi": "10.1051/0004-6361/201424369" } -{ "doi": "10.1371/journal.pone.0041353" } -{ "doi": "10.1073/pnas.1019446108" } -{ "doi": "10.1537/ase1887.26.45" } -{ "doi": "10.3390/12071367" } -{ "doi": "10.1093/toxsci/kfg090" } -{ "doi": "10.2215/cjn.02211205" } -{ "doi": "10.2215/cjn.02230409" } -{ "doi": "10.2215/cjn.02280215" } -{ "doi": "10.1107/s1600536804007081" } -{ "doi": "10.2140/pjm.1975.58.1" } -{ "doi": "10.3406/cea.1992.2098" } -{ "doi": "10.1103/physrevd.90.105020" } -{ "doi": "10.1051/0004-6361/201424382" } -{ "doi": "10.1073/pnas.90.2.750" } -{ "doi": "10.1080/00461520.2017.1333430" } -{ "doi": "10.1103/physrevd.94.083505" } -{ "doi": "10.1051/0004-6361/201424389" } -{ "doi": "10.1051/0004-6361/201630325" } -{ "doi": "10.1051/0004-6361/201731426" } -{ "doi": "10.1093/jigpal/jzi040" } -{ "doi": "10.1051/0004-6361/201833507" } -{ "doi": "10.13075/ijomeh.1896.01261" } -{ "doi": "10.1016/j.jmmm.2014.11.070" } -{ "doi": "10.1038/nphys4100" } -{ "doi": "10.1371/journal.pone.0041384" } -{ "doi": "10.3390/antiox8080243" } -{ "doi": "10.2215/cjn.02291205" } -{ "doi": "10.2215/cjn.02300606" } -{ "doi": "10.1128/aac.44.1.173-177.2000" } -{ "doi": "10.1128/aac.47.9.2951-2957.2003" } -{ "doi": "10.2215/cjn.02311205" } -{ "doi": "10.1128/aac.48.3.843-851.2004" } -{ "doi": "10.1128/aac.50.2.810-812.2006" } -{ "doi": "10.1128/aem.00862-16" } -{ "doi": "10.1128/aem.01394-08" } -{ "doi": "10.2215/cjn.02330315" } -{ "doi": "10.2215/cjn.02340310" } -{ "doi": "10.1182/asheducation-2014.1.66" } -{ "doi": "10.2215/cjn.02340607" } -{ "doi": "10.2215/cjn.02360311" } -{ "doi": "10.2172/824271" } -{ "doi": "10.1016/j.fertnstert.2018.11.022" } -{ "doi": "10.2215/cjn.02360409" } -{ "doi": "10.2172/824272" } -{ "doi": "10.2215/cjn.02370508" } -{ "doi": "10.1128/aem.66.1.10-14.2000" } -{ "doi": "10.1128/aem.66.1.15-22.2000" } -{ "doi": "10.2215/cjn.02400311" } -{ "doi": "10.20546/ijcmas.2019.807.209" } -{ "doi": "10.1128/aem.66.1.154-162.2000" } -{ "doi": "10.1128/aem.66.1.310-319.2000" } -{ "doi": "10.2991/icemct-15.2015.373" } -{ "doi": "10.1128/aem.66.11.4790-4797.2000" } -{ "doi": "10.1128/aem.66.11.4940-4944.2000" } -{ "doi": "10.1128/aem.66.11.4962-4971.2000" } -{ "doi": "10.31533/pubvet.v13n7a364.1-10" } -{ "doi": "10.22271/ortho.2017.v3.i3a.10" } -{ "doi": "10.2215/cjn.02490311" } -{ "doi": "10.2215/cjn.02490508" } -{ "doi": "10.2215/cjn.02500607" } -{ "doi": "10.1128/aem.66.12.5107-5109.2000" } -{ "doi": "10.2215/cjn.02510311" } -{ "doi": "10.2215/cjn.02550607" } -{ "doi": "10.14720/aas.2018.111.2.23" } -{ "doi": "10.3126/jcmsn.v11i4.14322" } -{ "doi": "10.2215/cjn.02570315" } -{ "doi": "10.34105/j.kmel.2010.02.020" } -{ "doi": "10.1128/jb.184.1.76-81.2002" } -{ "doi": "10.1128/jb.184.16.4529-4535.2002" } -{ "doi": "10.1128/jb.184.16.4536-4543.2002" } -{ "doi": "10.3998/ark.5550190.0010.302" } -{ "doi": "10.1128/aem.66.12.5161-5166.2000" } -{ "doi": "10.1128/jb.184.16.4555-4572.2002" } -{ "doi": "10.1371/journal.pone.0077504" } -{ "doi": "10.3390/ani10081341" } -{ "doi": "10.2215/cjn.02580607" } -{ "doi": "10.2215/cjn.02590508" } -{ "doi": "10.2215/cjn.02620707" } -{ "doi": "10.2215/cjn.02630608" } -{ "doi": "10.1371/journal.pone.0077660" } -{ "doi": "10.5915/24-1-15451" } -{ "doi": "10.36026/rpgeo.v4i2.2520" } -{ "doi": "10.2172/892378" } -{ "doi": "10.1128/aem.66.12.5301-5305.2000" } -{ "doi": "10.4067/s0034-98872016000900005" } -{ "doi": "10.5194/acp-17-12659-2017" } -{ "doi": "10.5125/jkaoms.2013.39.4.161" } -{ "doi": "10.1007/978-94-6300-208-0_9" } -{ "doi": "10.1177/026975800901600101" } -{ "doi": "10.1007/978-981-13-6504-1_114" } -{ "doi": "10.1128/jb.184.17.4733-4738.2002" } -{ "doi": "10.1128/aem.66.12.5437-5447.2000" } -{ "doi": "10.1128/aem.66.12.5518-5520.2000" } -{ "doi": "10.1128/aem.71.7.3935-3941.2005" } -{ "doi": "10.1128/ec.4.2.262-273.2005" } -{ "doi": "10.1128/jb.184.17.4757-4766.2002" } -{ "doi": "10.1128/ec.4.5.931-936.2005" } -{ "doi": "10.1128/genomea.00109-17" } -{ "doi": "10.1128/genomea.00379-17" } -{ "doi": "10.1128/genomea.00380-13" } -{ "doi": "10.1083/jcb.102.6.2023" } -{ "doi": "10.1128/genomea.00385-18" } -{ "doi": "10.1128/genomea.00399-13" } -{ "doi": "10.1128/genomea.00404-13" } -{ "doi": "10.1128/genomea.00406-15" } -{ "doi": "10.1128/genomea.00408-13" } -{ "doi": "10.2215/cjn.02640310" } -{ "doi": "10.15700/saje.v31n3a540" } -{ "doi": "10.1128/genomea.00617-17" } -{ "doi": "10.1128/genomea.00629-15" } -{ "doi": "10.2215/cjn.02650707" } -{ "doi": "10.1128/genomea.01177-16" } -{ "doi": "10.1128/iai.74.4.2102-2114.2006" } -{ "doi": "10.1128/iai.74.4.2233-2244.2006" } -{ "doi": "10.2215/cjn.02660706" } -{ "doi": "10.1128/jb.184.19.5502-5507.2002" } -{ "doi": "10.3390/s140610124" } -{ "doi": "10.1128/jb.185.15.4620-4625.2003" } -{ "doi": "10.1128/jb.185.16.4948-4955.2003" } -{ "doi": "10.1128/jb.06465-11" } -{ "doi": "10.1128/jb.06490-11" } -{ "doi": "10.1023/b:plso.0000035563.71887.15" } -{ "doi": "10.21236/ada200288" } -{ "doi": "10.14720/aas.2018.111.3.05" } -{ "doi": "10.1128/jb.187.11.3884-3888.2005" } -{ "doi": "10.1128/jb.188.6.2096-2105.2006" } -{ "doi": "10.1007/978-3-662-53120-4_300593" } -{ "doi": "10.1057/9781137032225_8" } -{ "doi": "10.1073/pnas.40.12.1155" } -{ "doi": "10.2169/internalmedicine.40.920" } -{ "doi": "10.1128/jb.182.18.5046-5051.2000" } -{ "doi": "10.1063/1.4920959" } -{ "doi": "10.2215/cjn.02740806" } -{ "doi": "10.2215/cjn.02760310" } -{ "doi": "10.15381/is.v22i40.15929" } -{ "doi": "10.1128/jvi.02060-08" } -{ "doi": "10.5937/tekstind1901025r" } -{ "doi": "10.1093/geronb/gbs161" } -{ "doi": "10.1177/0278364906068393" } -{ "doi": "10.1038/519266a" } -{ "doi": "10.1128/jvi.65.2.981-984.1991" } -{ "doi": "10.1134/s0001434618070179" } -{ "doi": "10.1155/2018/8474389" } -{ "doi": "10.22533/at.ed.4141916012" } -{ "doi": "10.15740/has/ijpp/9.2/514-519" } -{ "doi": "10.2215/cjn.02760315" } -{ "doi": "10.2215/cjn.02770409" } -{ "doi": "10.1063/1.4946808" } -{ "doi": "10.1007/s11227-021-03665-z" } -{ "doi": "10.4314/jae.v17i2.23" } -{ "doi": "10.3390/cryst8060243" } -{ "doi": "10.1002/chem.201901912" } -{ "doi": "10.1016/j.eurpsy.2017.01.002" } -{ "doi": "10.1016/j.jcss.2021.03.005" } -{ "doi": "10.18805/ijar.10276" } -{ "doi": "10.1371/journal.pgen.1007046" } -{ "doi": "10.2215/cjn.02780806" } -{ "doi": "10.2215/cjn.02790608" } -{ "doi": "10.1016/j.crwh.2018.e00060" } -{ "doi": "10.1128/jvi.01461-13" } -{ "doi": "10.1128/jvi.01461-17" } -{ "doi": "10.5897/ajb2014.14109" } -{ "doi": "10.1002/evl3.49" } -{ "doi": "10.35248/2684-1614.18.3.118" } -{ "doi": "10.4067/s0718-48162010000100009" } -{ "doi": "10.1016/j.jfa.2021.109027" } -{ "doi": "10.2215/cjn.02810707" } -{ "doi": "10.1139/cjfas-2018-0207" } -{ "doi": "10.1038/nmicrobiol.2016.250" } -{ "doi": "10.1002/ppp3.10159" } -{ "doi": "10.1021/acs.jpcc.6b05794" } -{ "doi": "10.1017/cbo9781139481373" } -{ "doi": "10.1002/tie.21672" } -{ "doi": "10.1051/alr:2008038" } -{ "doi": "10.2215/cjn.02820311" } -{ "doi": "10.3390/e19030087" } -{ "doi": "10.1371/journal.pone.0021863" } -{ "doi": "10.1007/bf02441950" } -{ "doi": "10.1371/journal.pone.0023339" } -{ "doi": "10.2215/cjn.02830409" } -{ "doi": "10.1155/2016/4364761" } -{ "doi": "10.1371/journal.pone.0032936" } -{ "doi": "10.1103/physrevlett.119.058003" } -{ "doi": "10.1590/1414-431x20165734" } -{ "doi": "10.3390/toxins11040203" } -{ "doi": "10.2215/cjn.02840314" } -{ "doi": "10.1016/j.jfa.2021.109034" } -{ "doi": "10.4103/0974-9233.97939" } -{ "doi": "10.4209/aaqr.2013.06.0208" } -{ "doi": "10.2215/cjn.02840806" } -{ "doi": "10.7188/bvsz.2013.89.4.4" } -{ "doi": "10.7717/peerj.6064" } -{ "doi": "10.2215/cjn.02860409" } -{ "doi": "10.2215/cjn.02870311" } -{ "doi": "10.1128/jcm.00710-16" } -{ "doi": "10.1128/jcm.00715-15" } -{ "doi": "10.1128/jcm.00717-15" } -{ "doi": "10.1007/s11740-021-01023-9" } -{ "doi": "10.1109/joe.2020.2984293" } -{ "doi": "10.1155/2016/5130346" } -{ "doi": "10.1128/jcm.39.8.2860-2863.2001" } -{ "doi": "10.1038/129672b0" } -{ "doi": "10.2215/cjn.02880312" } -{ "doi": "10.1128/jcm.39.9.3040-3046.2001" } -{ "doi": "10.1128/jcm.39.9.3373-3375.2001" } -{ "doi": "10.1128/jcm.43.1.277-283.2005" } -{ "doi": "10.1128/jcm.43.1.356-362.2005" } -{ "doi": "10.1371/journal.pone.0050129" } -{ "doi": "10.1371/journal.pcbi.1006188" } -{ "doi": "10.1128/jcm.43.12.6139-6143.2005" } -{ "doi": "10.1128/jvi.01251-15" } -{ "doi": "10.1038/s41467-018-06777-y" } -{ "doi": "10.1111/1365-2435.13215" } -{ "doi": "10.1021/acssynbio.6b00189" } -{ "doi": "10.2215/cjn.02890806" } -{ "doi": "10.1128/mcb.25.12.5171-5182.2005" } -{ "doi": "10.1080/037454809494575" } -{ "doi": "10.9756/sijifbm/v3i2/03040100201" } -{ "doi": "10.1155/2018/5287138" } -{ "doi": "10.2215/cjn.02900313" } -{ "doi": "10.2215/cjn.01760215" } -{ "doi": "10.2215/cjn.01760506" } -{ "doi": "10.1130/gsatg223a.1" } -{ "doi": "10.2215/cjn.01770214" } -{ "doi": "10.1130/gsatg278gw.1" } -{ "doi": "10.2172/7039964" } -{ "doi": "10.1130/gsatg291a.1" } -{ "doi": "10.2215/cjn.02920608" } -{ "doi": "10.2215/cjn.01790506" } -{ "doi": "10.18632/oncotarget.2626" } -{ "doi": "10.1017/cbo9781107338364" } -{ "doi": "10.2215/cjn.02950707" } -{ "doi": "10.2215/cjn.01820309" } -{ "doi": "10.2215/cjn.01820407" } -{ "doi": "10.2215/cjn.02960906" } -{ "doi": "10.1088/2058-7058/28/8/35" } -{ "doi": "10.1007/978-3-030-20024-4" } -{ "doi": "10.2172/7118817" } -{ "doi": "10.22201/fi.25940732e.2003.04n3.010" } -{ "doi": "10.21500/16578031.2172" } -{ "doi": "10.2215/cjn.01830309" } -{ "doi": "10.2172/7218931" } -{ "doi": "10.22201/fi.25940732e.2006.07n2.008" } -{ "doi": "10.1130/gsatg373gw.1" } -{ "doi": "10.2172/750108" } -{ "doi": "10.13005/bbra/1757" } -{ "doi": "10.2215/cjn.01841105" } -{ "doi": "10.2215/cjn.01860309" } -{ "doi": "10.5614/bull.geol.2021.5.1.1" } -{ "doi": "10.2215/cjn.01880216" } -{ "doi": "10.1038/aja.2013.76" } -{ "doi": "10.1051/matecconf/201711403011" } -{ "doi": "10.1371/journal.pmed.1001036" } -{ "doi": "10.22201/fi.25940732e.2006.07n3.013" } -{ "doi": "10.1130/gsatg392gw.1" } -{ "doi": "10.22201/fi.25940732e.2006.07n4.017" } -{ "doi": "10.2215/cjn.01881105" } -{ "doi": "10.32635/2176-9745.rbc.2017v63n1.188" } -{ "doi": "10.1088/0264-9381/20/11/330" } -{ "doi": "10.1001/jama.1899.02450730063034" } -{ "doi": "10.1175/bams_1001_cover2" } -{ "doi": "10.1128/jcm.41.11.5337-5339.2003" } -{ "doi": "10.1371/journal.pntd.0002094" } -{ "doi": "10.22271/ortho.2017.v3.i3e.56" } -{ "doi": "10.1371/journal.pone.0009444" } -{ "doi": "10.1073/pnas.12.3.162" } -{ "doi": "10.1080/09537287.2018.1555341" } -{ "doi": "10.1111/gove.12046" } -{ "doi": "10.2215/cjn.01890408" } -{ "doi": "10.1055/s-0038-1639376" } -{ "doi": "10.18502/kss.v3i13.4265" } -{ "doi": "10.22201/fi.25940732e.2007.08n1.001" } -{ "doi": "10.2215/cjn.01910213" } -{ "doi": "10.1371/journal.pone.0038316" } -{ "doi": "10.3390/en9070479" } -{ "doi": "10.22201/fi.25940732e.2007.08n3.014" } -{ "doi": "10.1002/asna.201612337" } -{ "doi": "10.1130/l1005.1" } -{ "doi": "10.1130/l1030.1" } -{ "doi": "10.1371/journal.pone.0041097" } -{ "doi": "10.2147/jbm.s52783" } -{ "doi": "10.20546/ijcmas.2017.612.078" } -{ "doi": "10.22271/ortho.2017.v3.i3f.61" } -{ "doi": "10.4414/cvm.2006.01205" } -{ "doi": "10.2307/1274161" } -{ "doi": "10.12962/j23546026.y2017i4.3076" } -{ "doi": "10.1371/journal.pone.0041119" } -{ "doi": "10.5216/ree.v15i1.16503" } -{ "doi": "10.1109/tie.2014.2331020" } -{ "doi": "10.22271/ortho.2017.v3.i3f.65" } -{ "doi": "10.1063/1.3625957" } -{ "doi": "10.1108/ijmf-07-2017-0144" } -{ "doi": "10.1161/hypertensionaha.108.117218" } -{ "doi": "10.1371/journal.pone.0041122" } -{ "doi": "10.1093/jxb/erz265" } -{ "doi": "10.2172/764628" } -{ "doi": "10.1371/journal.pone.0041136" } -{ "doi": "10.1371/journal.pone.0049162" } -{ "doi": "10.1051/0004-6361/201730693" } -{ "doi": "10.1051/0004-6361/201730700" } -{ "doi": "10.1051/0004-6361/201730701" } -{ "doi": "10.3390/f9100605" } -{ "doi": "10.2215/cjn.01960309" } -{ "doi": "10.2215/cjn.01990211" } -{ "doi": "10.22201/fi.25940732e.2007.08n4.021" } -{ "doi": "10.7181/acfs.2016.17.4.225" } -{ "doi": "10.5511/plantbiotechnology.14.0917a" } -{ "doi": "10.1371/journal.pone.0051799" } -{ "doi": "10.1371/journal.pone.0052753" } -{ "doi": "10.1371/journal.pone.0052762" } -{ "doi": "10.1051/0004-6361/201730704" } -{ "doi": "10.22201/fi.25940732e.2008.09n1.005" } -{ "doi": "10.1289/ehp.94102286" } -{ "doi": "10.2215/cjn.02000309" } -{ "doi": "10.2215/cjn.0200608" } -{ "doi": "10.1128/aac.00383-17" } -{ "doi": "10.1128/aac.00399-09" } -{ "doi": "10.1504/ijahuc.2014.064422" } -{ "doi": "10.22201/fi.25940732e.2008.09n2.012" } -{ "doi": "10.13031/2013.35254" } -{ "doi": "10.22201/fi.25940732e.2008.09n4.024" } -{ "doi": "10.2215/cjn.02020408" } -{ "doi": "10.1128/aac.02462-15" } -{ "doi": "10.2215/cjn.02030311" } -{ "doi": "10.1128/aac.02485-15" } -{ "doi": "10.1128/aac.03126-15" } -{ "doi": "10.1128/aac.48.4.1335-1343.2004" } -{ "doi": "10.1128/aem.01757-08" } -{ "doi": "10.1371/journal.pgen.1007102" } -{ "doi": "10.1128/jvi.01462-06" } -{ "doi": "10.3130/jaabe.7.233" } -{ "doi": "10.1109/apusncursinrsm.2019.8888598" } -{ "doi": "10.3346/jkms.2013.28.4.614" } -{ "doi": "10.22201/fi.25940732e.2008.09n4.026" } -{ "doi": "10.1128/jvi.01465-06" } -{ "doi": "10.1371/journal.pmed.0030006" } -{ "doi": "10.2215/cjn.02030408" } -{ "doi": "10.3390/mi8060177" } -{ "doi": "10.4314/ejesm.v5i2.6" } -{ "doi": "10.1128/aem.62.9.3304-3312.1996" } -{ "doi": "10.1089/cpb.2007.9993" } -{ "doi": "10.1093/molbev/msn137" } -{ "doi": "10.1055/s-0040-1722275" } -{ "doi": "10.1016/s0011-393x(96)80113-5" } -{ "doi": "10.1128/aem.66.11.4870-4876.2000" } -{ "doi": "10.4324/9781849772389" } -{ "doi": "10.1371/journal.pntd.0004265" } -{ "doi": "10.1074/jbc.m110.154575" } -{ "doi": "10.1371/journal.pntd.0004272" } -{ "doi": "10.1128/aem.66.11.4935-4939.2000" } -{ "doi": "10.1128/aem.66.11.4945-4953.2000" } -{ "doi": "10.22201/fi.25940732e.2009.10n2.016" } -{ "doi": "10.1128/aem.66.11.4992-4997.2000" } -{ "doi": "10.1016/j.chest.2018.12.027" } -{ "doi": "10.1128/aem.66.12.5206-5212.2000" } -{ "doi": "10.1128/aem.66.12.5406-5409.2000" } -{ "doi": "10.1128/aem.71.7.3512-3518.2005" } -{ "doi": "10.1093/mnras/stu1318" } -{ "doi": "10.1128/ec.1.3.391-400.2002" } -{ "doi": "10.1128/ec.2.1.9-18.2003" } -{ "doi": "10.1128/ec.2.3.510-520.2003" } -{ "doi": "10.1128/ec.3.2.393-405.2004" } -{ "doi": "10.18632/oncotarget.7125" } -{ "doi": "10.1128/ec.3.6.1619-1626.2004" } -{ "doi": "10.1128/ec.4.1.166-177.2005" } -{ "doi": "10.22271/tpi.2017.v6.i11l.02" } -{ "doi": "10.1128/ec.4.12.2066-2077.2005" } -{ "doi": "10.1128/ec.4.2.346-355.2005" } -{ "doi": "10.1128/ec.4.3.516-525.2005" } -{ "doi": "10.1128/ec.4.5.849-860.2005" } -{ "doi": "10.1128/genomea.00108-16" } -{ "doi": "10.1128/genomea.00379-18" } -{ "doi": "10.1128/genomea.00402-15" } -{ "doi": "10.1128/genomea.00406-17" } -{ "doi": "10.1128/genomea.00410-17" } -{ "doi": "10.1128/genomea.00620-15" } -{ "doi": "10.1021/om100149w" } -{ "doi": "10.1021/ic702471d" } -{ "doi": "10.2215/cjn.02050309" } -{ "doi": "10.1128/jvi.01470-07" } -{ "doi": "10.1128/jvi.02476-06" } -{ "doi": "10.1051/e3sconf/20130104004" } -{ "doi": "10.2514/6.2006-7734" } -{ "doi": "10.1128/jvi.03358-14" } -{ "doi": "10.22201/fi.25940732e.2009.10n3.024" } -{ "doi": "10.3389/fmars.2021.619190.s002" } -{ "doi": "10.5860/choice.191948" } -{ "doi": "10.1128/jcm.01682-06" } -{ "doi": "10.1001/archpsyc.58.8.737" } -{ "doi": "10.22201/fi.25940732e.2009.10n4.027" } -{ "doi": "10.1128/jvi.00578-15" } -{ "doi": "10.21926/obm.transplant.1901044" } -{ "doi": "10.1128/jvi.02155-09" } -{ "doi": "10.1128/jvi.65.3.1638-1643.1991" } -{ "doi": "10.3362/0262-8104.1999.021" } -{ "doi": "10.1515/rebs-2019-0080" } -{ "doi": "10.5020/23590777.14.1.141-151" } -{ "doi": "10.2215/cjn.02110508" } -{ "doi": "10.22201/fi.25940732e.2009.10n4.029" } -{ "doi": "10.1136/gut.33.6.759" } -{ "doi": "10.22201/fi.25940732e.2009.10n4.034" } -{ "doi": "10.3389/fpsyg.2019.00528" } -{ "doi": "10.1177/1555412005281819" } -{ "doi": "10.1371/journal.pone.0159550" } -{ "doi": "10.22201/fi.25940732e.2010.11n1.003" } -{ "doi": "10.1085/jgp.106.5.863" } -{ "doi": "10.2215/cjn.02180311" } -{ "doi": "10.2501/ija-30-4-641-663" } -{ "doi": "10.2215/cjn.02190312" } -{ "doi": "10.1029/2018gl079093" } -{ "doi": "10.22201/fi.25940732e.2010.11n3.029" } -{ "doi": "10.1175/2009mwr2843.1" } -{ "doi": "10.1051/0004-6361/201118429" } -{ "doi": "10.1099/00221287-98-1-147" } -{ "doi": "10.1006/ffta.2000.0291" } -{ "doi": "10.1038/leu.2014.285" } -{ "doi": "10.1073/pnas.73.3.867" } -{ "doi": "10.22201/fi.25940732e.2010.11n4.035" } -{ "doi": "10.2215/cjn.02220507" } -{ "doi": "10.2215/cjn.02230606" } -{ "doi": "10.1002/pola.10449" } -{ "doi": "10.22201/fi.25940732e.2011.12n3.027" } -{ "doi": "10.2215/cjn.02250508" } -{ "doi": "10.1371/journal.pgen.1003534" } -{ "doi": "10.1501/tipfak_0000000416" } -{ "doi": "10.1371/journal.pmed.1001664" } -{ "doi": "10.2215/cjn.02260507" } -{ "doi": "10.1002/wcm.321" } -{ "doi": "10.22201/fi.25940732e.2011.12n4.043" } -{ "doi": "10.18632/oncotarget.26699" } -{ "doi": "10.2215/cjn.02300311" } -{ "doi": "10.22201/fi.25940732e.2011.12n4.046" } -{ "doi": "10.22201/fi.25940732e.2012.13n1.007" } -{ "doi": "10.2172/782400" } -{ "doi": "10.2172/782408" } -{ "doi": "10.2215/cjn.02320311" } -{ "doi": "10.1371/journal.pone.0033056" } -{ "doi": "10.1371/journal.pone.0033067" } -{ "doi": "10.1371/journal.pone.0034420" } -{ "doi": "10.5788/25-1-1299" } -{ "doi": "10.1051/0004-6361/201423936" } -{ "doi": "10.1007/s40257-020-00504-4" } -{ "doi": "10.1007/978-3-642-16405-7_23" } -{ "doi": "10.22201/fi.25940732e.2012.13n1.012" } -{ "doi": "10.2215/cjn.02330508" } -{ "doi": "10.1016/j.mri.2010.06.028" } -{ "doi": "10.21236/ada389569" } -{ "doi": "10.1088/0305-4470/39/26/l03" } -{ "doi": "10.22201/fi.25940732e.2012.13n2.014" } -{ "doi": "10.1161/01.str.17.5.1019" } -{ "doi": "10.2215/cjn.02340409" } -{ "doi": "10.22201/fi.25940732e.2012.13n2.017" } -{ "doi": "10.1137/1.9781611972825.87" } -{ "doi": "10.2215/cjn.02340706" } -{ "doi": "10.1038/s41433-020-01221-2" } -{ "doi": "10.22201/fi.25940732e.2012.13n2.021" } -{ "doi": "10.22201/fi.25940732e.2012.13n3.029" } -{ "doi": "10.2172/7825" } -{ "doi": "10.23865/noasp.103" } -{ "doi": "10.2215/cjn.02360706" } -{ "doi": "10.2215/cjn.02400310" } -{ "doi": "10.22201/fi.25940732e.2012.13n3.034" } -{ "doi": "10.1090/tran/7688" } -{ "doi": "10.1155/1883/87478" } -{ "doi": "10.1155/2018/8614073" } -{ "doi": "10.1039/c0cc00078g" } -{ "doi": "10.2215/cjn.02400706" } -{ "doi": "10.1103/physrevd.57.6406" } -{ "doi": "10.1109/euma.2000.338815" } -{ "doi": "10.2172/782526" } -{ "doi": "10.17533/udea.redin.n76a03" } -{ "doi": "10.22201/fi.25940732e.2012.13n4.048" } -{ "doi": "10.1109/tnse.2018.2871726" } -{ "doi": "10.1371/journal.pone.0075442" } -{ "doi": "10.2215/cjn.02430607" } -{ "doi": "10.3390/80700556" } -{ "doi": "10.1017/cbo9781107415836.002" } -{ "doi": "10.1097/01.xme.0000395563.70945.52" } -{ "doi": "10.2353/ajpath.2010.090735" } -{ "doi": "10.1080/16878507.2021.1873901" } -{ "doi": "10.22201/fi.25940732e.2017.18n1.006" } -{ "doi": "10.1248/bpb.32.1500" } -{ "doi": "10.2215/cjn.02440607" } -{ "doi": "10.33582/2637-4927/1006" } -{ "doi": "10.1016/j.envpol.2007.12.019" } -{ "doi": "10.3390/admsci8030036" } -{ "doi": "10.1038/nrurol.2015.76" } -{ "doi": "10.25070/rea.v3i4.69" } -{ "doi": "10.2215/cjn.02450607" } -{ "doi": "10.1538/expanim.50.67" } -{ "doi": "10.22201/fi.25940732e.2017.18n3.025" } -{ "doi": "10.1371/journal.pone.0034706" } -{ "doi": "10.1016/s0167-6911(97)00081-9" } -{ "doi": "10.1186/s12877-019-1158-3" } -{ "doi": "10.1371/journal.pone.0051303" } -{ "doi": "10.1371/journal.pone.0060930" } -{ "doi": "10.1371/journal.pone.0060937" } -{ "doi": "10.25070/rea.v4i2.80" } -{ "doi": "10.2215/cjn.02480314" } -{ "doi": "10.22201/fi.25940732e.2017.18n3.028" } -{ "doi": "10.1371/journal.pone.0060964" } -{ "doi": "10.1371/journal.pone.0061231" } -{ "doi": "10.2215/cjn.02490409" } -{ "doi": "10.22201/fi.25940732e.2018.19n1.003" } -{ "doi": "10.1371/journal.pone.0062271" } -{ "doi": "10.31235/osf.io/p82fk" } -{ "doi": "10.2215/cjn.02510213" } -{ "doi": "10.2215/cjn.02510409" } -{ "doi": "10.1071/bi9750133" } -{ "doi": "10.3389/fonc.2021.605853" } -{ "doi": "10.1128/jb.171.12.6455-6467.1989" } -{ "doi": "10.1371/journal.pone.0063242" } -{ "doi": "10.3389/fonc.2021.636591" } -{ "doi": "10.3389/fonc.2021.646499" } -{ "doi": "10.22201/fpsi.20074719e.2012.3.234" } \ No newline at end of file diff --git a/src/frontend/public/favicon.ico b/src/frontend/public/favicon.ico deleted file mode 100644 index 18993ad9..00000000 Binary files a/src/frontend/public/favicon.ico and /dev/null differ diff --git a/src/graphql/.dockerignore b/src/graphql/.dockerignore deleted file mode 100644 index e9ccb8c8..00000000 --- a/src/graphql/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -log/ -test/ -.eslintrc.json -README.md \ No newline at end of file diff --git a/src/graphql/Dockerfile b/src/graphql/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/graphql/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/graphql/README.md b/src/graphql/README.md deleted file mode 100644 index 148cd6ae..00000000 --- a/src/graphql/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# ezunpaywall-graphql - -unpaywall data access service - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| NODE_ENV | development | environment of node | -| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | -| REDIS_HOST | redis | redis host | -| REDIS_PORT | 6379 | redis port | -| REDIS_PASSWORD | changeme | redis password | -| ELASTICSEARCH_HOSTS | http://elastic | elasticsearch host | -| ELASTICSEARCH_PORT | 9200 | elasticsearch port | -| ELASTICSEARCH_USERNAME | elastic | elasticsearch admin username | -| ELASTICSEARCH_PASSWORD | changeme | elasticsearch admin password | -| ELASTICSEARCH_INDEX_ALIAS | upw | graphql entry point | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | diff --git a/src/graphql/app.js b/src/graphql/app.js deleted file mode 100644 index 08bbf7b7..00000000 --- a/src/graphql/app.js +++ /dev/null @@ -1,78 +0,0 @@ -const fs = require('fs-extra'); -const path = require('path'); -const express = require('express'); -const responseTime = require('response-time'); -const cors = require('cors'); -const { json } = require('body-parser'); -const { ApolloServer } = require('@apollo/server'); -const { expressMiddleware } = require('@apollo/server/express4'); - -const { pingRedis, startConnectionRedis } = require('./lib/services/redis'); - -const getNumberOfDOI = require('./lib/middlewares/args'); -const auth = require('./lib/middlewares/auth'); - -const logger = require('./lib/logger'); -const morgan = require('./lib/morgan'); -const getConfig = require('./lib/config'); - -const cronMetrics = require('./lib/controllers/cron/metrics'); -const { setMetrics } = require('./lib/controllers/metrics'); - -const { pingElastic } = require('./lib/services/elastic'); - -const routerPing = require('./lib/routers/ping'); -const routerOpenapi = require('./lib/routers/openapi'); - -const typeDefs = require('./lib/models'); -const resolvers = require('./lib/resolvers'); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); -fs.ensureDir(path.resolve(logDir, 'access')); - -const server = new ApolloServer({ - typeDefs, - resolvers, - introspection: true, - csrfPrevention: false, -}); - -(async () => { - const app = express(); - - app.use(morgan); - app.use(responseTime()); - - app.use(cors({ - origin: '*', - allowedHeaders: ['Content-Type', 'x-api-key'], - method: ['GET', 'POST'], - })); - - app.use(routerPing); - app.use(routerOpenapi); - - await server.start(); - - app.use('/graphql', cors(), json(), auth, expressMiddleware(server, { - context: async ({ req }) => { - req.countDOI = getNumberOfDOI(req); - - return req; - }, - })); - - app.listen(3000, async () => { - logger.info('[express] ezunpaywall graphQL API listening on 3000'); - pingElastic().then(() => { - setMetrics(); - }); - getConfig(); - await startConnectionRedis(); - pingRedis(); - - cronMetrics.start(); - }); -})(); diff --git a/src/graphql/lib/middlewares/args.js b/src/graphql/lib/middlewares/args.js deleted file mode 100644 index c06011d0..00000000 --- a/src/graphql/lib/middlewares/args.js +++ /dev/null @@ -1,44 +0,0 @@ -const logger = require('../logger'); - -function getNumberOfDOI(req) { - const patternBetweenBracket = /.*?(\[.*?\]).*?/i; - const patternBetweenBracketQuery = /.*?(\[".*?"\]).*?/i; - // BODY - // { - // query: 'query ($dois: [ID!]!) { unpaywall(dois: $dois) { doi, is_oa } }', - // variables: { dois: [ '10.1186/s40510-015-0109-6' ] } - // } - if (req?.body?.variables?.dois) { return req.body.variables.dois.length; } - // BODY - // query: '{ unpaywall(dois: ["10.1186/s40510-015-0109-6","Coin Coin"]) { doi, is_oa } }' - if (req?.body?.query) { - const match = patternBetweenBracketQuery.exec(req?.body?.query); - let parsedMatch; - if (match?.length >= 1) { - try { - parsedMatch = JSON.parse(match[1]); - return parsedMatch.length; - } catch (err) { - logger.error(`[express] Cannot parse [${match}]`); - return 0; - } - } - } - // query: '{ unpaywall(dois:["10.1186/s40510-015-0109-6"]) { doi, is_oa } }' - if (req?.query?.query) { - const match = patternBetweenBracket.exec(req.query.query); - if (match?.length >= 1) { - try { - const parsedMatch = JSON.parse(match[1]); - return parsedMatch.length; - } catch (err) { - logger.error(`[express] Cannot parse [${match}]`); - return 0; - } - } - } - - return 0; -} - -module.exports = getNumberOfDOI; diff --git a/src/graphql/lib/models/index.js b/src/graphql/lib/models/index.js deleted file mode 100644 index c66be4f2..00000000 --- a/src/graphql/lib/models/index.js +++ /dev/null @@ -1,20 +0,0 @@ -const unpaywallType = require('./unpaywall'); -const oaLocationType = require('./oalocation'); -const zauthorsType = require('./zauthors'); -const metrics = require('./metrics'); - -const typeDefs = `#graphql - ${unpaywallType} - ${oaLocationType} - ${zauthorsType} - ${metrics} - - type Query { - unpaywall(dois: [ID!]!): [UnpaywallType] - GetByDOI(dois: [ID!]!): [UnpaywallType] - metrics: MetricsType - dailyMetrics: MetricsType - } -`; - -module.exports = typeDefs; diff --git a/src/graphql/lib/resolvers/unpaywall.js b/src/graphql/lib/resolvers/unpaywall.js deleted file mode 100644 index 6c99ee16..00000000 --- a/src/graphql/lib/resolvers/unpaywall.js +++ /dev/null @@ -1,136 +0,0 @@ -/* eslint-disable guard-for-in */ -/* eslint-disable no-restricted-syntax */ -const graphqlFields = require('graphql-fields'); - -const config = require('config'); - -const { redisClient } = require('../services/redis'); -const { elasticClient } = require('../services/elastic'); - -const logger = require('../logger'); - -/** - * Flatten nested properties of an object by seperating keys with dots. - * Example: { foo: { bar: 'foo' } } => { 'foo.bar': 'foo' } - * - * @param {Object} obj - Object need to be flatten. - * - * @returns {Object} Flatten object. - */ -function flatten(obj) { - const flattened = []; - - function flattenProp(data, keys) { - Object.entries(data).forEach(([key, value]) => { - if (typeof value !== 'object') { return; } - - const newKeys = [...keys, key]; - - if (Object.keys(value).length === 0) { - flattened.push(newKeys.join('.')); - } else { - flattenProp(value, newKeys); - } - }); - } - - flattenProp(obj, []); - - return flattened; -} - -async function unpaywall(parent, args, contextValue, info) { - const apikey = contextValue.get('X-API-KEY'); - - if (!apikey) { - throw Error('Not authorized'); - } - - let key; - try { - key = await redisClient.get(apikey); - } catch (err) { - logger.error(`[redis] Cannot get [${apikey}]`, err); - throw Error('Internal server error'); - } - - let apiKeyConfig; - try { - apiKeyConfig = JSON.parse(key); - } catch (err) { - logger.error(`[redis] Cannot parse [${key}]`, err); - throw Error('Internal server error'); - } - - if (!Array.isArray(apiKeyConfig?.access) || !apiKeyConfig?.access?.includes('graphql') || !apiKeyConfig?.allowed) { - throw Error('Not authorized'); - } - - // Demo apikey - if (apikey === 'demo') { - if ((apiKeyConfig.count - args.dois.length) < 0) { - throw Error('Not authorized'); - } - apiKeyConfig.count -= args.dois.length; - try { - await redisClient.set(apikey, `${JSON.stringify(apiKeyConfig)}`); - } catch (err) { - logger.error(`[redis] Cannot update apikey [${apikey}] with config [${JSON.stringify(apiKeyConfig)}]`, err); - throw err; - } - } - - let index = contextValue?.get('index'); - - const { attributes } = contextValue; - - if (!index) { - index = config.get('elasticsearch.indexAlias'); - } - - if (!attributes.includes('*')) { - const test = graphqlFields(info); - const requestedField = flatten(test); - - requestedField.forEach((field) => { - if (!attributes.includes(field)) { - throw Error(`You don't have access to ${field}`); - } - }); - } - - const dois = []; - - // Normalize request - args.dois.forEach((doi) => { - dois.push(doi.toLowerCase()); - }); - - const filter = [{ terms: { doi: dois } }]; - - const query = { - bool: { - filter, - }, - }; - - let res; - try { - res = await elasticClient.search({ - index, - size: dois.length || 1000, - body: { - query, - _source: attributes, - }, - - }); - } catch (err) { - logger.error('[elastic] Cannot request elastic', err); - return null; - } - // eslint-disable-next-line no-underscore-dangle - return res.body.hits.hits.map((hit) => hit._source); -} - -module.exports = unpaywall; diff --git a/src/graphql/lib/routers/openapi.js b/src/graphql/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/graphql/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/graphql/openapi.json b/src/graphql/openapi.json deleted file mode 100644 index 84c92ffa..00000000 --- a/src/graphql/openapi.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "The graphql service allows access to unpaywall data stored in elastic.", - "version": "1.0.0", - "title": "Graphql service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "paths": { - "/graphql": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "type": "string", - "x-examples": { - "example-1": "graphql service" - } - }, - "examples": { - "service": { - "value": "graphql service" - } - } - }, - "Success": { - "examples": { - "response": { - "value": { - "message": "graphql service" - } - } - } - } - } - } - }, - "operationId": "get-graphql", - "description": "Get name of graphql service", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/graphql/ping": { - "get": { - "summary": "Ping graphql service", - "operationId": "get-graphql-ping", - "description": "ping graphql service", - "tags": [ - "ping" - ], - "responses": { - "204": { - "description": "No Content" - } - } - }, - "parameters": [] - }, - "/graphql/health": { - "get": { - "summary": "Health", - "operationId": "get-graphql-health", - "description": "Health on all service connected to graphql service", - "tags": [ - "ping" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elastic": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - }, - "x-examples": { - "Example 1": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 1, - "status": true - } - } - }, - "examples": { - "Success": { - "value": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 1, - "status": true - } - }, - "Error redis": { - "value": { - "redis": { - "elapsedTime": 3001, - "status": false, - "error": "time out" - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 3001, - "status": false - } - } - } - } - } - } - } - }, - "parameters": [] - }, - "/graphql/health/redis": { - "get": { - "summary": "Health on redis service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-graphql-health-redis", - "description": "Health on redis", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/graphql/health/elastic": { - "get": { - "summary": "Health on elastic service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-graphql-health-elastic", - "description": "Health on elastic", - "tags": [ - "ping" - ] - }, - "parameters": [] - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "tags": [ - { - "name": "ping" - } - ], - "components": { - "responses": { - "Not-authorized": { - "description": "Not authorized", - "headers": {}, - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "Not authorized" - } - } - }, - "examples": { - "example-1": { - "value": { - "message": "string" - } - } - } - }, - "Not authorized": { - "examples": { - "response": { - "value": { - "message": "Not authorized" - } - } - } - } - } - }, - "Health": { - "description": "Example response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "elapsedTime": { - "type": "integer" - } - }, - "x-examples": { - "Example 1": { - "name": "redis", - "status": true, - "elapsedTime": 1 - } - } - }, - "examples": { - "Success": { - "value": { - "name": "name of service", - "status": true, - "elapsedTime": 1 - } - }, - "Error redis": { - "value": { - "name": "redis", - "elapsedTime": 3002, - "error": "time out", - "status": false - } - } - } - } - } - } - }, - "securitySchemes": { - "x-api-key": { - "type": "apiKey", - "in": "header", - "name": "API Key" - } - } - } -} \ No newline at end of file diff --git a/src/graphql/test/mapping/unpaywall.json b/src/graphql/test/mapping/unpaywall.json deleted file mode 100644 index 03c52e35..00000000 --- a/src/graphql/test/mapping/unpaywall.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "settings": { - "number_of_shards": 1 - }, - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "best_oa_location": { - "properties": { - "evidence": { "type": "keyword" }, - "host_type":{ "type": "keyword" }, - "is_best": { "type": "boolean" }, - "license": { "type": "keyword" }, - "pmh_id": { "type": "keyword" }, - "updated": { "type": "date" }, - "url": { "type": "keyword" }, - "url_for_landing_page": { "type": "keyword" }, - "url_for_pdf": { "type": "keyword" }, - "version": { "type": "keyword" } - } - }, - "data_standard": { - "type": "long" - }, - "doi": { - "type": "keyword" - }, - "doi_url": { - "type": "keyword" - }, - "first_oa_location": { - "properties": { - "evidence": { "type": "keyword" }, - "host_type":{ "type": "keyword" }, - "is_best": { "type": "boolean" }, - "license": { "type": "keyword" }, - "pmh_id": { "type": "keyword" }, - "updated": { "type": "date" }, - "url": { "type": "keyword" }, - "url_for_landing_page": { "type": "keyword" }, - "url_for_pdf": { "type": "keyword" }, - "version": { "type": "keyword" } - } - }, - "genre": { - "type": "keyword" - }, - "has_repository_copy": { - "type": "boolean" - }, - "is_oa": { - "type": "boolean" - }, - "is_paratext": { - "type": "boolean" - }, - "journal_is_in_doaj": { - "type": "boolean" - }, - "journal_is_oa": { - "type": "boolean" - }, - "journal_issn_l": { - "type": "keyword" - }, - "journal_issns": { - "type": "keyword" - }, - "journal_name": { - "type": "keyword" - }, - "oa_locations": { - "properties": { - "evidence": { "type": "keyword" }, - "host_type":{ "type": "keyword" }, - "is_best": { "type": "boolean" }, - "license": { "type": "keyword" }, - "pmh_id": { "type": "keyword" }, - "updated": { "type": "date" }, - "url": { "type": "keyword" }, - "url_for_landing_page": { "type": "keyword" }, - "url_for_pdf": { "type": "keyword" }, - "version": { "type": "keyword" } - } - }, - "oa_status": { - "type": "keyword" - }, - "published_date": { - "type": "date", - "format": "iso8601" - }, - "publisher": { - "type": "keyword" - }, - "title": { - "type": "keyword" - }, - "updated": { - "type": "date", - "format": "iso8601" - }, - "year": { - "type": "keyword" - }, - "z_authors": { - "properties": { - "family": { "type": "keyword" }, - "given": { "type": "keyword" }, - "ORCID": { "type": "keyword" }, - "authenticated-orcid": { "type": "boolean" }, - "affiliation": { - "properties": { - "name": { "type": "keyword" } - } - } - } - } - } - } -} diff --git a/src/graphql/test/sources/fake1.jsonl b/src/graphql/test/sources/fake1.jsonl deleted file mode 100644 index cdb0a299..00000000 --- a/src/graphql/test/sources/fake1.jsonl +++ /dev/null @@ -1,50 +0,0 @@ -{"doi":"10.1186/s40510-015-0109-6","year":2015,"genre":"journal-article","is_oa":true,"title":"Synergistic effect of wire bending and salivary pH on surface properties and mechanical properties of orthodontic stainless steel archwires","doi_url":"https://doi.org/10.1186/s40510-015-0109-6","updated":"2020-11-01T19:27:41.080986","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Marieke G.","family":"Hobbelink","sequence":"first"},{"given":"Yan","family":"He","sequence":"additional"},{"given":"Jia","family":"Xu","sequence":"additional"},{"given":"Huixu","family":"Xie","sequence":"additional"},{"given":"Richard","family":"Stoll","sequence":"additional"},{"given":"Qingsong","family":"Ye","sequence":"additional"}],"is_paratext":false,"journal_name":"Progress in Orthodontics","oa_locations":[{"url":"https://doi.org/10.1186/s40510-015-0109-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-10-26","updated":"2020-11-01T19:27:40.270925","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s40510-015-0109-6","repository_institution":null},{"url":"http://europepmc.org/articles/pmc4621974?pdf=render","pmh_id":"oai:europepmc.org:NW9rLbsGY7CncqCRefdW","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4621974?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4621974","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://pure.rug.nl/ws/files/67598823/s40510_015_0109_6.pdf","pmh_id":"oai:pure.rug.nl:publications/d3c2ac08-64c1-4194-b054-b41a3c4e749a","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-07-26T14:25:34.143808","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"7f0825cc41e4f9abd9e","url_for_pdf":"https://pure.rug.nl/ws/files/67598823/s40510_015_0109_6.pdf","url_for_landing_page":"https://pure.rug.nl/ws/files/67598823/s40510_015_0109_6.pdf","repository_institution":"University of Groningen / Centre for Information Technology - University of Groningen research database"},{"url":"https://www.rug.nl/research/portal/files/67598823/s40510_015_0109_6.pdf","pmh_id":"rug:oai:pure.rug.nl:publications/d3c2ac08-64c1-4194-b054-b41a3c4e749a","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-06-07T12:24:19.876345","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"bfa41bc4dfeca7f7fae","url_for_pdf":"https://www.rug.nl/research/portal/files/67598823/s40510_015_0109_6.pdf","url_for_landing_page":"https://www.rug.nl/research/portal/en/publications/synergistic-effect-of-wire-bending-and-salivary-ph-on-surface-properties-and-mechanical-properties-of-orthodontic-stainless-steel-archwires(d3c2ac08-64c1-4194-b054-b41a3c4e749a).html","repository_institution":"DANS - Data Archiving and Networked Services - NARCIS - National Academic Research and Collaborations Information System"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4621974","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T19:27:40.271198","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4621974","repository_institution":null},{"url":"https://researchonline.jcu.edu.au/41861/1/Hobbelink_et_%20al-2015-Progress_%20in_%20Orthodontics%2016.pdf","pmh_id":"oai:researchonline.jcu.edu.au:41861","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-10-02T21:36:03.353114","version":"acceptedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"fs4fwvjhwujmmpdysncr","url_for_pdf":"https://researchonline.jcu.edu.au/41861/1/Hobbelink_et_%20al-2015-Progress_%20in_%20Orthodontics%2016.pdf","url_for_landing_page":"https://researchonline.jcu.edu.au/41861/1/Hobbelink_et_%20al-2015-Progress_%20in_%20Orthodontics%2016.pdf","repository_institution":"James Cook University - ResearchOnline at James Cook University"}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2196-1042","journal_issn_l":"2196-1042","published_date":"2015-10-26","best_oa_location":{"url":"https://doi.org/10.1186/s40510-015-0109-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-10-26","updated":"2020-11-01T19:27:40.270925","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s40510-015-0109-6","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1186/s40510-015-0109-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-10-26","updated":"2020-11-01T19:27:40.270925","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s40510-015-0109-6","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1104/pp.67.5.922","year":1981,"genre":"journal-article","is_oa":true,"title":"Phosphatidylethanolamine Synthesis in Castor Bean Endosperm","doi_url":"https://doi.org/10.1104/pp.67.5.922","updated":"2020-10-28T12:27:54.139104","oa_status":"bronze","publisher":"American Society of Plant Biologists (ASPB)","z_authors":[{"given":"Salvatore A.","family":"Sparace","sequence":"first"},{"given":"Leslie K.","family":"Wagner","sequence":"additional"},{"given":"Thomas S.","family":"Moore","suffix":"Jr.","sequence":"additional"}],"is_paratext":false,"journal_name":"Plant Physiology","oa_locations":[{"url":"http://www.plantphysiol.org/content/67/5/922.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-16T16:15:02.291803","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.plantphysiol.org/content/67/5/922.full.pdf","url_for_landing_page":"https://doi.org/10.1104/pp.67.5.922","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC425801","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-04T00:36:12.551275","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC425801","repository_institution":null},{"url":"http://pdfs.semanticscholar.org/c7b3/3950cf64bcca8695871331b19fcabbde6334.pdf","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2019-10-01T00:00:00","version":"submittedVersion","evidence":"oa repository (semantic scholar lookup)","host_type":"repository","endpoint_id":"trmgzrn8eq4yx7ddvmzs","url_for_pdf":"http://pdfs.semanticscholar.org/c7b3/3950cf64bcca8695871331b19fcabbde6334.pdf","url_for_landing_page":"https://semanticscholar.org/paper/c7b33950cf64bcca8695871331b19fcabbde6334","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0032-0889,1532-2548","journal_issn_l":"0032-0889","published_date":"1981-05-01","best_oa_location":{"url":"http://www.plantphysiol.org/content/67/5/922.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-16T16:15:02.291803","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.plantphysiol.org/content/67/5/922.full.pdf","url_for_landing_page":"https://doi.org/10.1104/pp.67.5.922","repository_institution":null},"first_oa_location":{"url":"http://www.plantphysiol.org/content/67/5/922.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-16T16:15:02.291803","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.plantphysiol.org/content/67/5/922.full.pdf","url_for_landing_page":"https://doi.org/10.1104/pp.67.5.922","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1590/abd1806-4841.20187321","year":2018,"genre":"journal-article","is_oa":true,"title":"Chromoblastomycosis: an etiological, epidemiological, clinical, diagnostic, and treatment update","doi_url":"https://doi.org/10.1590/abd1806-4841.20187321","updated":"2020-10-30T09:09:16.327931","oa_status":"gold","publisher":"FapUNIFESP (SciELO)","z_authors":[{"ORCID":"http://orcid.org/0000-0002-7133-5321","given":"Arival Cardoso de","family":"Brito","sequence":"first","affiliation":[{"name":"Universidade Federal do Pará, Brazil; Universidade Federal do Pará, Brazil; Universidade Federal do Pará, Brazil"}],"authenticated-orcid":false},{"ORCID":"http://orcid.org/0000-0002-7297-0749","given":"Maraya de Jesus Semblano","family":"Bittencourt","sequence":"additional","affiliation":[{"name":"Universidade Federal do Pará, Brazil"}],"authenticated-orcid":false}],"is_paratext":false,"journal_name":"Anais Brasileiros de Dermatologia","oa_locations":[{"url":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc","oa_date":"2018-08-01","updated":"2019-12-09T13:46:57.337957","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","url_for_landing_page":"https://doi.org/10.1590/abd1806-4841.20187321","repository_institution":null},{"url":"https://doi.org/10.1590/abd1806-4841.20187321","pmh_id":null,"is_best":false,"license":"cc-by-nc","oa_date":"2018-08-01","updated":"2020-10-30T09:09:16.132924","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1590/abd1806-4841.20187321","repository_institution":null},{"url":"http://europepmc.org/articles/pmc6063100?pdf=render","pmh_id":"oai:europepmc.org:5027492","is_best":false,"license":"cc-by-nc-nd","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc6063100?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc6063100","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6063100","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-10-30T09:09:16.133315","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6063100","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1806-4841,0365-0596","journal_issn_l":"0365-0596","published_date":"2018-08-01","best_oa_location":{"url":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc","oa_date":"2018-08-01","updated":"2019-12-09T13:46:57.337957","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","url_for_landing_page":"https://doi.org/10.1590/abd1806-4841.20187321","repository_institution":null},"first_oa_location":{"url":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc","oa_date":"2018-08-01","updated":"2019-12-09T13:46:57.337957","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.scielo.br/pdf/abd/v93n4/0365-0596-abd-93-04-0495.pdf","url_for_landing_page":"https://doi.org/10.1590/abd1806-4841.20187321","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1186/s12864-020-6597-x","year":2020,"genre":"journal-article","is_oa":true,"title":"A completeness-independent method for pre-selection of closely related genomes for species delineation in prokaryotes","doi_url":"https://doi.org/10.1186/s12864-020-6597-x","updated":"2020-10-28T09:28:58.940622","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"ORCID":"http://orcid.org/0000-0003-2795-3111","given":"Yizhuang","family":"Zhou","sequence":"first","authenticated-orcid":false},{"given":"Jifang","family":"Zheng","sequence":"additional"},{"given":"Yepeng","family":"Wu","sequence":"additional"},{"given":"Wenting","family":"Zhang","sequence":"additional"},{"given":"Junfei","family":"Jin","sequence":"additional"}],"is_paratext":false,"journal_name":"BMC Genomics","oa_locations":[{"url":"https://doi.org/10.1186/s12864-020-6597-x","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:58.877057","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s12864-020-6597-x","repository_institution":null},{"url":"http://europepmc.org/articles/pmc7045542?pdf=render","pmh_id":"oai:europepmc.org:cUJPZaCeuHu66v6cS8H4","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc7045542?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc7045542","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7045542","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-03T16:39:58.877335","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7045542","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1471-2164","journal_issn_l":"1471-2164","published_date":"2020-02-26","best_oa_location":{"url":"https://doi.org/10.1186/s12864-020-6597-x","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:58.877057","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s12864-020-6597-x","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1186/s12864-020-6597-x","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:58.877057","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s12864-020-6597-x","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1186/s13071-020-3976-8","year":2020,"genre":"journal-article","is_oa":true,"title":"Survey of Spanish pet owners about endoparasite infection risk and deworming frequencies","doi_url":"https://doi.org/10.1186/s13071-020-3976-8","updated":"2020-10-28T09:28:27.228404","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Guadalupe","family":"Miró","sequence":"first"},{"given":"Rosa","family":"Gálvez","sequence":"additional"},{"given":"Ana","family":"Montoya","sequence":"additional"},{"given":"Beatriz","family":"Delgado","sequence":"additional"},{"given":"Jason","family":"Drake","sequence":"additional"}],"is_paratext":false,"journal_name":"Parasites & Vectors","oa_locations":[{"url":"https://doi.org/10.1186/s13071-020-3976-8","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:40:06.841042","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13071-020-3976-8","repository_institution":null},{"url":"http://europepmc.org/articles/pmc7045513?pdf=render","pmh_id":"oai:europepmc.org:vsJ7zPU3tRBPGbbT4KRo","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc7045513?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc7045513","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7045513","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-03T16:40:06.841212","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7045513","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1756-3305","journal_issn_l":"1756-3305","published_date":"2020-02-26","best_oa_location":{"url":"https://doi.org/10.1186/s13071-020-3976-8","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:40:06.841042","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13071-020-3976-8","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1186/s13071-020-3976-8","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:40:06.841042","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13071-020-3976-8","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1186/s13570-019-0156-6","year":2020,"genre":"journal-article","is_oa":true,"title":"Haematological changes in transhumant Baruwal sheep (Ovis aries) grazing in the western Himalayan mountains in Nepal","doi_url":"https://doi.org/10.1186/s13570-019-0156-6","updated":"2020-10-28T09:28:39.954182","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"ORCID":"http://orcid.org/0000-0001-6840-1503","given":"Shanker Raj","family":"Barsila","sequence":"first","authenticated-orcid":false},{"given":"Keshav","family":"Bhatt","sequence":"additional"},{"given":"Badrika","family":"Devkota","sequence":"additional"},{"given":"Naba Raj","family":"Devkota","sequence":"additional"}],"is_paratext":false,"journal_name":"Pastoralism","oa_locations":[{"url":"https://doi.org/10.1186/s13570-019-0156-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:49.170719","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13570-019-0156-6","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2041-7136","journal_issn_l":"2041-7136","published_date":"2020-02-26","best_oa_location":{"url":"https://doi.org/10.1186/s13570-019-0156-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:49.170719","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13570-019-0156-6","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1186/s13570-019-0156-6","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2020-02-26","updated":"2020-11-03T16:39:49.170719","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/s13570-019-0156-6","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":false} -{"doi":"10.1109/jphot.2020.3022703","year":2020,"genre":"journal-article","is_oa":true,"title":"Full-duplex self-recovery optical fibre transport system based on a passive single-line bidirectional optical add/drop multiplexer","doi_url":"https://doi.org/10.1109/jphot.2020.3022703","updated":"2020-10-29T13:15:15.936188","oa_status":"gold","publisher":"Institute of Electrical and Electronics Engineers (IEEE)","z_authors":[{"given":"Chung-Yi","family":"Li","sequence":"first"},{"ORCID":"http://orcid.org/0000-0003-2899-6535","given":"Ching-Hung","family":"Chang","sequence":"additional","authenticated-orcid":false},{"given":"Dong-Yi","family":"Lu","sequence":"additional"}],"is_paratext":false,"journal_name":"IEEE Photonics Journal","oa_locations":[{"url":"https://ieeexplore.ieee.org/ielx7/4563994/9180368/09188010.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-29T13:14:55.444190","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://ieeexplore.ieee.org/ielx7/4563994/9180368/09188010.pdf","url_for_landing_page":"https://doi.org/10.1109/jphot.2020.3022703","repository_institution":null},{"url":"https://doi.org/10.1109/jphot.2020.3022703","pmh_id":null,"is_best":false,"license":"cc-by","oa_date":"2020-10-01","updated":"2020-11-04T16:50:29.839713","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1109/jphot.2020.3022703","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1943-0655,1943-0647","journal_issn_l":"1943-0647","published_date":"2020-10-01","best_oa_location":{"url":"https://ieeexplore.ieee.org/ielx7/4563994/9180368/09188010.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-29T13:14:55.444190","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://ieeexplore.ieee.org/ielx7/4563994/9180368/09188010.pdf","url_for_landing_page":"https://doi.org/10.1109/jphot.2020.3022703","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1109/jphot.2020.3022703","pmh_id":null,"is_best":false,"license":"cc-by","oa_date":"2020-10-01","updated":"2020-11-04T16:50:29.839713","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1109/jphot.2020.3022703","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":false} -{"doi":"10.1109/jphotov.2020.3019951","year":2020,"genre":"journal-article","is_oa":false,"title":"Iodine Vacancy Formation Energy in CH$_{3}$NH$_{3}$PbI$_{3}$ Perovskite","doi_url":"https://doi.org/10.1109/jphotov.2020.3019951","updated":"2020-10-29T13:14:39.320906","oa_status":"closed","publisher":"Institute of Electrical and Electronics Engineers (IEEE)","z_authors":[{"given":"Hamid","family":"Shahivandi","sequence":"first"},{"given":"Majid","family":"Vaezzadeh","sequence":"additional"},{"ORCID":"http://orcid.org/0000-0002-6256-8975","given":"Mohammadreza","family":"Saeidi","sequence":"additional","authenticated-orcid":false}],"is_paratext":false,"journal_name":"IEEE Journal of Photovoltaics","oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":"2156-3381,2156-3403","journal_issn_l":"2156-3403","published_date":"2020-11-01","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1163/9789004325883_008","year":2017,"genre":"book-chapter","is_oa":false,"title":" « Man Zaydan ? » À propos de quelques cas curieux de ḥikāya chez Sībawayhi","doi_url":"https://doi.org/10.1163/9789004325883_008","updated":"2020-10-31T00:48:11.491658","oa_status":"closed","publisher":"BRILL","z_authors":null,"is_paratext":false,"journal_name":"Approaches to the History and Dialectology of Arabic in Honor of Pierre Larcher","oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":null,"journal_issn_l":null,"published_date":"2017-01-01","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.12700/aph.13.2.2016.2.8","year":2016,"genre":"journal-article","is_oa":true,"title":"Conceptualization with Incremental Bron-Kerbosch Algorithm in Big Data Architecture","doi_url":"https://doi.org/10.12700/aph.13.2.2016.2.8","updated":"2020-10-31T00:48:19.409446","oa_status":"bronze","publisher":"Obuda University","z_authors":null,"is_paratext":false,"journal_name":"Acta Polytechnica Hungarica","oa_locations":[{"url":"https://doi.org/10.12700/aph.13.2.2016.2.8","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-01-27T15:38:14.746780","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.12700/aph.13.2.2016.2.8","url_for_landing_page":null,"repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1785-8860","journal_issn_l":"1785-8860","published_date":"2016-02-29","best_oa_location":{"url":"https://doi.org/10.12700/aph.13.2.2016.2.8","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-01-27T15:38:14.746780","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.12700/aph.13.2.2016.2.8","url_for_landing_page":null,"repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.12700/aph.13.2.2016.2.8","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-01-27T15:38:14.746780","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.12700/aph.13.2.2016.2.8","url_for_landing_page":null,"repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2672.2004.02357.x","year":2004,"genre":"journal-article","is_oa":true,"title":"Identification of extracellular enzyme producing alkalophilic bacilli from Izmir province by 16S-ITS rDNA RFLP","doi_url":"https://doi.org/10.1111/j.1365-2672.2004.02357.x","updated":"2020-11-01T16:44:45.888944","oa_status":"bronze","publisher":"Wiley","z_authors":[{"given":"G.","family":"Akbalik","sequence":"first"},{"given":"H.","family":"Gunes","sequence":"additional"},{"given":"E.","family":"Yavuz","sequence":"additional"},{"given":"I.","family":"Yasa","sequence":"additional"},{"given":"S.","family":"Harsa","sequence":"additional"},{"given":"Z.S.","family":"Elmaci","sequence":"additional"},{"given":"A.F.","family":"Yenidunya","sequence":"additional"}],"is_paratext":false,"journal_name":"Journal of Applied Microbiology","oa_locations":[{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-12T06:10:30.544019","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2004.02357.x","repository_institution":null},{"url":"http://openaccess.iyte.edu.tr/xmlui/bitstream/11147/4730/1/4730.pdf","pmh_id":"oai:openaccess.iyte.edu.tr:11147/4730","is_best":false,"license":"cc-by-nc-nd","oa_date":null,"updated":"2020-10-30T20:38:03.475531","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"a603561abf99400b457","url_for_pdf":"http://openaccess.iyte.edu.tr/xmlui/bitstream/11147/4730/1/4730.pdf","url_for_landing_page":"http://hdl.handle.net/11147/4730","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1364-5072,1365-2672","journal_issn_l":"1364-5072","published_date":"2004-10-01","best_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-12T06:10:30.544019","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2004.02357.x","repository_institution":null},"first_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-10-12T06:10:30.544019","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2004.02357.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2004.02357.x","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1596/27933","year":2017,"genre":"book","is_oa":false,"title":"Zambia","doi_url":"https://doi.org/10.1596/27933","updated":"2020-11-03T08:59:15.968795","oa_status":"closed","publisher":"Washington, DC: World Bank","z_authors":[{"given":"Sudha Bala","family":"Krishnan","sequence":"first"},{"given":"Teresa","family":"Peterburs","sequence":"additional"}],"is_paratext":false,"journal_name":null,"oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":null,"journal_issn_l":null,"published_date":"2017-01-01","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1371/journal.pgen.1005040","year":2015,"genre":"journal-article","is_oa":true,"title":"Extreme-Depth Re-sequencing of Mitochondrial DNA Finds No Evidence of Paternal Transmission in Humans","doi_url":"https://doi.org/10.1371/journal.pgen.1005040","updated":"2020-11-04T09:11:25.074572","oa_status":"gold","publisher":"Public Library of Science (PLoS)","z_authors":[{"given":"Angela","family":"Pyle","sequence":"first"},{"given":"Gavin","family":"Hudson","sequence":"additional"},{"given":"Ian J.","family":"Wilson","sequence":"additional"},{"given":"Jonathan","family":"Coxhead","sequence":"additional"},{"given":"Tania","family":"Smertenko","sequence":"additional"},{"given":"Mary","family":"Herbert","sequence":"additional"},{"given":"Mauro","family":"Santibanez-Koref","sequence":"additional"},{"given":"Patrick F.","family":"Chinnery","sequence":"additional"}],"is_paratext":false,"journal_name":"PLOS Genetics","oa_locations":[{"url":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-05-14","updated":"2018-11-05T14:24:56.016950","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pgen.1005040","repository_institution":null},{"url":"https://doi.org/10.1371/journal.pgen.1005040","pmh_id":null,"is_best":false,"license":"cc-by","oa_date":"2015-05-14","updated":"2020-11-04T09:11:24.843215","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1371/journal.pgen.1005040","repository_institution":null},{"url":"http://europepmc.org/articles/pmc4431825?pdf=render","pmh_id":"oai:europepmc.org:gt9FHFtogtvhGDdzieRr","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4431825?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4431825","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://eprint.ncl.ac.uk/fulltext.aspx?url=214080/79A040F5-5FBD-41C7-A57C-EA7AFA954877.pdf&pub_id=214080","pmh_id":"oai:eprint.ncl.ac.uk:214080","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-10-31T15:15:05.904519","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"bat7kjmq3jvy3bqwnkle","url_for_pdf":"https://eprint.ncl.ac.uk/fulltext.aspx?url=214080/79A040F5-5FBD-41C7-A57C-EA7AFA954877.pdf&pub_id=214080","url_for_landing_page":"https://eprint.ncl.ac.uk/fulltext.aspx?url=214080/79A040F5-5FBD-41C7-A57C-EA7AFA954877.pdf&pub_id=214080","repository_institution":"Newcastle Univesity - Newcastle University ePrints"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4431825","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-04T09:11:24.843470","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4431825","repository_institution":null},{"url":"http://pdfs.semanticscholar.org/d761/c07cce66cb89fe8d6012e44e898fa7307604.pdf","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2019-10-01T00:00:00","version":"submittedVersion","evidence":"oa repository (semantic scholar lookup)","host_type":"repository","endpoint_id":"trmgzrn8eq4yx7ddvmzs","url_for_pdf":"http://pdfs.semanticscholar.org/d761/c07cce66cb89fe8d6012e44e898fa7307604.pdf","url_for_landing_page":"https://semanticscholar.org/paper/d761c07cce66cb89fe8d6012e44e898fa7307604","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1553-7404","journal_issn_l":"1553-7390","published_date":"2015-05-14","best_oa_location":{"url":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-05-14","updated":"2018-11-05T14:24:56.016950","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pgen.1005040","repository_institution":null},"first_oa_location":{"url":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2015-05-14","updated":"2018-11-05T14:24:56.016950","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosgenetics/article/file?id=10.1371/journal.pgen.1005040&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pgen.1005040","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.9783/9780812206401.34","year":2013,"genre":"book-chapter","is_oa":false,"title":"Chapter 1. “Sharīf of the Jewish Nation”: Reconceptualizing the House of David in the Islamic East","doi_url":"https://doi.org/10.9783/9780812206401.34","updated":"2020-11-04T09:11:18.761952","oa_status":"closed","publisher":"University of Pennsylvania Press","z_authors":null,"is_paratext":false,"journal_name":"This Noble House","oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":null,"journal_issn_l":null,"published_date":"2013-12-31","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.35448/jequ.v8i1.4967","year":2018,"genre":"journal-article","is_oa":true,"title":"Pengaruh Utang Luar Negeri Dan Penanaman Modal asing (PMA) Terhadap Pertumbuhan Ekonomi Di Indonesia","doi_url":"https://doi.org/10.35448/jequ.v8i1.4967","updated":"2020-11-04T09:11:14.156289","oa_status":"gold","publisher":"Faculty of Economics and Business - Universitas Sultan Ageng Tirtayasa","z_authors":[{"given":"Saharuddin","family":"Didu","sequence":"first"}],"is_paratext":false,"journal_name":"Jurnal Ekonomi-Qu","oa_locations":[{"url":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-04-30","updated":"2020-01-28T15:06:39.716373","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","url_for_landing_page":"https://doi.org/10.35448/jequ.v8i1.4967","repository_institution":null},{"url":"https://doi.org/10.35448/jequ.v8i1.4967","pmh_id":null,"is_best":false,"license":"cc-by","oa_date":"2018-04-30","updated":"2020-11-04T09:11:14.052663","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.35448/jequ.v8i1.4967","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2541-1314,2089-4473","journal_issn_l":"2089-4473","published_date":"2018-04-30","best_oa_location":{"url":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-04-30","updated":"2020-01-28T15:06:39.716373","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","url_for_landing_page":"https://doi.org/10.35448/jequ.v8i1.4967","repository_institution":null},"first_oa_location":{"url":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-04-30","updated":"2020-01-28T15:06:39.716373","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://jurnal.untirta.ac.id/index.php/Ekonomi-Qu/article/download/4967/3948","url_for_landing_page":"https://doi.org/10.35448/jequ.v8i1.4967","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2427.2008.01986.x","year":2008,"genre":"journal-article","is_oa":true,"title":"Diversity and functions of leaf-decaying fungi in human-altered streams","doi_url":"https://doi.org/10.1111/j.1365-2427.2008.01986.x","updated":"2020-11-01T16:44:26.790910","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"ANTOINE","family":"LECERF","sequence":"first"},{"given":"ERIC","family":"CHAUVET","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","pmh_id":"oai:HAL:hal-01345995v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-03-10T20:44:05.419374","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","repository_institution":null},{"url":"https://hal.archives-ouvertes.fr/hal-01345995/document","pmh_id":"oai:HAL:hal-01345995v1","is_best":false,"license":null,"oa_date":"2020-10-23","updated":"2020-10-31T20:06:53.119494","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"0bef5a4743b644a14cc","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01345995/document","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01345995/document","repository_institution":"IRD - Institut de recherche pour le développement - HAL"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070,1365-2427","journal_issn_l":"0046-5070","published_date":"2008-08-01","best_oa_location":{"url":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","pmh_id":"oai:HAL:hal-01345995v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-03-10T20:44:05.419374","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01345995/file/lecerf_9627.pdf","repository_institution":null},"first_oa_location":{"url":"https://hal.archives-ouvertes.fr/hal-01345995/document","pmh_id":"oai:HAL:hal-01345995v1","is_best":false,"license":null,"oa_date":"2020-10-23","updated":"2020-10-31T20:06:53.119494","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"0bef5a4743b644a14cc","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01345995/document","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01345995/document","repository_institution":"IRD - Institut de recherche pour le développement - HAL"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2672.2005.02574.x","year":2005,"genre":"journal-article","is_oa":true,"title":"Comparison of three methods of DNA extraction from cold-smoked salmon and impact of physical treatments","doi_url":"https://doi.org/10.1111/j.1365-2672.2005.02574.x","updated":"2020-11-01T16:44:28.881504","oa_status":"bronze","publisher":"Wiley","z_authors":[{"given":"S.","family":"Giacomazzi","sequence":"first"},{"given":"F.","family":"Leroi","sequence":"additional"},{"given":"J.-J.","family":"Joffraud","sequence":"additional"}],"is_paratext":false,"journal_name":"Journal of Applied Microbiology","oa_locations":[{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-09-10T15:27:05.779651","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2005.02574.x","repository_institution":null},{"url":"https://archimer.ifremer.fr/doc/2005/publication-1106.pdf","pmh_id":"oai:archimer.ifremer.fr:1106","is_best":false,"license":null,"oa_date":null,"updated":"2020-10-27T21:56:38.982797","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1c7ccdee485072c7cf1","url_for_pdf":"https://archimer.ifremer.fr/doc/2005/publication-1106.pdf","url_for_landing_page":"https://archimer.ifremer.fr/doc/2005/publication-1106.pdf","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1364-5072,1365-2672","journal_issn_l":"1364-5072","published_date":"2005-05-01","best_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-09-10T15:27:05.779651","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2005.02574.x","repository_institution":null},"first_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-09-10T15:27:05.779651","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2005.02574.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2005.02574.x","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.13045/jar.2020.00136","year":2020,"genre":"journal-article","is_oa":true,"title":"Electroacupuncture Treatment for Women with Primary Obesity: A Review of Randomized Controlled Trials","doi_url":"https://doi.org/10.13045/jar.2020.00136","updated":"2020-10-28T15:21:54.670428","oa_status":"gold","publisher":"Korean Acupuncture and Moxibustion Medicine Society","z_authors":[{"ORCID":"http://orcid.org/0000-0001-8642-475X","given":"Soo Jin","family":"Lee","sequence":"first","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0002-5003-2567","given":"Da Yoon","family":"Oh","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0002-4883-4499","given":"Jae Eun","family":"Park","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0001-7248-978X","given":"Min Cheol","family":"Lee","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0002-2815-2052","given":"Myung Kyu","family":"Jeon","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0001-5423-9429","given":"Yeong Suk","family":"Jang","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0003-2026-3986","given":"Hyeon Jin","family":"Kim","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0003-0689-1257","given":"Jae Young","family":"Ahn","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0003-0966-2919","given":"Noo ri","family":"Hong","sequence":"additional","authenticated-orcid":true},{"ORCID":"http://orcid.org/0000-0001-9736-959X","given":"Woo Young","family":"Kim","sequence":"additional","authenticated-orcid":true}],"is_paratext":false,"journal_name":"Journal of Acupuncture Research","oa_locations":[{"url":"http://www.e-jar.org/upload/pdf/jar-2020-00136.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-28T15:21:15.997252","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.e-jar.org/upload/pdf/jar-2020-00136.pdf","url_for_landing_page":"https://doi.org/10.13045/jar.2020.00136","repository_institution":null},{"url":"https://doi.org/10.13045/jar.2020.00136","pmh_id":null,"is_best":false,"license":"cc-by-nc-nd","oa_date":"2020-05-31","updated":"2020-11-03T16:40:00.360649","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.13045/jar.2020.00136","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2586-288X,2586-2898","journal_issn_l":"2586-288X","published_date":"2020-05-31","best_oa_location":{"url":"http://www.e-jar.org/upload/pdf/jar-2020-00136.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-28T15:21:15.997252","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.e-jar.org/upload/pdf/jar-2020-00136.pdf","url_for_landing_page":"https://doi.org/10.13045/jar.2020.00136","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.13045/jar.2020.00136","pmh_id":null,"is_best":false,"license":"cc-by-nc-nd","oa_date":"2020-05-31","updated":"2020-11-03T16:40:00.360649","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.13045/jar.2020.00136","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":false} -{"doi":"10.1515/biolog-2015-0050","year":2015,"genre":"journal-article","is_oa":false,"title":"A qualitative and quantitative study of thrips (Thysanoptera) on alfalfa and records of thrips species on cultivated and wild Medicago species of Greece","doi_url":"https://doi.org/10.1515/biolog-2015-0050","updated":"2020-10-28T09:29:10.502934","oa_status":"closed","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Evangelos G.","family":"Badieritakis","sequence":"first"},{"given":"Ricos C.","family":"Thanopoulos","sequence":"additional"},{"given":"Argyro A.","family":"Fantinou","sequence":"additional"},{"given":"Nikolaos G.","family":"Emmanouel","sequence":"additional"}],"is_paratext":false,"journal_name":"Biologia","oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":"1336-9563,0006-3088","journal_issn_l":"0006-3088","published_date":"2015-01-01","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1038/srep35129","year":2016,"genre":"journal-article","is_oa":true,"title":"Capturing coupled riparian and coastal disturbance from industrial mining using cloud-resilient satellite time series analysis","doi_url":"https://doi.org/10.1038/srep35129","updated":"2020-10-31T16:52:48.312220","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Michael","family":"Alonzo","sequence":"first"},{"given":"Jamon","family":"Van Den Hoek","sequence":"additional"},{"given":"Nabil","family":"Ahmed","sequence":"additional"}],"is_paratext":false,"journal_name":"Scientific Reports","oa_locations":[{"url":"https://doi.org/10.1038/srep35129","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2016-10-11","updated":"2020-10-31T16:52:48.240723","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1038/srep35129","repository_institution":null},{"url":"http://europepmc.org/articles/pmc5057129?pdf=render","pmh_id":"oai:europepmc.org:7Hgd5QKxoSZb6aHC22JW","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc5057129?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc5057129","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5057129","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-10-31T16:52:48.240914","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5057129","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2045-2322","journal_issn_l":"2045-2322","published_date":"2016-10-11","best_oa_location":{"url":"https://doi.org/10.1038/srep35129","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2016-10-11","updated":"2020-10-31T16:52:48.240723","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1038/srep35129","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1038/srep35129","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2016-10-11","updated":"2020-10-31T16:52:48.240723","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1038/srep35129","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2672.2007.03551.x","year":2007,"genre":"journal-article","is_oa":true,"title":"Bifidobacteria as indicators of faecal contamination along a sheep meat production chain","doi_url":"https://doi.org/10.1111/j.1365-2672.2007.03551.x","updated":"2020-11-01T16:44:51.951491","oa_status":"bronze","publisher":"Wiley","z_authors":[{"given":"V.","family":"Delcenserie","sequence":"first"},{"given":"D.","family":"Loncaric","sequence":"additional"},{"given":"C.","family":"Bonaparte","sequence":"additional"},{"given":"M.","family":"Upmann","sequence":"additional"},{"given":"B.","family":"China","sequence":"additional"},{"given":"G.","family":"Daube","sequence":"additional"},{"given":"F.","family":"Gavini","sequence":"additional"}],"is_paratext":false,"journal_name":"Journal of Applied Microbiology","oa_locations":[{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-02-27T14:50:43.416291","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2007.03551.x","repository_institution":null},{"url":"https://orbi.uliege.be/bitstream/2268/391/1/jam_3551.pdf","pmh_id":"oai:orbi.ulg.ac.be:2268/391","is_best":false,"license":null,"oa_date":null,"updated":"2020-10-30T06:46:57.721948","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"8d593a6996552cca86c","url_for_pdf":"https://orbi.uliege.be/bitstream/2268/391/1/jam_3551.pdf","url_for_landing_page":"http://orbi.ulg.ac.be/handle/2268/391","repository_institution":"University of Liège - Open Repository and Bibliography"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1364-5072,1365-2672","journal_issn_l":"1364-5072","published_date":"2007-10-08","best_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-02-27T14:50:43.416291","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2007.03551.x","repository_institution":null},"first_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-02-27T14:50:43.416291","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2672.2007.03551.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2672.2007.03551.x","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1073/pnas.1316708111","year":2014,"genre":"journal-article","is_oa":true,"title":"A seismologically consistent compositional model of Earth's core","doi_url":"https://doi.org/10.1073/pnas.1316708111","updated":"2020-11-01T12:32:43.275970","oa_status":"bronze","publisher":"Proceedings of the National Academy of Sciences","z_authors":[{"given":"J.","family":"Badro","sequence":"first"},{"given":"A. S.","family":"Cote","sequence":"additional"},{"given":"J. P.","family":"Brodholt","sequence":"additional"}],"is_paratext":false,"journal_name":"Proceedings of the National Academy of Sciences","oa_locations":[{"url":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-09-21T15:33:37.292167","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1316708111","repository_institution":null},{"url":"http://europepmc.org/articles/pmc4040578?pdf=render","pmh_id":"oai:europepmc.org:TzxVhDtwxYfkaQoLGPf4","is_best":false,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4040578?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4040578","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://hal-insu.archives-ouvertes.fr/insu-01387412/file/PNAS-2014-Badro-7542-5.pdf","pmh_id":"oai:HAL:insu-01387412v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-10-30T14:14:32.349310","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1917d1f02296464ee55","url_for_pdf":"https://hal-insu.archives-ouvertes.fr/insu-01387412/file/PNAS-2014-Badro-7542-5.pdf","url_for_landing_page":"https://hal-insu.archives-ouvertes.fr/insu-01387412/file/PNAS-2014-Badro-7542-5.pdf","repository_institution":"Inrap - Institut national de recherches archéologiques préventives - HAL"},{"url":"https://hal-insu.archives-ouvertes.fr/insu-01387412/document","pmh_id":"oai:HAL:insu-01387412v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-10-15T07:14:11.039284","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"f666d20cf545c330785","url_for_pdf":"https://hal-insu.archives-ouvertes.fr/insu-01387412/document","url_for_landing_page":"https://hal-insu.archives-ouvertes.fr/insu-01387412","repository_institution":"Université de Bretagne Occidentale - HAL"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4040578","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T12:32:40.952864","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4040578","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0027-8424,1091-6490","journal_issn_l":"0027-8424","published_date":"2014-05-12","best_oa_location":{"url":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-09-21T15:33:37.292167","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1316708111","repository_institution":null},"first_oa_location":{"url":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-09-21T15:33:37.292167","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/111/21/7542.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1316708111","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2672.2007.03559.x","year":2007,"genre":"journal-article","is_oa":true,"title":"Growth, CO2consumption and H2production of Anabaena variabilis ATCC 29413-U under different irradiances and CO2concentrations","doi_url":"https://doi.org/10.1111/j.1365-2672.2007.03559.x","updated":"2020-11-01T16:44:55.058034","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"H.","family":"Berberoğlu","sequence":"first"},{"given":"N.","family":"Barra","sequence":"additional"},{"given":"L.","family":"Pilon","sequence":"additional"},{"given":"J.","family":"Jay","sequence":"additional"}],"is_paratext":false,"journal_name":"Journal of Applied Microbiology","oa_locations":[{"url":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","pmh_id":"oai:escholarship.org/ark:/13030/qt3hn1j300","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-27T13:45:32.838539","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"0c2483948fb02b6f303","url_for_pdf":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","url_for_landing_page":"https://escholarship.org/uc/item/3hn1j300","repository_institution":"California Digital Library - eScholarship"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1364-5072,1365-2672","journal_issn_l":"1364-5072","published_date":"2007-10-08","best_oa_location":{"url":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","pmh_id":"oai:escholarship.org/ark:/13030/qt3hn1j300","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-27T13:45:32.838539","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"0c2483948fb02b6f303","url_for_pdf":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","url_for_landing_page":"https://escholarship.org/uc/item/3hn1j300","repository_institution":"California Digital Library - eScholarship"},"first_oa_location":{"url":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","pmh_id":"oai:escholarship.org/ark:/13030/qt3hn1j300","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-27T13:45:32.838539","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"0c2483948fb02b6f303","url_for_pdf":"https://escholarship.org/content/qt3hn1j300/qt3hn1j300.pdf?t=lnr32x","url_for_landing_page":"https://escholarship.org/uc/item/3hn1j300","repository_institution":"California Digital Library - eScholarship"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1016/j.sjbs.2020.08.005","year":2020,"genre":"journal-article","is_oa":true,"title":"The potential mitigation effect of ZnO nanoparticles on [Abelmoschus esculentus L. Moench] metabolism under salt stress conditions","doi_url":"https://doi.org/10.1016/j.sjbs.2020.08.005","updated":"2020-10-31T16:52:44.364670","oa_status":"gold","publisher":"Elsevier BV","z_authors":[{"given":"Nadiyah M.","family":"Alabdallah","sequence":"first"},{"given":"Hassan S.","family":"Alzahrani","sequence":"additional"}],"is_paratext":false,"journal_name":"Saudi Journal of Biological Sciences","oa_locations":[{"url":"https://doi.org/10.1016/j.sjbs.2020.08.005","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-11-01","updated":"2020-10-31T16:52:44.299648","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1016/j.sjbs.2020.08.005","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7569121","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-10-31T16:52:44.299825","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7569121","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1319-562X","journal_issn_l":"1319-562X","published_date":"2020-11-01","best_oa_location":{"url":"https://doi.org/10.1016/j.sjbs.2020.08.005","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-11-01","updated":"2020-10-31T16:52:44.299648","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1016/j.sjbs.2020.08.005","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1016/j.sjbs.2020.08.005","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-11-01","updated":"2020-10-31T16:52:44.299648","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1016/j.sjbs.2020.08.005","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1016/j.xkme.2020.05.014","year":2020,"genre":"journal-article","is_oa":true,"title":"Alport Syndrome Classification and Management","doi_url":"https://doi.org/10.1016/j.xkme.2020.05.014","updated":"2020-10-31T16:52:39.643213","oa_status":"gold","publisher":"Elsevier BV","z_authors":[{"given":"Bradley A.","family":"Warady","sequence":"first"},{"given":"Rajiv","family":"Agarwal","sequence":"additional"},{"given":"Sripal","family":"Bangalore","sequence":"additional"},{"given":"Arlene","family":"Chapman","sequence":"additional"},{"given":"Adeera","family":"Levin","sequence":"additional"},{"given":"Peter","family":"Stenvinkel","sequence":"additional"},{"given":"Robert D.","family":"Toto","sequence":"additional"},{"given":"Glenn M.","family":"Chertow","sequence":"additional"}],"is_paratext":false,"journal_name":"Kidney Medicine","oa_locations":[{"url":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-09-01","updated":"2020-10-04T23:18:26.914514","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","url_for_landing_page":"https://doi.org/10.1016/j.xkme.2020.05.014","repository_institution":null},{"url":"https://doi.org/10.1016/j.xkme.2020.05.014","pmh_id":null,"is_best":false,"license":"cc-by-nc-nd","oa_date":"2020-09-01","updated":"2020-10-31T16:52:39.555366","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1016/j.xkme.2020.05.014","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7568086","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-10-31T16:52:39.555633","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7568086","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"2590-0595","journal_issn_l":"2590-0595","published_date":"2020-09-01","best_oa_location":{"url":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-09-01","updated":"2020-10-04T23:18:26.914514","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","url_for_landing_page":"https://doi.org/10.1016/j.xkme.2020.05.014","repository_institution":null},"first_oa_location":{"url":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","pmh_id":null,"is_best":true,"license":"cc-by-nc-nd","oa_date":"2020-09-01","updated":"2020-10-04T23:18:26.914514","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://www.kidneymedicinejournal.org/article/S2590059520301606/pdf","url_for_landing_page":"https://doi.org/10.1016/j.xkme.2020.05.014","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1073/pnas.1203743109","year":2012,"genre":"journal-article","is_oa":true,"title":"Biphasic water splitting by osmocene","doi_url":"https://doi.org/10.1073/pnas.1203743109","updated":"2020-11-01T12:32:45.850948","oa_status":"bronze","publisher":"Proceedings of the National Academy of Sciences","z_authors":[{"given":"P.","family":"Ge","sequence":"first"},{"given":"T. K.","family":"Todorova","sequence":"additional"},{"given":"I. H.","family":"Patir","sequence":"additional"},{"given":"A. J.","family":"Olaya","sequence":"additional"},{"given":"H.","family":"Vrubel","sequence":"additional"},{"given":"M.","family":"Mendez","sequence":"additional"},{"given":"X.","family":"Hu","sequence":"additional"},{"given":"C.","family":"Corminboeuf","sequence":"additional"},{"given":"H. H.","family":"Girault","sequence":"additional"}],"is_paratext":false,"journal_name":"Proceedings of the National Academy of Sciences","oa_locations":[{"url":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-10-23T14:44:25.368097","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1203743109","repository_institution":null},{"url":"http://europepmc.org/articles/pmc3406862?pdf=render","pmh_id":"oai:europepmc.org:pBbLPSrAeqoVBbFGMgyb","is_best":false,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc3406862?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc3406862","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3406862","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T12:32:45.528661","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3406862","repository_institution":null},{"url":"http://infoscience.epfl.ch/record/176267/files/finalonline.pdf","pmh_id":"oai:infoscience.tind.io:176267","is_best":false,"license":null,"oa_date":null,"updated":"2020-08-18T06:54:34.734606","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"7760ae59248d04d82fd","url_for_pdf":"http://infoscience.epfl.ch/record/176267/files/finalonline.pdf","url_for_landing_page":"http://infoscience.epfl.ch/record/176267/files/finalonline.pdf","repository_institution":"Ecole Polytechnique Fédérale de Lausanne - Infoscience"},{"url":"http://infoscience.epfl.ch/record/176267/files/pnas.1203743109_SI.pdf","pmh_id":"oai:infoscience.tind.io:176267","is_best":false,"license":null,"oa_date":null,"updated":"2020-08-08T04:19:28.569893","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"7760ae59248d04d82fd","url_for_pdf":"http://infoscience.epfl.ch/record/176267/files/pnas.1203743109_SI.pdf","url_for_landing_page":"http://infoscience.epfl.ch/record/176267/files/pnas.1203743109_SI.pdf","repository_institution":"Ecole Polytechnique Fédérale de Lausanne - Infoscience"},{"url":"https://infoscience.epfl.ch/record/176267/files/pnas.1203743109_SI.pdf","pmh_id":"oai:infoscience.tind.io:176267","is_best":false,"license":null,"oa_date":null,"updated":"2020-08-02T13:29:26.188932","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"7760ae59248d04d82fd","url_for_pdf":"https://infoscience.epfl.ch/record/176267/files/pnas.1203743109_SI.pdf","url_for_landing_page":"http://infoscience.epfl.ch/record/176267","repository_institution":"Ecole Polytechnique Fédérale de Lausanne - Infoscience"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0027-8424,1091-6490","journal_issn_l":"0027-8424","published_date":"2012-06-04","best_oa_location":{"url":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-10-23T14:44:25.368097","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1203743109","repository_institution":null},"first_oa_location":{"url":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-10-23T14:44:25.368097","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/29/11558.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1203743109","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1073/pnas.1204067109","year":2012,"genre":"journal-article","is_oa":true,"title":"Dynamics of a bacterial multidrug ABC transporter in the inward- and outward-facing conformations","doi_url":"https://doi.org/10.1073/pnas.1204067109","updated":"2020-11-01T12:32:37.715365","oa_status":"bronze","publisher":"Proceedings of the National Academy of Sciences","z_authors":[{"given":"S.","family":"Mehmood","sequence":"first"},{"given":"C.","family":"Domene","sequence":"additional"},{"given":"E.","family":"Forest","sequence":"additional"},{"given":"J.-M.","family":"Jault","sequence":"additional"}],"is_paratext":false,"journal_name":"Proceedings of the National Academy of Sciences","oa_locations":[{"url":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-12-05T12:08:06.568336","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204067109","repository_institution":null},{"url":"http://europepmc.org/articles/pmc3390859?pdf=render","pmh_id":"oai:europepmc.org:2535127","is_best":false,"license":null,"oa_date":null,"updated":"2020-06-01T01:16:29.527346","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc3390859?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc3390859","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3390859","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T12:32:35.046807","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3390859","repository_institution":null},{"url":"https://hal.archives-ouvertes.fr/hal-01004601/file/Mehmood_PNAS_12.pdf","pmh_id":"oai:HAL:hal-01004601v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-05-24T22:24:28.848872","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01004601/file/Mehmood_PNAS_12.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01004601/file/Mehmood_PNAS_12.pdf","repository_institution":null},{"url":"https://hal.archives-ouvertes.fr/hal-01004601/document","pmh_id":"oai:HAL:hal-01004601v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-04-27T16:55:42.188533","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-01004601/document","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-01004601","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0027-8424,1091-6490","journal_issn_l":"0027-8424","published_date":"2012-06-18","best_oa_location":{"url":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-12-05T12:08:06.568336","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204067109","repository_institution":null},"first_oa_location":{"url":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2019-12-05T12:08:06.568336","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/27/10832.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204067109","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1073/pnas.1204791109","year":2012,"genre":"journal-article","is_oa":true,"title":"Cage assembly of DegP protease is not required for substrate-dependent regulation of proteolytic activity or high-temperature cell survival","doi_url":"https://doi.org/10.1073/pnas.1204791109","updated":"2020-11-01T12:32:59.655327","oa_status":"bronze","publisher":"Proceedings of the National Academy of Sciences","z_authors":[{"given":"S.","family":"Kim","sequence":"first"},{"given":"R. T.","family":"Sauer","sequence":"additional"}],"is_paratext":false,"journal_name":"Proceedings of the National Academy of Sciences","oa_locations":[{"url":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-01-02T20:05:12.548235","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204791109","repository_institution":null},{"url":"http://europepmc.org/articles/pmc3358883?pdf=render","pmh_id":"oai:europepmc.org:AdLaLqkGbYA5nKw9syFz","is_best":false,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc3358883?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc3358883","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3358883","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T12:32:59.471158","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3358883","repository_institution":null},{"url":"https://dspace.mit.edu/bitstream/1721.1/75363/1/Kim-2012-Cage%20assembly%20of%20Deg.pdf","pmh_id":"oai:dspace.mit.edu:1721.1/75363","is_best":false,"license":"cc-by-nc","oa_date":null,"updated":"2020-10-29T13:55:51.083656","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"a996c19dace9d4ac72d","url_for_pdf":"https://dspace.mit.edu/bitstream/1721.1/75363/1/Kim-2012-Cage%20assembly%20of%20Deg.pdf","url_for_landing_page":"http://hdl.handle.net/1721.1/75363","repository_institution":"Massachusetts Institute of Technology - DSpace@MIT"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0027-8424,1091-6490","journal_issn_l":"0027-8424","published_date":"2012-04-23","best_oa_location":{"url":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-01-02T20:05:12.548235","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204791109","repository_institution":null},"first_oa_location":{"url":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-01-02T20:05:12.548235","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://www.pnas.org/content/pnas/109/19/7263.full.pdf","url_for_landing_page":"https://doi.org/10.1073/pnas.1204791109","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.7901/2169-3358-1997-1-213","year":1997,"genre":"journal-article","is_oa":false,"title":"SEA EMPRESSSPILL: IMPACTS ON MARINE AND COASTAL HABITATS","doi_url":"https://doi.org/10.7901/2169-3358-1997-1-213","updated":"2020-10-30T09:09:23.678382","oa_status":"closed","publisher":"International Oil Spill Conference","z_authors":[{"given":"Jon","family":"Moore","sequence":"first","affiliation":[{"name":"OPRU, Dolphin Court, Neyland, Pembrokeshire, Wales"}]},{"given":"Stephen","family":"Evans","sequence":"additional","affiliation":[{"name":"Countryside Council for Wales, Fishguard, Pembrokeshire, Wales"}]},{"given":"Blaise","family":"Bullimore","sequence":"additional","affiliation":[{"name":"Countryside Council for Wales, Skomer Marine Nature Reserve, Pembrokeshire, Wales"}]},{"given":"Jane","family":"Hodges","sequence":"additional","affiliation":[{"name":"Pembrokeshire Coast National Park Authority, Haverfordwest, Pembrokeshire, Wales"}]},{"given":"Robin","family":"Crump","sequence":"additional","affiliation":[{"name":"Field Studies Council, Orielton Field Center, Pembroke, Wales"}]},{"given":"Julian","family":"Cremona","sequence":"additional","affiliation":[{"name":"Field Studies Council, Dale Fort Field Center, Pembrokeshire, Wales"}]},{"given":"Francis","family":"Bunker","sequence":"additional","affiliation":[{"name":"Marine Seen, Bentlass, Pembrokeshire, Wales"}]},{"given":"Dale","family":"Rostron","sequence":"additional","affiliation":[{"name":"SubSea Survey, 13–14 Merlins Cross, Pembroke, Wales"}]},{"given":"Annette","family":"Little","sequence":"additional","affiliation":[{"name":"28 School Lane, Swavesey, Cambridge, United Kingdom"}]},{"given":"Yvonne","family":"Chamberlain","sequence":"additional","affiliation":[{"name":"Culverhouse Partners, Itchen Abbas, Winchester, United Kingdom"}]},{"given":"Peter","family":"Dyrynda","sequence":"additional","affiliation":[{"name":"School of Biological Sciences, University of Wales, Swansea, Wales"}]},{"given":"Adrian","family":"Worley","sequence":"additional","affiliation":[{"name":"Department of Biological Sciences, Napier University, Edinburgh, United Kingdom"}]}],"is_paratext":false,"journal_name":"International Oil Spill Conference Proceedings","oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":"2169-3358,2169-3366","journal_issn_l":"2169-3358","published_date":"1997-04-01","best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1016/j.socscimed.2015.02.017","year":2015,"genre":"journal-article","is_oa":true,"title":"Mobility and health sector development in China and India","doi_url":"https://doi.org/10.1016/j.socscimed.2015.02.017","updated":"2020-10-31T00:48:30.072293","oa_status":"green","publisher":"Elsevier BV","z_authors":[{"given":"Jennifer","family":"Holdaway","sequence":"first"},{"given":"Peggy","family":"Levitt","sequence":"additional"},{"given":"Jing","family":"Fang","sequence":"additional"},{"given":"Narasimhan","family":"Rajaram","sequence":"additional"}],"is_paratext":false,"journal_name":"Social Science & Medicine","oa_locations":[{"url":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","pmh_id":"oai:ir.igsnrr.ac.cn:311030/38642","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-02T22:09:13.768307","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"01d422d6c121df24ff1","url_for_pdf":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","url_for_landing_page":"http://ir.igsnrr.ac.cn/handle/311030/38642","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0277-9536","journal_issn_l":"0277-9536","published_date":"2015-04-01","best_oa_location":{"url":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","pmh_id":"oai:ir.igsnrr.ac.cn:311030/38642","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-02T22:09:13.768307","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"01d422d6c121df24ff1","url_for_pdf":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","url_for_landing_page":"http://ir.igsnrr.ac.cn/handle/311030/38642","repository_institution":null},"first_oa_location":{"url":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","pmh_id":"oai:ir.igsnrr.ac.cn:311030/38642","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-02T22:09:13.768307","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"01d422d6c121df24ff1","url_for_pdf":"http://ir.igsnrr.ac.cn/bitstream/311030/38642/1/Holdaway-2015-Mobility%20and%20health.pdf","url_for_landing_page":"http://ir.igsnrr.ac.cn/handle/311030/38642","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1371/journal.pone.0014392","year":2010,"genre":"journal-article","is_oa":true,"title":"Complexity of the Tensegrity Structure for Dynamic Energy and Force Distribution of Cytoskeleton during Cell Spreading","doi_url":"https://doi.org/10.1371/journal.pone.0014392","updated":"2020-11-04T09:11:27.443491","oa_status":"gold","publisher":"Public Library of Science (PLoS)","z_authors":[{"given":"Ting-Jung","family":"Chen","sequence":"first"},{"given":"Chia-Ching","family":"Wu","sequence":"additional"},{"given":"Ming-Jer","family":"Tang","sequence":"additional"},{"given":"Jong-Shin","family":"Huang","sequence":"additional"},{"given":"Fong-Chin","family":"Su","sequence":"additional"}],"is_paratext":false,"journal_name":"PLoS ONE","oa_locations":[{"url":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-12-21","updated":"2018-12-07T09:29:54.758153","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pone.0014392","repository_institution":null},{"url":"https://doi.org/10.1371/journal.pone.0014392","pmh_id":null,"is_best":false,"license":"cc-by","oa_date":"2010-12-21","updated":"2020-11-04T09:11:27.297464","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1371/journal.pone.0014392","repository_institution":null},{"url":"http://europepmc.org/articles/pmc3006198?pdf=render","pmh_id":"oai:europepmc.org:FX5oG3Tmw6EopH8D72Sp","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc3006198?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc3006198","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3006198","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-04T09:11:27.297759","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3006198","repository_institution":null},{"url":"http://pdfs.semanticscholar.org/84f6/dd65ebb0cdf137eed1e88412cc7f5d07af35.pdf","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2019-10-01T00:00:00","version":"submittedVersion","evidence":"oa repository (semantic scholar lookup)","host_type":"repository","endpoint_id":"trmgzrn8eq4yx7ddvmzs","url_for_pdf":"http://pdfs.semanticscholar.org/84f6/dd65ebb0cdf137eed1e88412cc7f5d07af35.pdf","url_for_landing_page":"https://semanticscholar.org/paper/84f6dd65ebb0cdf137eed1e88412cc7f5d07af35","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1932-6203","journal_issn_l":"1932-6203","published_date":"2010-12-21","best_oa_location":{"url":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-12-21","updated":"2018-12-07T09:29:54.758153","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pone.0014392","repository_institution":null},"first_oa_location":{"url":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2010-12-21","updated":"2018-12-07T09:29:54.758153","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0014392&type=printable","url_for_landing_page":"https://doi.org/10.1371/journal.pone.0014392","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.5688/aj7005115","year":2006,"genre":"journal-article","is_oa":true,"title":"Student Use ofNABPLaw Onlinein a Pharmacy Laws Project","doi_url":"https://doi.org/10.5688/aj7005115","updated":"2020-11-03T00:37:29.734075","oa_status":"green","publisher":"American Journal of Pharmaceutical Education","z_authors":[{"given":"Thomas K.","family":"Hazlet","sequence":"first"},{"given":"Dana P.","family":"Hammer","sequence":"additional"},{"given":"Cassandra J.","family":"Hartnett","sequence":"additional"},{"given":"Donald H.","family":"Williams","sequence":"additional"}],"is_paratext":false,"journal_name":"American Journal of Pharmaceutical Education","oa_locations":[{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-11-03T00:37:29.576574","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0002-9459,1553-6467","journal_issn_l":"0002-9459","published_date":"2006-09-01","best_oa_location":{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-11-03T00:37:29.576574","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","repository_institution":null},"first_oa_location":{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-11-03T00:37:29.576574","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1637009","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.24875/gmm.20000036","year":2020,"genre":"journal-article","is_oa":true,"title":"Terapia dual o triple en hipertensión arterial sistémica, ¿a quiénes, cuándo y con qué?","doi_url":"https://doi.org/10.24875/gmm.20000036","updated":"2020-10-29T03:52:14.018919","oa_status":"gold","publisher":"Publicidad Permanyer, SLU","z_authors":[{"given":"Martín","family":"Rosas-Peralta","sequence":"first"},{"given":"Gabriela","family":"Borrayo-Sánchez","sequence":"additional"},{"given":"Luis","family":"Alcocer","sequence":"additional"},{"given":"Juan L. G.","family":"Durán-Arenas","sequence":"additional"},{"given":"Víctor H.","family":"Borja-Aburto","sequence":"additional"}],"is_paratext":false,"journal_name":"Gaceta de M�xico","oa_locations":[{"url":"https://gacetamedicademexico.com/files/es/gmm_20_156_3_225-228.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-29T03:51:48.580664","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://gacetamedicademexico.com/files/es/gmm_20_156_3_225-228.pdf","url_for_landing_page":"https://doi.org/10.24875/gmm.20000036","repository_institution":null},{"url":"https://doi.org/10.24875/gmm.20000036","pmh_id":null,"is_best":false,"license":null,"oa_date":"2020-06-01","updated":"2020-11-04T09:11:25.266233","version":"publishedVersion","evidence":"oa journal (via observed oa rate)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.24875/gmm.20000036","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"0016-3813","journal_issn_l":"0016-3813","published_date":"2020-06-01","best_oa_location":{"url":"https://gacetamedicademexico.com/files/es/gmm_20_156_3_225-228.pdf","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2020-10-29T03:51:48.580664","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://gacetamedicademexico.com/files/es/gmm_20_156_3_225-228.pdf","url_for_landing_page":"https://doi.org/10.24875/gmm.20000036","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.24875/gmm.20000036","pmh_id":null,"is_best":false,"license":null,"oa_date":"2020-06-01","updated":"2020-11-04T09:11:25.266233","version":"publishedVersion","evidence":"oa journal (via observed oa rate)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.24875/gmm.20000036","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2923.2007.02797.x","year":2007,"genre":"journal-article","is_oa":true,"title":"Burnout in medical residents: a review","doi_url":"https://doi.org/10.1111/j.1365-2923.2007.02797.x","updated":"2020-11-01T16:44:56.125401","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"Jelle T","family":"Prins","sequence":"first"},{"given":"Stacey M","family":"Gazendam-Donofrio","sequence":"additional"},{"given":"Ben J","family":"Tubben","sequence":"additional"},{"given":"Frank M M A","family":"van der Heijden","sequence":"additional"},{"given":"Harry B M","family":"van de Wiel","sequence":"additional"},{"given":"Josette E H M","family":"Hoekstra-Weebers","sequence":"additional"}],"is_paratext":false,"journal_name":"Medical Education","oa_locations":[{"url":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","pmh_id":"oai:pure.rug.nl:publications/43974310-583a-477d-af4a-df3a3a50c277","is_best":true,"license":null,"oa_date":null,"updated":"2020-07-26T20:15:10.983890","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"3ba687452a47e90aa9f","url_for_pdf":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","url_for_landing_page":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","repository_institution":"University of Groningen / Centre for Information Technology - University of Groningen research database"},{"url":"https://www.rug.nl/research/portal/files/2781953/Prins_2007_Med_Educ.pdf","pmh_id":"rug:oai:pure.rug.nl:publications/43974310-583a-477d-af4a-df3a3a50c277","is_best":false,"license":null,"oa_date":null,"updated":"2020-06-01T16:04:26.097476","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"bfa41bc4dfeca7f7fae","url_for_pdf":"https://www.rug.nl/research/portal/files/2781953/Prins_2007_Med_Educ.pdf","url_for_landing_page":"https://www.rug.nl/research/portal/en/publications/burnout-in-medical-residents(43974310-583a-477d-af4a-df3a3a50c277).html","repository_institution":"DANS - Data Archiving and Networked Services - NARCIS - National Academic Research and Collaborations Information System"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0308-0110,1365-2923","journal_issn_l":"0308-0110","published_date":"2007-08-01","best_oa_location":{"url":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","pmh_id":"oai:pure.rug.nl:publications/43974310-583a-477d-af4a-df3a3a50c277","is_best":true,"license":null,"oa_date":null,"updated":"2020-07-26T20:15:10.983890","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"3ba687452a47e90aa9f","url_for_pdf":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","url_for_landing_page":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","repository_institution":"University of Groningen / Centre for Information Technology - University of Groningen research database"},"first_oa_location":{"url":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","pmh_id":"oai:pure.rug.nl:publications/43974310-583a-477d-af4a-df3a3a50c277","is_best":true,"license":null,"oa_date":null,"updated":"2020-07-26T20:15:10.983890","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"3ba687452a47e90aa9f","url_for_pdf":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","url_for_landing_page":"https://pure.rug.nl/ws/files/2781953/Prins_2007_Med_Educ.pdf","repository_institution":"University of Groningen / Centre for Information Technology - University of Groningen research database"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.14393/ufu.di.2018.728","year":null,"genre":"dissertation","is_oa":false,"title":"Qualidade do solo em local de disposição inadequada de resíduos sólidos em um município de pequeno porte","doi_url":"https://doi.org/10.14393/ufu.di.2018.728","updated":"2020-10-29T18:43:15.096282","oa_status":"closed","publisher":"EDUFU - Editora da Universidade Federal de Uberlandia","z_authors":[{"given":"Daniela","family":"Rezende","sequence":"first"}],"is_paratext":false,"journal_name":null,"oa_locations":[],"data_standard":2,"journal_is_oa":false,"journal_issns":null,"journal_issn_l":null,"published_date":null,"best_oa_location":null,"first_oa_location":null,"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2427.2009.02375.x","year":2010,"genre":"journal-article","is_oa":true,"title":"Integration of science and monitoring of river ecosystem health to guide investments in catchment protection and rehabilitation","doi_url":"https://doi.org/10.1111/j.1365-2427.2009.02375.x","updated":"2020-11-01T16:44:21.965154","oa_status":"bronze","publisher":"Wiley","z_authors":[{"given":"S. E.","family":"BUNN","sequence":"first"},{"given":"E. G.","family":"ABAL","sequence":"additional"},{"given":"M. J.","family":"SMITH","sequence":"additional"},{"given":"S. C.","family":"CHOY","sequence":"additional"},{"given":"C. S.","family":"FELLOWS","sequence":"additional"},{"given":"B. D.","family":"HARCH","sequence":"additional"},{"given":"M. J.","family":"KENNARD","sequence":"additional"},{"given":"F.","family":"SHELDON","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-11-22T19:47:11.045873","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2427.2009.02375.x","repository_institution":null},{"url":"https://research-repository.griffith.edu.au/bitstream/10072/33237/1/63381_1.pdf","pmh_id":"oai:research-repository.griffith.edu.au:10072/33237","is_best":false,"license":null,"oa_date":null,"updated":"2020-08-17T03:32:22.304300","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1682e0cdd0e88e4d723","url_for_pdf":"https://research-repository.griffith.edu.au/bitstream/10072/33237/1/63381_1.pdf","url_for_landing_page":"http://hdl.handle.net/10072/33237","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070,1365-2427","journal_issn_l":"0046-5070","published_date":"2010-01-01","best_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-11-22T19:47:11.045873","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2427.2009.02375.x","repository_institution":null},"first_oa_location":{"url":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-11-22T19:47:11.045873","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://onlinelibrary.wiley.com/doi/pdfdirect/10.1111/j.1365-2427.2009.02375.x","url_for_landing_page":"https://doi.org/10.1111/j.1365-2427.2009.02375.x","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1186/1940-0640-7-s1-a92","year":2012,"genre":"journal-article","is_oa":true,"title":"Feasibility of a brief intervention delivered via mobile phone to reduce harmful drinking and injury among trauma patients in New Zealand","doi_url":"https://doi.org/10.1186/1940-0640-7-s1-a92","updated":"2020-11-04T09:11:17.152437","oa_status":"gold","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Shanthi","family":"Ameratunga","sequence":"first"},{"given":"Emily","family":"Smith","sequence":"additional"},{"given":"Bridget","family":"Kool","sequence":"additional"},{"given":"Kimiora","family":"Raerino","sequence":"additional"}],"is_paratext":false,"journal_name":"Addiction Science & Clinical Practice","oa_locations":[{"url":"https://doi.org/10.1186/1940-0640-7-s1-a92","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2012-10-01","updated":"2020-11-04T09:11:17.099895","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/1940-0640-7-s1-a92","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3480121","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-04T09:11:17.100218","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3480121","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1940-0640","journal_issn_l":"1940-0632","published_date":"2012-10-01","best_oa_location":{"url":"https://doi.org/10.1186/1940-0640-7-s1-a92","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2012-10-01","updated":"2020-11-04T09:11:17.099895","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/1940-0640-7-s1-a92","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1186/1940-0640-7-s1-a92","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2012-10-01","updated":"2020-11-04T09:11:17.099895","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1186/1940-0640-7-s1-a92","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.13185/122","year":2012,"genre":"journal-article","is_oa":true,"title":"Arabicization and Arabic Expanding Techniques Used in Science Lectures in Two Arab Universities","doi_url":"https://doi.org/10.13185/122","updated":"2020-11-04T09:11:21.059248","oa_status":"bronze","publisher":"Ateneo de Manila University","z_authors":[{"given":"Mahmoud Sabri","family":"Al-Asal","sequence":"first"},{"given":"Oqlah Mahmoud","family":"Smadi","sequence":"additional"}],"is_paratext":false,"journal_name":"Perspectives in the Arts and Humanities Asia","oa_locations":[{"url":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-05-17T06:31:02.692904","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","url_for_landing_page":"https://doi.org/10.13185/122","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"2094-9375,2094-9219","journal_issn_l":"2094-9219","published_date":"2012-03-29","best_oa_location":{"url":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-05-17T06:31:02.692904","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","url_for_landing_page":"https://doi.org/10.13185/122","repository_institution":null},"first_oa_location":{"url":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-05-17T06:31:02.692904","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://journals.ateneo.edu/ojs/index.php/apah/article/download/122/53","url_for_landing_page":"https://doi.org/10.13185/122","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1007/s11356-016-6586-4","year":2016,"genre":"journal-article","is_oa":true,"title":"Characterization of microbial communities in wetland mesocosms receiving caffeine-enriched wastewater","doi_url":"https://doi.org/10.1007/s11356-016-6586-4","updated":"2020-10-27T14:35:35.867512","oa_status":"green","publisher":"Springer Science and Business Media LLC","z_authors":[{"given":"Dongqing","family":"Zhang","sequence":"first"},{"given":"Jinxue","family":"Luo","sequence":"additional"},{"given":"Zarraz May Ping","family":"Lee","sequence":"additional"},{"given":"Richard M.","family":"Gersberg","sequence":"additional"},{"given":"Yu","family":"Liu","sequence":"additional"},{"given":"Soon Keat","family":"Tan","sequence":"additional"},{"given":"Wun Jern","family":"Ng","sequence":"additional"}],"is_paratext":false,"journal_name":"Environmental Science and Pollution Research","oa_locations":[{"url":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","pmh_id":"oai:ir.rcees.ac.cn:311016/36110","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-21T20:32:52.333158","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"cb323cd173f932675c4","url_for_pdf":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","url_for_landing_page":"http://ir.rcees.ac.cn/handle/311016/36110","repository_institution":"Chinese Academy of Sciences - Research Center for Eco-Environmental Sciences OpenIR"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0944-1344,1614-7499","journal_issn_l":"0944-1344","published_date":"2016-04-12","best_oa_location":{"url":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","pmh_id":"oai:ir.rcees.ac.cn:311016/36110","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-21T20:32:52.333158","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"cb323cd173f932675c4","url_for_pdf":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","url_for_landing_page":"http://ir.rcees.ac.cn/handle/311016/36110","repository_institution":"Chinese Academy of Sciences - Research Center for Eco-Environmental Sciences OpenIR"},"first_oa_location":{"url":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","pmh_id":"oai:ir.rcees.ac.cn:311016/36110","is_best":true,"license":"cc-by-nc-sa","oa_date":null,"updated":"2020-10-21T20:32:52.333158","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"cb323cd173f932675c4","url_for_pdf":"http://ir.rcees.ac.cn/bitstream/311016/36110/1/Characterization%20of%20microbial%20communities%20in%20wetland%20mesocosms%20receiving%20caffeine-enriched%20wastewater.pdf","url_for_landing_page":"http://ir.rcees.ac.cn/handle/311016/36110","repository_institution":"Chinese Academy of Sciences - Research Center for Eco-Environmental Sciences OpenIR"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1016/j.envsci.2018.10.011","year":2019,"genre":"journal-article","is_oa":true,"title":"Designing collaborative governance: Insights from the drought contingency planning process for the lower Colorado River basin","doi_url":"https://doi.org/10.1016/j.envsci.2018.10.011","updated":"2020-11-03T00:37:28.436754","oa_status":"bronze","publisher":"Elsevier BV","z_authors":[{"given":"Abigail","family":"Sullivan","sequence":"first"},{"ORCID":"http://orcid.org/0000-0002-5518-1596","given":"Dave D.","family":"White","sequence":"additional","authenticated-orcid":false},{"given":"Michael","family":"Hanemann","sequence":"additional"}],"is_paratext":false,"journal_name":"Environmental Science & Policy","oa_locations":[{"url":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","pmh_id":null,"is_best":true,"license":"elsevier-specific: oa user license","oa_date":null,"updated":"2020-11-03T00:37:28.379175","version":"acceptedVersion","evidence":"open (via crossref license, author manuscript)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","url_for_landing_page":"https://doi.org/10.1016/j.envsci.2018.10.011","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1462-9011","journal_issn_l":"1462-9011","published_date":"2019-01-01","best_oa_location":{"url":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","pmh_id":null,"is_best":true,"license":"elsevier-specific: oa user license","oa_date":null,"updated":"2020-11-03T00:37:28.379175","version":"acceptedVersion","evidence":"open (via crossref license, author manuscript)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","url_for_landing_page":"https://doi.org/10.1016/j.envsci.2018.10.011","repository_institution":null},"first_oa_location":{"url":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","pmh_id":null,"is_best":true,"license":"elsevier-specific: oa user license","oa_date":null,"updated":"2020-11-03T00:37:28.379175","version":"acceptedVersion","evidence":"open (via crossref license, author manuscript)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"http://manuscript.elsevier.com/S1462901118305124/pdf/S1462901118305124.pdf","url_for_landing_page":"https://doi.org/10.1016/j.envsci.2018.10.011","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.9790/5728-10251416","year":2014,"genre":"journal-article","is_oa":true,"title":"A New Version of the Proof Of    n n  1 ","doi_url":"https://doi.org/10.9790/5728-10251416","updated":"2020-10-31T00:48:29.578562","oa_status":"bronze","publisher":"IOSR Journals","z_authors":[{"given":"Amusa","family":"I. Sesan","sequence":"first"},{"name":"Department Of Mathematics, University Of Lagos, Nigeria","sequence":"first"},{"given":"Mohammed","family":"A. Modiu","sequence":"additional"},{"given":"Baiyeri","family":"J. Funso","sequence":"additional"},{"given":"Ekakitie","family":"E.T","sequence":"additional"},{"given":"Adeniji","family":"A. Adesola","sequence":"additional"}],"is_paratext":false,"journal_name":"IOSR Journal of Mathematics","oa_locations":[{"url":"https://doi.org/10.9790/5728-10251416","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-07-16T23:08:29.970172","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.9790/5728-10251416","url_for_landing_page":null,"repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"2319-765X,2278-5728","journal_issn_l":"2278-5728","published_date":"2014-01-01","best_oa_location":{"url":"https://doi.org/10.9790/5728-10251416","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-07-16T23:08:29.970172","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.9790/5728-10251416","url_for_landing_page":null,"repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.9790/5728-10251416","pmh_id":null,"is_best":true,"license":null,"oa_date":null,"updated":"2018-07-16T23:08:29.970172","version":"publishedVersion","evidence":"open (via free pdf)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://doi.org/10.9790/5728-10251416","url_for_landing_page":null,"repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2427.2010.02385.x","year":2009,"genre":"journal-article","is_oa":true,"title":"Relative influences of DOC flux and subterranean fauna on microbial abundance and activity in aquifer sediments: new insights from 13C-tracer experiments","doi_url":"https://doi.org/10.1111/j.1365-2427.2010.02385.x","updated":"2020-11-01T16:44:29.122082","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"ARNAUD","family":"FOULQUIER","sequence":"first"},{"given":"LAURENT","family":"SIMON","sequence":"additional"},{"given":"FRANCK","family":"GILBERT","sequence":"additional"},{"given":"FRANCOIS","family":"FOUREL","sequence":"additional"},{"given":"FLORIAN","family":"MALARD","sequence":"additional"},{"given":"FLORIAN","family":"MERMILLOD-BLONDIN","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","pmh_id":"oai:HAL:halsde-00520932v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-05-22T01:18:59.831063","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","repository_institution":null},{"url":"https://hal.archives-ouvertes.fr/halsde-00520932/document","pmh_id":"oai:HAL:halsde-00520932v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-03-31T05:28:09.098247","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/halsde-00520932/document","url_for_landing_page":"https://hal.archives-ouvertes.fr/halsde-00520932/document","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070,1365-2427","journal_issn_l":"0046-5070","published_date":"2009-06-09","best_oa_location":{"url":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","pmh_id":"oai:HAL:halsde-00520932v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-05-22T01:18:59.831063","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","repository_institution":null},"first_oa_location":{"url":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","pmh_id":"oai:HAL:halsde-00520932v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-05-22T01:18:59.831063","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/halsde-00520932/file/Foulquier_et_al._2010.pdf","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.15252/embr.201439409","year":2014,"genre":"journal-article","is_oa":true,"title":"Omics and the bioeconomy: Applications of genomics hold great potential for a future bio-based economy and sustainable development","doi_url":"https://doi.org/10.15252/embr.201439409","updated":"2020-11-03T16:38:35.279822","oa_status":"green","publisher":"EMBO","z_authors":[{"given":"Gerardo","family":"Jiménez‐Sánchez","sequence":"first","affiliation":[{"name":"Harvard School of Public Health Department of Epidemiology Harvard University Boston MA USA"},{"name":"Global Biotech Consulting Group Mexico City Mexico"}]},{"given":"Jim","family":"Philp","sequence":"additional","affiliation":[{"name":"OECD Directorate for Science Technology and Innovation Paris France"}]}],"is_paratext":false,"journal_name":"EMBO reports","oa_locations":[{"url":"http://europepmc.org/articles/pmc4304725?pdf=render","pmh_id":"oai:europepmc.org:etewbvqmi73kujAg86qo","is_best":true,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4304725?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4304725","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4304725","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-04T00:36:24.897480","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4304725","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1469-221X,1469-3178","journal_issn_l":"1469-221X","published_date":"2014-12-04","best_oa_location":{"url":"http://europepmc.org/articles/pmc4304725?pdf=render","pmh_id":"oai:europepmc.org:etewbvqmi73kujAg86qo","is_best":true,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4304725?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4304725","repository_institution":"PubMed Central - Europe PMC"},"first_oa_location":{"url":"http://europepmc.org/articles/pmc4304725?pdf=render","pmh_id":"oai:europepmc.org:etewbvqmi73kujAg86qo","is_best":true,"license":null,"oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc4304725?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc4304725","repository_institution":"PubMed Central - Europe PMC"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2427.2010.02544.x","year":2010,"genre":"journal-article","is_oa":true,"title":"Seasonal contrasts in carbon resources and ecological processes on a tropical floodplain","doi_url":"https://doi.org/10.1111/j.1365-2427.2010.02544.x","updated":"2020-11-01T16:45:03.391819","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"N. E.","family":"PETTIT","sequence":"first"},{"given":"P.","family":"BAYLISS","sequence":"additional"},{"given":"P. M.","family":"DAVIES","sequence":"additional"},{"given":"S. K.","family":"HAMILTON","sequence":"additional"},{"given":"D. M.","family":"WARFE","sequence":"additional"},{"given":"S. E.","family":"BUNN","sequence":"additional"},{"given":"M. M.","family":"DOUGLAS","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","pmh_id":"oai:research-repository.griffith.edu.au:10072/42506","is_best":true,"license":null,"oa_date":null,"updated":"2020-08-27T20:08:34.182040","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1682e0cdd0e88e4d723","url_for_pdf":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","url_for_landing_page":"http://hdl.handle.net/10072/42506","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070","journal_issn_l":"0046-5070","published_date":"2010-12-14","best_oa_location":{"url":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","pmh_id":"oai:research-repository.griffith.edu.au:10072/42506","is_best":true,"license":null,"oa_date":null,"updated":"2020-08-27T20:08:34.182040","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1682e0cdd0e88e4d723","url_for_pdf":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","url_for_landing_page":"http://hdl.handle.net/10072/42506","repository_institution":null},"first_oa_location":{"url":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","pmh_id":"oai:research-repository.griffith.edu.au:10072/42506","is_best":true,"license":null,"oa_date":null,"updated":"2020-08-27T20:08:34.182040","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"1682e0cdd0e88e4d723","url_for_pdf":"https://research-repository.griffith.edu.au/bitstream/10072/42506/1/74054_1.pdf","url_for_landing_page":"http://hdl.handle.net/10072/42506","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1111/eva.12532","year":2017,"genre":"journal-article","is_oa":true,"title":"Rapid evolution of symbiont-mediated resistance compromises biological control of aphids by parasitoids","doi_url":"https://doi.org/10.1111/eva.12532","updated":"2020-11-01T16:45:00.363962","oa_status":"gold","publisher":"Wiley","z_authors":[{"ORCID":"http://orcid.org/0000-0002-2149-8050","given":"Heidi","family":"Käch","sequence":"first","affiliation":[{"name":"Aquatic Ecology; Eawag; Dübendorf Switzerland"},{"name":"Institute of Integrative Biology; ETH Zürich; Zürich Switzerland"}],"authenticated-orcid":false},{"given":"Hugo","family":"Mathé-Hubert","sequence":"additional","affiliation":[{"name":"Aquatic Ecology; Eawag; Dübendorf Switzerland"}]},{"given":"Alice B.","family":"Dennis","sequence":"additional","affiliation":[{"name":"Institute for Biochemistry & Biology; University of Potsdam; Potsdam Germany"}]},{"ORCID":"http://orcid.org/0000-0002-3627-0841","given":"Christoph","family":"Vorburger","sequence":"additional","affiliation":[{"name":"Aquatic Ecology; Eawag; Dübendorf Switzerland"},{"name":"Institute of Integrative Biology; ETH Zürich; Zürich Switzerland"}],"authenticated-orcid":false}],"is_paratext":false,"journal_name":"Evolutionary Applications","oa_locations":[{"url":"https://doi.org/10.1111/eva.12532","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-09-03","updated":"2020-11-01T16:44:59.786466","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12532","repository_institution":null},{"url":"http://europepmc.org/articles/pmc5775498?pdf=render","pmh_id":"oai:europepmc.org:cQpR9JUufSsZGScZSnJY","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc5775498?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc5775498","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://www.dora.lib4ri.ch/eawag/islandora/object/eawag%3A16030/datastream/PDF/K%C3%A4ch-2018-Rapid_evolution_of_symbiont-mediated_resistance-%28published_version%29.pdf","pmh_id":"oai:dora:eawag_16030","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-09-05T23:22:02.054571","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"0e4b3470adfe367233a","url_for_pdf":"https://www.dora.lib4ri.ch/eawag/islandora/object/eawag%3A16030/datastream/PDF/K%C3%A4ch-2018-Rapid_evolution_of_symbiont-mediated_resistance-%28published_version%29.pdf","url_for_landing_page":"https://www.dora.lib4ri.ch/eawag/islandora/object/eawag%3A16030","repository_institution":"Swiss Federal Institute of Aquatic Science and Technology (Eawag) - DORA Eawag"},{"url":"https://publishup.uni-potsdam.de/files/42354/pmnr620.pdf","pmh_id":"oai:kobv.de-opus4-uni-potsdam:42354","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-10-27T20:15:28.590440","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"e2ec2ad47590679b13d","url_for_pdf":"https://publishup.uni-potsdam.de/files/42354/pmnr620.pdf","url_for_landing_page":"https://nbn-resolving.org/urn:nbn:de:kobv:517-opus4-423542","repository_institution":null},{"url":"https://publishup.uni-potsdam.de/opus4-ubp/files/42354/pmnr620.pdf","pmh_id":"oai:kobv.de-opus4-uni-potsdam:42354","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-09-19T22:11:08.541183","version":"publishedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"e2ec2ad47590679b13d","url_for_pdf":"https://publishup.uni-potsdam.de/opus4-ubp/files/42354/pmnr620.pdf","url_for_landing_page":"https://publishup.uni-potsdam.de/opus4-ubp/files/42354/pmnr620.pdf","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5775498","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T16:44:59.786697","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5775498","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1752-4571","journal_issn_l":"1752-4571","published_date":"2017-09-03","best_oa_location":{"url":"https://doi.org/10.1111/eva.12532","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-09-03","updated":"2020-11-01T16:44:59.786466","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12532","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1111/eva.12532","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-09-03","updated":"2020-11-01T16:44:59.786466","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12532","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2427.2011.02592.x","year":2011,"genre":"journal-article","is_oa":true,"title":"Modelling everything everywhere: a new approach to decision-making for water management under uncertainty","doi_url":"https://doi.org/10.1111/j.1365-2427.2011.02592.x","updated":"2020-11-01T16:44:33.104827","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"KEITH J.","family":"BEVEN","sequence":"first"},{"given":"RUTH E.","family":"ALCOCK","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","pmh_id":"oai:eprints.lse.ac.uk:60564","is_best":true,"license":"cc-by","oa_date":null,"updated":"2020-10-29T07:19:00.376912","version":"acceptedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"827e22a400ea712f72b","url_for_pdf":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","url_for_landing_page":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","repository_institution":"London School of Economics and Political Science - London School of Economics and Political Science Research Online"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070","journal_issn_l":"0046-5070","published_date":"2011-03-08","best_oa_location":{"url":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","pmh_id":"oai:eprints.lse.ac.uk:60564","is_best":true,"license":"cc-by","oa_date":null,"updated":"2020-10-29T07:19:00.376912","version":"acceptedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"827e22a400ea712f72b","url_for_pdf":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","url_for_landing_page":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","repository_institution":"London School of Economics and Political Science - London School of Economics and Political Science Research Online"},"first_oa_location":{"url":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","pmh_id":"oai:eprints.lse.ac.uk:60564","is_best":true,"license":"cc-by","oa_date":null,"updated":"2020-10-29T07:19:00.376912","version":"acceptedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"827e22a400ea712f72b","url_for_pdf":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","url_for_landing_page":"http://eprints.lse.ac.uk/60564/1/Beven_Alcock_Modelling-everything-everywhere_2012.pdf","repository_institution":"London School of Economics and Political Science - London School of Economics and Political Science Research Online"},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.2174/1874836801812010216","year":2018,"genre":"journal-article","is_oa":true,"title":"Retraction Notice: Research on Feasibility of Controlling Crack Resistance of the Concrete Expanded-Plates Pile Under Vertical Tension","doi_url":"https://doi.org/10.2174/1874836801812010216","updated":"2020-11-04T09:11:31.667418","oa_status":"hybrid","publisher":"Bentham Science Publishers Ltd.","z_authors":[{"given":"Qian","family":"Yongmei","sequence":"first"},{"given":"Wang","family":"Xu","sequence":"additional"},{"given":"Wang","family":"Ruozhu","sequence":"additional"}],"is_paratext":false,"journal_name":"The Open Construction & Building Technology Journal","oa_locations":[{"url":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-06-14","updated":"2019-09-05T13:54:16.948987","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","url_for_landing_page":"https://doi.org/10.2174/1874836801812010216","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"1874-8368","journal_issn_l":"1874-8368","published_date":"2018-06-14","best_oa_location":{"url":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-06-14","updated":"2019-09-05T13:54:16.948987","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","url_for_landing_page":"https://doi.org/10.2174/1874836801812010216","repository_institution":null},"first_oa_location":{"url":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2018-06-14","updated":"2019-09-05T13:54:16.948987","version":"publishedVersion","evidence":"open (via page says license)","host_type":"publisher","endpoint_id":null,"url_for_pdf":"https://openconstructionbuildingtechnologyjournal.com/VOLUME/12/PAGE/216/PDF/","url_for_landing_page":"https://doi.org/10.2174/1874836801812010216","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":false} -{"doi":"10.1111/j.1365-2427.2011.02620.x","year":2011,"genre":"journal-article","is_oa":true,"title":"Degradation of native and exotic riparian plant leaf litter in a floodplain pond","doi_url":"https://doi.org/10.1111/j.1365-2427.2011.02620.x","updated":"2020-11-01T16:44:59.869776","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"MARION","family":"BOTTOLLIER-CURTET","sequence":"first"},{"given":"JEAN-YVES","family":"CHARCOSSET","sequence":"additional"},{"given":"ANNE-MARIE","family":"PLANTY-TABACCHI","sequence":"additional"},{"given":"ERIC","family":"TABACCHI","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","pmh_id":"oai:HAL:hal-00955408v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-06-13T05:43:34.662721","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","repository_institution":null},{"url":"https://hal.archives-ouvertes.fr/hal-00955408/document","pmh_id":"oai:HAL:hal-00955408v1","is_best":false,"license":null,"oa_date":null,"updated":"2020-06-12T04:01:27.677125","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-00955408/document","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-00955408","repository_institution":null}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070","journal_issn_l":"0046-5070","published_date":"2011-05-30","best_oa_location":{"url":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","pmh_id":"oai:HAL:hal-00955408v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-06-13T05:43:34.662721","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","repository_institution":null},"first_oa_location":{"url":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","pmh_id":"oai:HAL:hal-00955408v1","is_best":true,"license":null,"oa_date":null,"updated":"2020-06-13T05:43:34.662721","version":"submittedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","url_for_landing_page":"https://hal.archives-ouvertes.fr/hal-00955408/file/Bottollier-Curtet_8909.pdf","repository_institution":null},"journal_is_in_doaj":false,"has_repository_copy":true} -{"doi":"10.1111/eva.12537","year":2017,"genre":"journal-article","is_oa":true,"title":"Effects of inbreeding on a gregarious parasitoid wasp with complementary sex determination","doi_url":"https://doi.org/10.1111/eva.12537","updated":"2020-11-01T16:44:40.099134","oa_status":"gold","publisher":"Wiley","z_authors":[{"ORCID":"http://orcid.org/0000-0002-4993-0386","given":"Tania","family":"Zaviezo","sequence":"first","affiliation":[{"name":"Facultad Agronomía e Ingeniería Forestal; Pontificia Universidad Católica de Chile; Santiago Chile"}],"authenticated-orcid":false},{"given":"Romina","family":"Retamal","sequence":"additional","affiliation":[{"name":"Facultad Agronomía e Ingeniería Forestal; Pontificia Universidad Católica de Chile; Santiago Chile"}]},{"given":"Teddy","family":"Urvois","sequence":"additional","affiliation":[{"name":"ISA; INRA, CNRS, Université Côte d'Azur; Sophia-Antipolis France"},{"name":"Université de Bourgogne; Dijon France"}]},{"given":"Xavier","family":"Fauvergue","sequence":"additional","affiliation":[{"name":"ISA; INRA, CNRS, Université Côte d'Azur; Sophia-Antipolis France"}]},{"given":"Aurélie","family":"Blin","sequence":"additional","affiliation":[{"name":"ISA; INRA, CNRS, Université Côte d'Azur; Sophia-Antipolis France"}]},{"given":"Thibaut","family":"Malausa","sequence":"additional","affiliation":[{"name":"ISA; INRA, CNRS, Université Côte d'Azur; Sophia-Antipolis France"}]}],"is_paratext":false,"journal_name":"Evolutionary Applications","oa_locations":[{"url":"https://doi.org/10.1111/eva.12537","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-10-13","updated":"2020-11-01T16:44:39.158531","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12537","repository_institution":null},{"url":"http://europepmc.org/articles/pmc5775491?pdf=render","pmh_id":"oai:europepmc.org:ZVYTqMejekAF6SfscXqc","is_best":false,"license":"cc-by","oa_date":null,"updated":null,"version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"b5e840539009389b1a6","url_for_pdf":"http://europepmc.org/articles/pmc5775491?pdf=render","url_for_landing_page":"http://europepmc.org/articles/pmc5775491","repository_institution":"PubMed Central - Europe PMC"},{"url":"https://hal.inrae.fr/hal-02621754/file/2018_Zaviezo_Evol%20Applic_1.pdf","pmh_id":"oai:HAL:hal-02621754v1","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-07-10T19:06:27.805596","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.inrae.fr/hal-02621754/file/2018_Zaviezo_Evol%20Applic_1.pdf","url_for_landing_page":"https://hal.inrae.fr/hal-02621754/file/2018_Zaviezo_Evol%20Applic_1.pdf","repository_institution":null},{"url":"https://hal.inrae.fr/hal-02621754/document","pmh_id":"oai:HAL:hal-02621754v1","is_best":false,"license":"cc-by","oa_date":null,"updated":"2020-07-10T19:18:07.174804","version":"publishedVersion","evidence":"oa repository (via OAI-PMH doi match)","host_type":"repository","endpoint_id":"2cb0529f001d4fe2c95","url_for_pdf":"https://hal.inrae.fr/hal-02621754/document","url_for_landing_page":"https://hal.inrae.fr/hal-02621754","repository_institution":null},{"url":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5775491","pmh_id":null,"is_best":false,"license":null,"oa_date":null,"updated":"2020-11-01T16:44:39.158823","version":"publishedVersion","evidence":"oa repository (via pmcid lookup)","host_type":"repository","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5775491","repository_institution":null}],"data_standard":2,"journal_is_oa":true,"journal_issns":"1752-4571","journal_issn_l":"1752-4571","published_date":"2017-10-13","best_oa_location":{"url":"https://doi.org/10.1111/eva.12537","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-10-13","updated":"2020-11-01T16:44:39.158531","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12537","repository_institution":null},"first_oa_location":{"url":"https://doi.org/10.1111/eva.12537","pmh_id":null,"is_best":true,"license":"cc-by","oa_date":"2017-10-13","updated":"2020-11-01T16:44:39.158531","version":"publishedVersion","evidence":"oa journal (via doaj)","host_type":"publisher","endpoint_id":null,"url_for_pdf":null,"url_for_landing_page":"https://doi.org/10.1111/eva.12537","repository_institution":null},"journal_is_in_doaj":true,"has_repository_copy":true} -{"doi":"10.1111/j.1365-2427.2011.02663.x","year":2011,"genre":"journal-article","is_oa":true,"title":"Indirect and direct controls of macroinvertebrates and small fish by abiotic factors and trophic interactions in the Florida Everglades","doi_url":"https://doi.org/10.1111/j.1365-2427.2011.02663.x","updated":"2020-11-01T16:44:33.393323","oa_status":"green","publisher":"Wiley","z_authors":[{"given":"BROOKE L.","family":"SARGEANT","sequence":"first"},{"given":"EVELYN E.","family":"GAISER","sequence":"additional"},{"given":"JOEL C.","family":"TREXLER","sequence":"additional"}],"is_paratext":false,"journal_name":"Freshwater Biology","oa_locations":[{"url":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","pmh_id":"oai:digitalcommons.fiu.edu:fce_lter_journal_articles-1219","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-26T22:15:32.497742","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"74ea586a01403fd1e30","url_for_pdf":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","url_for_landing_page":"https://digitalcommons.fiu.edu/fce_lter_journal_articles/213","repository_institution":"Florida International University - Florida International University Digital Commons"}],"data_standard":2,"journal_is_oa":false,"journal_issns":"0046-5070","journal_issn_l":"0046-5070","published_date":"2011-07-27","best_oa_location":{"url":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","pmh_id":"oai:digitalcommons.fiu.edu:fce_lter_journal_articles-1219","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-26T22:15:32.497742","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"74ea586a01403fd1e30","url_for_pdf":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","url_for_landing_page":"https://digitalcommons.fiu.edu/fce_lter_journal_articles/213","repository_institution":"Florida International University - Florida International University Digital Commons"},"first_oa_location":{"url":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","pmh_id":"oai:digitalcommons.fiu.edu:fce_lter_journal_articles-1219","is_best":true,"license":null,"oa_date":null,"updated":"2020-10-26T22:15:32.497742","version":"submittedVersion","evidence":"oa repository (via OAI-PMH title and first author match)","host_type":"repository","endpoint_id":"74ea586a01403fd1e30","url_for_pdf":"https://digitalcommons.fiu.edu/cgi/viewcontent.cgi?article=1219&context=fce_lter_journal_articles","url_for_landing_page":"https://digitalcommons.fiu.edu/fce_lter_journal_articles/213","repository_institution":"Florida International University - Florida International University Digital Commons"},"journal_is_in_doaj":false,"has_repository_copy":true} diff --git a/src/health/.eslintrc.json b/src/health/.eslintrc.json deleted file mode 100644 index b2333ba6..00000000 --- a/src/health/.eslintrc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "env": { - "mocha": true, - "commonjs": true, - "es2021": true, - "node": true - }, - "extends": [ - "airbnb-base" - ], - "parserOptions": { - "ecmaVersion": 12 - }, - "rules": { - "no-unused-vars": ["error", { "argsIgnorePattern": "next" }], - "no-await-in-loop": 0, - "consistent-return": 0, - "import/no-extraneous-dependencies": [ - "error", { "devDependencies": true } - ] - } -} diff --git a/src/health/Dockerfile b/src/health/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/health/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/health/README.md b/src/health/README.md deleted file mode 100644 index a1489464..00000000 --- a/src/health/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# ezunpaywall-health - -Health service indicating the status of the connection between each service. - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| GRAPHQL_HOST | http://graphql:3000 | graphql host | -| ENRICH_HOST | http://enrich:3000 | enrich host | -| UPDATE_HOST | http://update:3000 | update host | -| APIKEY_HOST | http://apikey:3000 | apikey host | -| MAIL_HOST | http://mail:3000 | mail host | -| ELASTICSEARCH_HOSTS | http://elastic | elasticsearch host | -| ELASTICSEARCH_PORT | 9200 | elasticsearch port | -| ELASTICSEARCH_USERNAME | elastic | elasticsearch admin username | -| ELASTICSEARCH_PASSWORD | changeme | elasticsearch admin password | -| REDIS_HOST | redis | redis host | -| REDIS_PORT | 6379 | redis port | -| REDIS_PASSWORD | changeme | redis password | -| UNPAYWALL_HOST | http://fakeUnpaywall:3000 | unpaywall host | -| UNPAYWALL_APIKEY | default | unpaywall apikey | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | \ No newline at end of file diff --git a/src/health/app.js b/src/health/app.js deleted file mode 100644 index 70b19d3e..00000000 --- a/src/health/app.js +++ /dev/null @@ -1,32 +0,0 @@ -const express = require('express'); -const cors = require('cors'); -const fs = require('fs-extra'); -const path = require('path'); - -const logger = require('./lib/logger'); -const getConfig = require('./lib/config'); - -const routerHealth = require('./lib/routers/health'); -const routerOpenapi = require('./lib/routers/openapi'); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); - -const app = express(); - -app.use(express.json()); -app.use(cors()); - -app.use(routerHealth); -app.use(routerOpenapi); - -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); - -app.use((error, req, res, next) => res.status(500).json({ message: error.message })); - -app.listen(3000, async () => { - logger.info('[express] ezunpaywall health service listening on 3000'); - getConfig(); -}); diff --git a/src/health/config/custom-environment-variables.json b/src/health/config/custom-environment-variables.json deleted file mode 100644 index 056c5fc9..00000000 --- a/src/health/config/custom-environment-variables.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "nodeEnv": "NODE_ENV", - "graphqlHost": "GRAPHQL_HOST", - "updateHost": "UPDATE_HOST", - "enrichHost": "ENRICH_HOST", - "apikeyHost": "APIKEY_HOST", - "mailHost": "MAIL_HOST", - "elasticsearch": { - "host": "ELASTICSEARCH_HOSTS", - "port": "ELASTICSEARCH_PORT", - "user": "ELASTICSEARCH_USERNAME", - "password": "ELASTICSEARCH_PASSWORD" - }, - "unpaywall": { - "host": "UNPAYWALL_HOST", - "apikey": "UNPAYWALL_APIKEY" - }, - "redis": { - "host": "REDIS_HOST", - "port": "REDIS_PORT", - "password": "REDIS_PASSWORD" - }, - "healthTimeout": "HEALTH_TIMEOUT" -} \ No newline at end of file diff --git a/src/health/config/default.json b/src/health/config/default.json deleted file mode 100644 index 21a434f9..00000000 --- a/src/health/config/default.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "nodeEnv": "development", - "graphqlHost": "http://graphql:3000", - "updateHost": "http://update:3000", - "enrichHost": "http://enrich:3000", - "apikeyHost": "http://apikey:3000", - "mailHost": "http://mail:3000", - "elasticsearch": { - "host": "http://elastic", - "port": 9200, - "user": "elastic", - "password": "changeme" - }, - "unpaywall": { - "host": "http://fakeUnpaywall:3000", - "apikey": "default" - }, - "redis": { - "host": "redis", - "port": "6379", - "password": "changeme" - }, - "healthTimeout": 3000 -} \ No newline at end of file diff --git a/src/health/lib/config.js b/src/health/lib/config.js deleted file mode 100644 index dda44ea5..00000000 --- a/src/health/lib/config.js +++ /dev/null @@ -1,33 +0,0 @@ -const config = require('config'); - -const logger = require('./logger'); -const defaultConfig = require('../config/default.json'); - -const copyConfig = JSON.parse(JSON.stringify(config)); - -/** - * Get config of service. - * - * @returns {Object} Config of service. - */ -function getConfig() { - if (copyConfig.redis.password === defaultConfig.redis.password) { - logger.warn('[config]: Redis password has the default value'); - } - if (copyConfig.elasticsearch.password === defaultConfig.elasticsearch.password) { - logger.warn('[config]: Elastic password has the default value'); - } - if (copyConfig.unpaywall.apikey === defaultConfig.unpaywall.apikey) { - logger.warn('[config]: Unpaywall apikey has the default value'); - } - - copyConfig.redis.password = '********'; - copyConfig.elasticsearch.password = '********'; - copyConfig.unpaywall.apikey = '********'; - - logger.info(JSON.stringify(copyConfig, null, 2)); - - return copyConfig; -} - -module.exports = getConfig; diff --git a/src/health/lib/controllers/health.js b/src/health/lib/controllers/health.js deleted file mode 100644 index 605ca1f8..00000000 --- a/src/health/lib/controllers/health.js +++ /dev/null @@ -1,27 +0,0 @@ -const healthAll = require('../health'); - -/** - * Controller to get health of all services of ezunpaywall. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function health(req, res, next) { - let resultPing = await healthAll(); - resultPing = resultPing.map((e) => e.value); - const result = {}; - - resultPing.forEach((e) => { - result[e?.name] = { - elapsedTime: e?.elapsedTime, - services: e?.services, - error: e?.error, - healthy: e?.healthy, - }; - }); - - return res.status(200).json(result); -} - -module.exports = health; diff --git a/src/health/lib/health.js b/src/health/lib/health.js deleted file mode 100644 index 95758b36..00000000 --- a/src/health/lib/health.js +++ /dev/null @@ -1,176 +0,0 @@ -const axios = require('axios'); -const config = require('config'); - -const logger = require('./logger'); - -const pingRedisWithClient = require('./services/redis'); -const pingElasticWithClient = require('./services/elastic'); - -const healthTimeout = config.get('healthTimeout'); - -/** - * Executes a promise but cuts it off after a while if it has not been resolved. - * this function is used for healthcheck routes. - * - * @param {Promise} p1 - Promise to be executed which will be stopped - * if it does not solve after a certain time. - * @param {string} name - Name of service. - * - * @returns {Promise} Status of healthcheck with name, time, optionnal error and healthy. - */ -async function PromiseOnHealthWithTimeout(p1, name) { - const start = Date.now(); - - const p2 = new Promise((resolve, reject) => { - setTimeout(reject, healthTimeout, new Error('time out')); - }); - - let reply; - - try { - reply = await Promise.race([p1, p2]); - } catch (err) { - logger.error(`[${name}]`, err); - return { - name, elapsedTime: Date.now() - start, error: err?.message, healthy: false, - }; - } - - const services = { ...reply }; - - delete services.elapsedTime; - delete services.healthy; - - return { - name, elapsedTime: Date.now() - start, services, healthy: reply.healthy || false, - }; -} - -/** - * Get health of serivce. - * - * @param {string} name - Name of service. - * @param {string} host - Host of service. - * - * @returns {Promise} Status of healthcheck with name, time, optionnal error and healthy. - */ -async function health(name, host) { - let res; - try { - res = await axios({ - method: 'GET', - url: `${host}/health`, - }); - } catch (err) { - logger.error(`[${name}] Cannot request ${host}/health`, err); - return false; - } - return res.data; -} - -/** - * Executes a promise but cuts it off after a while if it has not been resolved. - * This function is used for healthcheck routes. - * - * @param {Promise} p1 - Promise to be executed which will be stopped - * if it does not solve after a certain time. - * @param {string} name - Name of service. - * - * @returns {Promise} Status of healthcheck with name, time, optionnal error and healthy. - */ -async function promiseWithTimeout(p1, name) { - const start = Date.now(); - - const p2 = new Promise((resolve, reject) => { - setTimeout(reject, healthTimeout, new Error('time out')); - }); - - let reply; - - try { - reply = await Promise.race([p1, p2]); - } catch (err) { - logger.error(`[${name}]`, err); - return { - name, elapsedTime: Date.now() - start, error: err?.message, healthy: false, - }; - } - - let error; - let healthy = true; - - if (reply !== true) { - error = reply; - healthy = false; - } - - return { - name, elapsedTime: Date.now() - start, error, healthy, - }; -} - -/** - * Ping service. - * - * @param {string} name - Name of service. - * @param {string} host - Host of service. - * - * @returns {Promise} ping - */ -async function ping(name, host) { - try { - await axios({ - method: 'GET', - url: host, - }); - } catch (err) { - logger.error(`[${name}] Cannot request ${host}`, err); - return false; - } - return true; -} - -/** - * Health and ping all service on ezunpaywall. - * - * @returns {Promise} Sist of status of healthcheck with - * name, time, optionnal error and healthy for each service. - */ -async function healthAll() { - const graphqlHost = config.get('graphqlHost'); - const healthGraphql = PromiseOnHealthWithTimeout(health('graphql', graphqlHost), 'graphql'); - - const updateHost = config.get('updateHost'); - const healthUpdate = PromiseOnHealthWithTimeout(health('update', updateHost), 'update'); - - const enrichHost = config.get('enrichHost'); - const healthEnrich = PromiseOnHealthWithTimeout(health('enrich', enrichHost), 'enrich'); - - const apikeyHost = config.get('apikeyHost'); - const healthApikey = PromiseOnHealthWithTimeout(health('apikey', apikeyHost), 'apikey'); - - const mailHost = config.get('mailHost'); - const healthMail = PromiseOnHealthWithTimeout(health('mail', mailHost), 'mail'); - - const pingElastic = promiseWithTimeout(pingElasticWithClient(), 'elastic'); - - const unpaywallHost = config.get('unpaywall.host'); - const pingUnpaywall = promiseWithTimeout(ping('unpaywall', unpaywallHost), 'unpaywall'); - - const pingRedis = promiseWithTimeout(pingRedisWithClient(), 'redis'); - - const result = await Promise.allSettled([ - healthGraphql, - healthUpdate, - healthEnrich, - healthApikey, - healthMail, - pingElastic, - pingUnpaywall, - pingRedis, - ]); - - return result; -} - -module.exports = healthAll; diff --git a/src/health/lib/logger.js b/src/health/lib/logger.js deleted file mode 100644 index 7e3531ea..00000000 --- a/src/health/lib/logger.js +++ /dev/null @@ -1,60 +0,0 @@ -const path = require('path'); -const { nodeEnv } = require('config'); - -const isProd = (nodeEnv === 'production'); - -const { - createLogger, - transports, - format, -} = require('winston'); - -require('winston-daily-rotate-file'); - -const { - combine, - timestamp, - printf, - colorize, -} = format; - -// logger configuration -const processConfiguration = [ - new transports.DailyRotateFile({ - name: 'file', - filename: path.resolve(__dirname, '..', 'log', 'application', '%DATE%.log'), - datePattern: 'yyyy-MM-DD', - level: 'info', - }), - new (transports.Console)(), -]; - -function devFormat() { - const formatMessage = (info) => `${info.timestamp} ${info.level}: ${info.message}`; - const formatError = (info) => `${info.timestamp} ${info.level}: ${info.message}\n\n${info.stack}\n`; - const form = (info) => (info instanceof Error ? formatError(info) : formatMessage(info)); - return combine(colorize(), timestamp(), printf(form)); -} - -const logger = createLogger({ - level: process.env.LOG_LEVEL || 'info', - exitOnError: false, - transports: processConfiguration, - format: devFormat(), -}); - -logger.logError = logger.error; - -function error(text, err) { - logger.logError(text); - if (err) { - if (isProd) { - logger.logError(err?.message); - } else { - logger.logError(err); - } - } -} -logger.error = error; - -module.exports = logger; diff --git a/src/health/lib/routers/health.js b/src/health/lib/routers/health.js deleted file mode 100644 index cb82bbdb..00000000 --- a/src/health/lib/routers/health.js +++ /dev/null @@ -1,20 +0,0 @@ -const router = require('express').Router(); - -const health = require('../controllers/health'); - -/** - * Route that give the name of service. - */ -router.get('/', (req, res) => res.status(200).json('health service')); - -/** - * Route that ping the service. - */ -router.get('/ping', (req, res) => res.status(204).end()); - -/** - * route that gives the state of health of services - */ -router.get('/status', health); - -module.exports = router; diff --git a/src/health/lib/routers/openapi.js b/src/health/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/health/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/health/lib/services/elastic.js b/src/health/lib/services/elastic.js deleted file mode 100644 index f4b1dfb0..00000000 --- a/src/health/lib/services/elastic.js +++ /dev/null @@ -1,60 +0,0 @@ -const fs = require('fs-extra'); -const path = require('path'); - -const { Client } = require('@elastic/elasticsearch'); -const { URL } = require('url'); -const { elasticsearch } = require('config'); -const { nodeEnv } = require('config'); -const logger = require('../logger'); - -const isProd = (nodeEnv === 'production'); - -/** - * Ping elastic service. - * - * @returns {Promise} - */ -async function pingElasticWithClient() { - let ssl; - - if (isProd) { - let ca; - const caPath = path.resolve(__dirname, '..', '..', 'certs', 'ca.crt'); - try { - ca = await fs.readFile(caPath, 'utf8'); - } catch (err) { - logger.error(`[elastic] Cannot read certificate file in ${caPath}`, err); - return false; - } - ssl = { - ca, - rejectUnauthorized: true, - }; - } - - const elasticClient = new Client({ - node: { - url: new URL(`${elasticsearch.host}:${elasticsearch.port}`), - auth: { - username: elasticsearch.user, - password: elasticsearch.password, - }, - ssl, - }, - requestTimeout: 2000, - }); - let elasticStatus; - try { - elasticStatus = await elasticClient.ping(); - } catch (err) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port}`, err); - return false; - } - if (elasticStatus?.statusCode !== 200) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port} - ${elasticStatus?.statusCode}`); - return false; - } - return true; -} - -module.exports = pingElasticWithClient; diff --git a/src/health/lib/services/redis.js b/src/health/lib/services/redis.js deleted file mode 100644 index 5c0fdb54..00000000 --- a/src/health/lib/services/redis.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = require('config'); -const redis = require('redis'); -const logger = require('../logger'); - -/** - * Ping redis service. - * - * @returns @returns {Promise} - */ -async function pingRedisWithClient() { - const redisClient = redis.createClient({ - legacyMode: true, - socket: { - host: config.get('redis.host'), - port: config.get('redis.port'), - }, - password: config.get('redis.password'), - }); - - try { - await redisClient.connect(); - } catch (err) { - logger.error(`[redis] Cannot ping ${config.get('redis.host')}:${config.get('redis.port')}`, err); - return false; - } - - try { - await redisClient.disconnect(); - } catch (err) { - logger.error(`[redis] Cannot disconnect ${config.get('redis.host')}:${config.get('redis.port')}`, err); - return false; - } - return true; -} - -module.exports = pingRedisWithClient; diff --git a/src/health/openapi.json b/src/health/openapi.json deleted file mode 100644 index 628951a1..00000000 --- a/src/health/openapi.json +++ /dev/null @@ -1,477 +0,0 @@ -{ - "openapi": "3.0.0", - "x-stoplight": { - "id": "i72lagp6c0vth" - }, - "info": { - "description": "The Health service allows to know if the services are healthy or not", - "version": "1.0.0", - "title": "Health service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "paths": { - "/health": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "type": "string", - "x-examples": { - "Example 1": "health service" - } - }, - "examples": { - "service": { - "value": "health service" - } - } - }, - "Success": { - "examples": { - "response": { - "value": { - "message": "graphql service" - } - } - } - } - } - } - }, - "operationId": "get-graphql", - "description": "Get name of health service", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/health/ping": { - "get": { - "summary": "Your GET endpoint", - "tags": [ - "ping" - ], - "responses": { - "204": { - "description": "No Content" - } - }, - "operationId": "get-health-ping", - "description": "ping health service" - } - }, - "/health/health": { - "get": { - "summary": "Your GET endpoint", - "tags": [ - "ping" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "graphql": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "services": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elastic": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - } - }, - "status": { - "type": "boolean" - } - } - }, - "update": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "services": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elastic": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - } - }, - "status": { - "type": "boolean" - } - } - }, - "enrich": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "services": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "graphql": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - } - }, - "status": { - "type": "boolean" - } - } - }, - "apikey": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "services": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - } - }, - "status": { - "type": "boolean" - } - } - }, - "mail": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "services": { - "type": "object", - "properties": { - "smtp": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - }, - "error": { - "type": "string" - } - } - } - } - }, - "status": { - "type": "boolean" - } - } - }, - "elastic": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "unpaywall": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - }, - "x-examples": { - "Example 1": { - "graphql": { - "elapsedTime": 12, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "update": { - "elapsedTime": 11, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "enrich": { - "elapsedTime": 11, - "services": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "graphql": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "apikey": { - "elapsedTime": 9, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - } - }, - "status": true - }, - "mail": { - "elapsedTime": 109, - "services": { - "smtp": { - "elapsedTime": 104, - "status": false, - "error": "self signed certificate" - } - }, - "status": false - }, - "elastic": { - "elapsedTime": 11, - "status": true - }, - "unpaywall": { - "elapsedTime": 6, - "status": true - }, - "redis": { - "elapsedTime": 1, - "status": true - } - } - } - }, - "examples": { - "Success": { - "value": { - "graphql": { - "elapsedTime": 12, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "update": { - "elapsedTime": 11, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "enrich": { - "elapsedTime": 11, - "services": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "graphql": { - "elapsedTime": 1, - "status": true - } - }, - "status": true - }, - "apikey": { - "elapsedTime": 9, - "services": { - "redis": { - "elapsedTime": 0, - "status": true - } - }, - "status": true - }, - "mail": { - "elapsedTime": 109, - "services": { - "smtp": { - "elapsedTime": 104, - "status": false, - "error": "self signed certificate" - } - }, - "status": false - }, - "elastic": { - "elapsedTime": 11, - "status": true - }, - "unpaywall": { - "elapsedTime": 6, - "status": true - }, - "redis": { - "elapsedTime": 1, - "status": true - } - } - } - } - } - } - } - }, - "operationId": "get-health-health", - "description": "Health on all service relied to ezunpaywall" - } - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "tags": [ - { - "name": "ping" - } - ], - "components": { - "responses": {}, - "securitySchemes": {} - } -} \ No newline at end of file diff --git a/src/health/package-lock.json b/src/health/package-lock.json deleted file mode 100644 index 73c4dd1e..00000000 --- a/src/health/package-lock.json +++ /dev/null @@ -1,6447 +0,0 @@ -{ - "name": "ezunpaywall-health", - "version": "1.3.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "ezunpaywall-health", - "version": "1.3.0", - "license": "CeCILL", - "dependencies": { - "@elastic/elasticsearch": "^7.13.0", - "axios": "^1.5.0", - "config": "^3.3.9", - "cors": "^2.8.5", - "express": "^4.18.2", - "fs-extra": "^11.1.1", - "redis": "^4.6.8", - "winston": "^3.10.0", - "winston-daily-rotate-file": "^4.7.1" - }, - "devDependencies": { - "eslint": "^8.49.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "nodemon": "^3.0.1" - } - }, - "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/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@elastic/elasticsearch": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.13.0.tgz", - "integrity": "sha512-WgwLWo2p9P2tdqzBGX9fHeG8p5IOTXprXNTECQG2mJ7z9n93N5AFBJpEw4d35tWWeCWi9jI13A2wzQZH7XZ/xw==", - "dependencies": { - "debug": "^4.3.1", - "hpagent": "^0.1.1", - "ms": "^2.1.3", - "secure-json-parse": "^2.4.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@elastic/elasticsearch/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/@elastic/elasticsearch/node_modules/debug/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/@elastic/elasticsearch/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/@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.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "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/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/@eslint/eslintrc/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/@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "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/config-array/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/@humanwhocodes/config-array/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/@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/@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/@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/client": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", - "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", - "dependencies": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/json": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "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==", - "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-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/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/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": "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/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/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/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-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "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/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/axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.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==", - "dev": true - }, - "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/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==", - "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/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/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/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "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/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/chalk/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/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/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/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "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/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/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/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==" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "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==", - "dev": true - }, - "node_modules/config": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", - "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", - "dependencies": { - "json5": "^2.2.3" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/config/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "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==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "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==" - }, - "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==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "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/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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "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/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==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "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==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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==" - }, - "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": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", - "@humanwhocodes/config-array": "^0.11.11", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "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.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "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", - "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", - "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-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/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/eslint-import-resolver-node/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/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/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/eslint-module-utils/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/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/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/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/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/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "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.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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/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/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/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "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/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "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/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-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.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "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/file-stream-rotator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", - "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", - "dependencies": { - "moment": "^2.29.1" - } - }, - "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.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "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/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/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/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "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/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "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/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/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "engines": { - "node": ">= 4" - } - }, - "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==", - "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-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "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/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-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==", - "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==", - "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/hpagent": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", - "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==" - }, - "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==", - "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/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.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/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "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/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/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==" - }, - "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/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==", - "engines": { - "node": ">= 0.10" - } - }, - "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.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "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-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "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-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-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-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "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-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-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==", - "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.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "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, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-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/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "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/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "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/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.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/logform": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", - "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", - "dependencies": { - "@colors/colors": "1.5.0", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - }, - "node_modules/logform/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/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/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==", - "engines": { - "node": ">= 0.6" - } - }, - "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==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "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/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.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/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/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "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/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nodemon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", - "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/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/nodemon/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/nodemon/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "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/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "engines": { - "node": ">= 6" - } - }, - "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==", - "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/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "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==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "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/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/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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "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==", - "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-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==" - }, - "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/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/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==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "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/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==", - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "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/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==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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/redis": { - "version": "4.6.8", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", - "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", - "dependencies": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.9", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", - "@redis/time-series": "1.0.5" - } - }, - "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/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.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": "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/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/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/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-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz", - "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "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/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/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==", - "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/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "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/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "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/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.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.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-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/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/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "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/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==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "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.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/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "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/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==", - "engines": { - "node": ">= 0.4.0" - } - }, - "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==", - "engines": { - "node": ">= 0.8" - } - }, - "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-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "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/winston": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz", - "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==", - "dependencies": { - "@colors/colors": "1.5.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-daily-rotate-file": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", - "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", - "dependencies": { - "file-stream-rotator": "^0.6.1", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "winston": "^3" - } - }, - "node_modules/winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "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/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "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": { - "@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 - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" - }, - "@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@elastic/elasticsearch": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.13.0.tgz", - "integrity": "sha512-WgwLWo2p9P2tdqzBGX9fHeG8p5IOTXprXNTECQG2mJ7z9n93N5AFBJpEw4d35tWWeCWi9jI13A2wzQZH7XZ/xw==", - "requires": { - "debug": "^4.3.1", - "hpagent": "^0.1.1", - "ms": "^2.1.3", - "secure-json-parse": "^2.4.0" - }, - "dependencies": { - "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" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "@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.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "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": { - "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" - } - }, - "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 - } - } - }, - "@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "dependencies": { - "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" - } - }, - "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 - } - } - }, - "@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 - }, - "@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" - } - }, - "@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "requires": {} - }, - "@redis/client": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", - "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", - "requires": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - } - }, - "@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", - "requires": {} - }, - "@redis/json": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz", - "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==", - "requires": {} - }, - "@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "requires": {} - }, - "@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "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==", - "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-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "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-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": "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" - } - }, - "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" - } - }, - "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 - }, - "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-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - } - }, - "array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - } - }, - "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "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 - }, - "axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "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 - }, - "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 - }, - "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==", - "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" - } - }, - "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" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "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 - }, - "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": { - "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" - } - } - } - }, - "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" - } - }, - "cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - }, - "dependencies": { - "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==", - "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==" - } - } - }, - "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==" - }, - "color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "requires": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "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==", - "dev": true - }, - "config": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", - "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", - "requires": { - "json5": "^2.2.3" - }, - "dependencies": { - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - } - } - }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "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==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "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" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "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 - }, - "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==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "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" - } - }, - "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==" - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - } - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "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==" - }, - "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 - }, - "eslint": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", - "@humanwhocodes/config-array": "^0.11.11", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "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.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "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", - "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", - "text-table": "^0.2.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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 - } - } - }, - "eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "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" - } - }, - "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 - } - } - }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "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" - } - }, - "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 - } - } - }, - "eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "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" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "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 - } - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "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==" - }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "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" - } - }, - "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-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.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "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" - } - }, - "file-stream-rotator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", - "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", - "requires": { - "moment": "^2.29.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.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "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" - } - }, - "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" - } - }, - "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 - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "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" - } - }, - "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==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "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==", - "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 - }, - "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 - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "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 - }, - "generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==" - }, - "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==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "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" - } - }, - "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "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.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "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-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==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "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" - } - }, - "hpagent": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", - "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==" - }, - "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==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "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" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "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==" - }, - "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" - } - }, - "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==" - }, - "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.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "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-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "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-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "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-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "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-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-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==" - }, - "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.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "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 - }, - "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 - }, - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "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" - } - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "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" - } - }, - "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.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 - }, - "logform": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", - "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", - "requires": { - "@colors/colors": "1.5.0", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "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" - } - }, - "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==" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "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" - } - }, - "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.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "nodemon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", - "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "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" - } - }, - "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 - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "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 - }, - "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==" - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" - }, - "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==" - }, - "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" - } - }, - "object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "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==", - "requires": { - "ee-first": "1.1.1" - } - }, - "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" - } - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "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-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==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "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 - }, - "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==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "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==" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "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 - }, - "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==" - }, - "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==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "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==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "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" - } - }, - "redis": { - "version": "4.6.8", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", - "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", - "requires": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.9", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", - "@redis/time-series": "1.0.5" - } - }, - "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" - } - }, - "resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "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 - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "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-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - } - }, - "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==" - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safe-stable-stringify": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz", - "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "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": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "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==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "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 - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "requires": { - "semver": "^7.5.3" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "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.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "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-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 - }, - "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 - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "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 - }, - "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==" - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "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.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 - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "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==" - }, - "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==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "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-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "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" - } - }, - "winston": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz", - "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==", - "requires": { - "@colors/colors": "1.5.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.4.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" - } - }, - "winston-daily-rotate-file": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", - "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", - "requires": { - "file-stream-rotator": "^0.6.1", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - } - }, - "winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", - "requires": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - } - }, - "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 - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "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/src/health/package.json b/src/health/package.json deleted file mode 100644 index 128880fc..00000000 --- a/src/health/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "ezunpaywall-health", - "version": "1.3.5", - "description": "", - "main": "app.js", - "author": "felixleo22", - "license": "CeCILL", - "scripts": { - "start": "node app.js", - "dev": "nodemon -L -e .js,.json app.js", - "lint": "eslint --ext .js ." - }, - "dependencies": { - "@elastic/elasticsearch": "^7.13.0", - "axios": "^1.5.0", - "config": "^3.3.9", - "cors": "^2.8.5", - "express": "^4.18.2", - "fs-extra": "^11.1.1", - "redis": "^4.6.8", - "winston": "^3.10.0", - "winston-daily-rotate-file": "^4.7.1" - }, - "devDependencies": { - "eslint": "^8.49.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "nodemon": "^3.0.1" - } -} diff --git a/src/mail/.gitignore b/src/mail/.gitignore deleted file mode 100644 index e9ccb8c8..00000000 --- a/src/mail/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -log/ -test/ -.eslintrc.json -README.md \ No newline at end of file diff --git a/src/mail/Dockerfile b/src/mail/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/mail/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/mail/README.md b/src/mail/README.md deleted file mode 100644 index 98995b1b..00000000 --- a/src/mail/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# ezunpaywall-health - -Health service indicating the status of the connection between each service. - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| NODE_ENV | development | environment of node | -| NODE_CONFIG | {} | make tls and secure of mail (only in developement) | -| ACCESS_LOG_ROTATE | false | Set to true if you want to use access log rotation | -| MAIL_SMTP_HOST | localhost | SMTP server host | -| MAIL_SMTP_PORT | 25 | SMTP server port | -| MAIL_NOTIFICATIONS_SENDER | ezunpaywall | the sender for emails issued by ezunpaywall | -| MAIL_NOTIFICATIONS_RECEIVERS | ezunpaywall@example.fr" | recipients of the recent activity email | -| MAIL_NOTIFICATIONS_MACHINE | dev | environment of machine | -| MAIL_APIKEY | changeme | mail apikey | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | diff --git a/src/mail/app.js b/src/mail/app.js deleted file mode 100644 index edc91b6a..00000000 --- a/src/mail/app.js +++ /dev/null @@ -1,42 +0,0 @@ -const express = require('express'); -const cors = require('cors'); -const fs = require('fs-extra'); -const path = require('path'); - -const logger = require('./lib/logger'); -const morgan = require('./lib/morgan'); -const getConfig = require('./lib/config'); - -const routerPing = require('./lib/routers/ping'); -const routerMail = require('./lib/routers/mail'); -const routerOpenapi = require('./lib/routers/openapi'); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); -fs.ensureDir(path.resolve(logDir, 'access')); - -const app = express(); - -app.use(cors({ - origin: '*', - method: ['GET', 'POST'], -})); - -app.use(morgan); -app.use(express.urlencoded({ extended: true })); -app.use(express.json()); - -app.use(routerPing); -app.use(routerMail); -app.use(routerOpenapi); - -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); - -app.use((error, req, res, next) => res.status(500).json({ message: error.message })); - -app.listen(3000, () => { - logger.info('[express] ezunpaywall mail service listening on 3000'); - getConfig(); -}); diff --git a/src/mail/lib/routers/openapi.js b/src/mail/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/mail/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/mail/openapi.json b/src/mail/openapi.json deleted file mode 100644 index d82125fd..00000000 --- a/src/mail/openapi.json +++ /dev/null @@ -1,421 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "The mail service allows the sending of mail for the different services", - "version": "1.0.0", - "title": "Mail service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "paths": { - "/mail": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "type": "string", - "x-examples": { - "example-1": "mail service" - } - }, - "examples": { - "service": { - "value": "mail service" - } - } - }, - "Success": { - "examples": { - "response": { - "value": { - "message": "mail service" - } - } - } - } - } - } - }, - "operationId": "get-mail", - "description": "Get name of mail service", - "tags": [ - "ping" - ] - } - }, - "/mail/ping": { - "get": { - "summary": "Ping mail service", - "operationId": "get-mail-ping", - "description": "Ping mail service", - "tags": [ - "ping" - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/mail/health": { - "get": { - "summary": "Health", - "operationId": "get-mail-health", - "description": "Health on all service connected to enrich service", - "tags": [ - "ping" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "smtp": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - } - }, - "x-examples": { - "Example 1": { - "smtp": { - "elapsedTime": 1, - "status": true - } - } - } - }, - "examples": { - "Success": { - "value": { - "smtp": { - "elapsedTime": 1, - "status": true - } - } - }, - "Error smtp": { - "value": { - "smtp": { - "elapsedTime": 133, - "status": false, - "error": "self signed certificate" - } - } - } - } - } - } - } - } - }, - "parameters": [] - }, - "/mail/health/smtp": { - "get": { - "summary": "Health on SMTP service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-mail-health-smtp", - "description": "Health on smtp", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/mail/contact": { - "post": { - "summary": "Send mail contact", - "operationId": "post-mail-contact", - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Bad Request", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - }, - "email expected": { - "examples": { - "response": { - "value": { - "message": "email are expected" - } - } - } - }, - "invalid email": { - "examples": { - "response": { - "value": { - "message": "[\"john\"] is invalid email" - } - } - } - }, - "subject expected": { - "examples": { - "response": { - "value": { - "message": "subject are expected" - } - } - } - }, - "message expected": { - "examples": { - "response": { - "value": { - "message": "message are expected" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "403": { - "description": "Forbidden", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - } - } - } - }, - "description": "Send contact mail", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "mail" - ] - } - }, - "/mail/update-start": { - "post": { - "summary": "Send mail update process start", - "operationId": "post-mail-update-start", - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Bad Request", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "403": { - "description": "Forbidden", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - } - } - } - }, - "description": "Sending of the email informing the launch of the update process", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "mail" - ] - }, - "parameters": [] - }, - "/mail/update-end": { - "post": { - "summary": "Send mail update process ended", - "operationId": "post-mail-update-end", - "responses": { - "202": { - "description": "Accepted" - }, - "400": { - "description": "Bad Request", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "403": { - "description": "Forbidden", - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": {} - } - } - } - } - }, - "description": "Sending of the email with the report of the end of the update", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "mail" - ] - }, - "parameters": [] - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "tags": [ - { - "name": "mail" - }, - { - "name": "ping" - } - ], - "components": { - "responses": { - "Not-authorized": { - "description": "Not authorized", - "headers": {}, - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "Not authorized" - } - } - } - }, - "Not authorized": { - "examples": { - "response": { - "value": { - "message": "Not authorized" - } - } - } - } - } - }, - "Health": { - "description": "Example response", - "content": { - "Success": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "elapsedTime": { - "type": "integer" - } - }, - "x-examples": { - "Example 1": { - "name": "redis", - "status": true, - "elapsedTime": 1 - } - } - }, - "examples": { - "Success": { - "value": { - "name": "name of service", - "status": true, - "elapsedTime": 1 - } - }, - "Error smtp": { - "value": { - "elapsedTime": 115, - "status": false, - "error": "self signed certificate" - } - } - } - } - } - } - }, - "securitySchemes": { - "x-api-key": { - "name": "API Key", - "type": "apiKey", - "in": "header" - } - } - } -} \ No newline at end of file diff --git a/src/nginx/README.md b/src/nginx/README.md deleted file mode 100644 index e95cb02c..00000000 --- a/src/nginx/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# ezunpaywall-health - -Entry point and reverse proxy of ezunpaywall. - -## Docker environment variables - -| name | default | description | -| --- | --- | --- | -| NGINX_CONFIG_PATH | ./src/nginx/log/application | nginx config path | -| NGINX_ACCESS_LOG_PATH | ./src/nginx/log/access | access log output path | -| NGINX_PORT | 80 | output port | \ No newline at end of file diff --git a/src/update/Dockerfile b/src/update/Dockerfile deleted file mode 100644 index bcf3f763..00000000 --- a/src/update/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.17-alpine3.18 -LABEL maintainer="ezTeam " - -EXPOSE 3000 - -ENV NODE_ENV production - -WORKDIR /usr/src/app - -COPY package*.json ./ -RUN npm ci --omit=dev -COPY . . - -CMD [ "npm", "start" ] \ No newline at end of file diff --git a/src/update/README.md b/src/update/README.md deleted file mode 100644 index 1f380f52..00000000 --- a/src/update/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# ezunpaywall-health - -Health service indicating the status of the connection between each service. - -## Service environment variables - -| name | default | description | -| --- | --- | --- | -| NODE_ENV | development | environnement of node | -| UNPAYWALL_HOST | http://fakeunpaywall:3000 | unpaywall api host to access to changefiles | -| UNPAYWALL_APIKEY | changeme | unpaywall apikey to access to changefiles | -| MAIL_HOST | http://mail:3000 | mail service host | -| MAIL_APIKEY | changeme | mail apikey | -| ELASTICSEARCH_HOSTS | http://elastic | elastic host | -| ELASTICSEARCH_PORT | 9200 | elastic port | -| ELASTICSEARCH_USERNAME | elastic | username of elastic super user | -| ELASTICSEARCH_PASSWORD | changeme | password of elastic super user | -| ELASTICSEARCH_MAX_BULK_SIZE | 4000 | max bulk size of update process | -| ELASTICSEARCH_INDEX_ALIAS | upw | default alias of unpaywall data | -| UPDATE_CRON_SCHEDULE | 0 0 0 * * * | schedule of cron | -| UPDATE_CRON_ACTIVE | false | state of cron | -| UPDATE_CRON_INDEX | unpaywall | index of update process of cron | -| UPDATE_CRON_INTERVAL | day | interval of update process of cron | -| UPDATE_APIKEY | changeme | update apikey to start update process | -| HEALTH_TIMEOUT | 3000 | timeout to query the health route | \ No newline at end of file diff --git a/src/update/app.js b/src/update/app.js deleted file mode 100644 index d5b35653..00000000 --- a/src/update/app.js +++ /dev/null @@ -1,59 +0,0 @@ -const express = require('express'); -const fs = require('fs-extra'); -const path = require('path'); -const cors = require('cors'); - -const morgan = require('./lib/morgan'); -const logger = require('./lib/logger'); -const getConfig = require('./lib/config'); - -const routerPing = require('./lib/routers/ping'); -const routerJob = require('./lib/routers/job'); -const routerReport = require('./lib/routers/report'); -const routerSnapshot = require('./lib/routers/snapshot'); -const routerState = require('./lib/routers/state'); -const routerStatus = require('./lib/routers/status'); -const routerUnpaywall = require('./lib/routers/unpaywall'); -const routerCron = require('./lib/routers/cron'); -const routerElastic = require('./lib/routers/elastic'); -const routerOpenapi = require('./lib/routers/openapi'); - -require('./lib/cron/file'); - -const dataDir = path.resolve(__dirname, 'data'); -fs.ensureDir(path.resolve(dataDir)); -fs.ensureDir(path.resolve(dataDir, 'reports')); -fs.ensureDir(path.resolve(dataDir, 'states')); -fs.ensureDir(path.resolve(dataDir, 'snapshots')); - -const logDir = path.resolve(__dirname, 'log'); -fs.ensureDir(path.resolve(logDir)); -fs.ensureDir(path.resolve(logDir, 'application')); -fs.ensureDir(path.resolve(logDir, 'access')); - -const app = express(); - -app.use(express.json()); -app.use(cors()); -app.use(morgan); - -app.use(routerJob); -app.use(routerReport); -app.use(routerSnapshot); -app.use(routerState); -app.use(routerStatus); -app.use(routerUnpaywall); -app.use(routerCron); -app.use(routerElastic); -app.use(routerOpenapi); -app.use(routerPing); - -/* Errors and unknown routes */ -app.use((req, res, next) => res.status(404).json({ message: `Cannot ${req.method} ${req.originalUrl}` })); - -app.use((error, req, res, next) => res.status(500).json({ message: error.message })); - -app.listen(3000, async () => { - logger.info('[express] ezunpaywall update service listening on 3000'); - getConfig(); -}); diff --git a/src/update/config/custom-environment-variables.json b/src/update/config/custom-environment-variables.json deleted file mode 100644 index 6845e35f..00000000 --- a/src/update/config/custom-environment-variables.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "nodeEnv": "NODE_ENV", - "accessLogRotate": "ACCESS_LOG_ROTATE", - "unpaywall": { - "host": "UNPAYWALL_HOST", - "apikey": "UNPAYWALL_APIKEY" - }, - "mail": { - "host": "MAIL_HOST", - "apikey": "MAIL_APIKEY" - }, - "elasticsearch": { - "host": "ELASTICSEARCH_HOSTS", - "port": "ELASTICSEARCH_PORT", - "user": "ELASTICSEARCH_USERNAME", - "password": "ELASTICSEARCH_PASSWORD", - "maxBulkSize": "ELASTICSEARCH_MAX_BULK_SIZE", - "indexAlias": "ELASTICSEARCH_INDEX_ALIAS", - "timeout": "ELASTICSEARCH_TIMEOUT" - }, - "cron": { - "schedule": "UPDATE_CRON_SCHEDULE", - "active": "UPDATE_CRON_ACTIVE", - "index": "UPDATE_CRON_INDEX", - "interval": "UPDATE_CRON_INTERVAL" - }, - "apikey": "UPDATE_APIKEY", - "healthTimeout": "HEALTH_TIMEOUT" -} \ No newline at end of file diff --git a/src/update/config/default.json b/src/update/config/default.json deleted file mode 100644 index 93d3872a..00000000 --- a/src/update/config/default.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "nodeEnv": "development", - "accessLogRotate": false, - "unpaywall": { - "host": "http://fakeunpaywall:3000", - "apikey": "default" - }, - "mail": { - "host": "http://mail:3000", - "apikey": "changeme" - }, - "elasticsearch": { - "host": "http://elastic", - "port": 9200, - "user": "elastic", - "password": "changeme", - "maxBulkSize": 4000, - "indexAlias": "upw", - "timeout": 20000 - }, - "cron": { - "schedule": "0 0 0 * * *", - "active": false, - "index": "unpaywall", - "interval": "day" - }, - "apikey": "changeme", - "healthTimeout": 3000 -} \ No newline at end of file diff --git a/src/update/lib/controllers/cron.js b/src/update/lib/controllers/cron.js deleted file mode 100644 index e42fb369..00000000 --- a/src/update/lib/controllers/cron.js +++ /dev/null @@ -1,82 +0,0 @@ -const cronValidator = require('cron-validator'); -const cron = require('../cron/update'); - -/** - * Controller to start update cron. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -function startUpdateCron(req, res, next) { - try { - cron.updateCron.start(); - } catch (err) { - return next(err); - } - - return res.status(202).json(); -} - -/** - * Controller to stop update cron. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -function stopUpdateCron(req, res, next) { - try { - cron.updateCron.stop(); - } catch (err) { - return next(err); - } - - return res.status(202).json(); -} - -/** - * Controller to update config of update cron. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -function patchUpdateCron(req, res, next) { - const value = req.data; - const { time, index, interval } = value; - - if (time) { - const validCron = cronValidator.isValidCron(time, { seconds: true }); - if (!validCron) { return res.status(400).json('schedule is invalid'); } - } - - try { - cron.update({ time, index, interval }); - } catch (err) { - return next(err); - } - - const config = cron.getGlobalConfig(); - - return res.status(200).json(config); -} - -/** - * Controller to get config of update cron. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -function getConfigOfUpdateCron(req, res) { - const config = cron.getGlobalConfig(); - - return res.status(200).json(config); -} -module.exports = { - startUpdateCron, - stopUpdateCron, - patchUpdateCron, - getConfigOfUpdateCron, -}; diff --git a/src/update/lib/controllers/elastic.js b/src/update/lib/controllers/elastic.js deleted file mode 100644 index 2a804b4c..00000000 --- a/src/update/lib/controllers/elastic.js +++ /dev/null @@ -1,21 +0,0 @@ -const { initAlias } = require('../services/elastic'); -const unpaywallMapping = require('../../mapping/unpaywall.json'); - -/** - * Controller to create alias unpaywall on elastic. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function createAlias(req, res, next) { - try { - await initAlias('unpaywall', unpaywallMapping, 'upw'); - } catch (err) { - return next(err); - } - - return res.status(202).end(); -} - -module.exports = createAlias; diff --git a/src/update/lib/controllers/job.js b/src/update/lib/controllers/job.js deleted file mode 100644 index b539371a..00000000 --- a/src/update/lib/controllers/job.js +++ /dev/null @@ -1,114 +0,0 @@ -const fs = require('fs-extra'); -const path = require('path'); -const { format } = require('date-fns'); - -const snapshotsDir = path.resolve(__dirname, '..', '..', 'data', 'snapshots'); - -const { - downloadAndInsertSnapshot, - insertChangefilesOnPeriod, - insertChangefile, -} = require('../job'); - -/** - * Controller to start job that download and insert snapshot. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function downloadAndInsertSnapshotJob(req, res, next) { - const index = req.data; - - const jobConfig = { - index, - offset: 0, - limit: -1, - }; - - downloadAndInsertSnapshot(jobConfig); - return res.status(202).json(); -} - -/** - * Controller to start job that download ans insert changefiles on period. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function insertChangefilesOnPeriodJob(req, res, next) { - const { - startDate, - endDate, - index, - interval, - } = req.data; - - if (new Date(startDate).getTime() > Date.now()) { - return res.status(400).json({ message: 'startDate cannot be in the futur' }); - } - - if (startDate && endDate) { - if (new Date(endDate).getTime() < new Date(startDate).getTime()) { - return res.status(400).json({ message: 'endDate cannot be lower than startDate' }); - } - } - - const jobConfig = { - index, - interval, - startDate, - endDate, - offset: 0, - limit: -1, - }; - - if (!startDate && !endDate) { - jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); - if (interval === 'week') jobConfig.startDate = format(new Date() - (7 * 24 * 60 * 60 * 1000), 'yyyy-MM-dd'); - if (interval === 'day') jobConfig.startDate = format(new Date(), 'yyyy-MM-dd'); - - insertChangefilesOnPeriod(jobConfig); - return res.status(202).json(); - } - - if (startDate && !endDate) jobConfig.endDate = format(new Date(), 'yyyy-MM-dd'); - - insertChangefilesOnPeriod(jobConfig); - return res.status(202).json(); -} - -/** - * Controller to start job that insert file already installed. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function insertChangefileJob(req, res, next) { - const { - filename, index, offset, limit, - } = req.data; - - if (!await fs.pathExists(path.resolve(snapshotsDir, filename))) { - return res.status(404).json({ message: `File [${filename}] not found` }); - } - - const jobConfig = { - filename, - index, - offset, - limit, - }; - - insertChangefile(jobConfig); - - return res.status(202).json(); -} - -module.exports = { - downloadAndInsertSnapshotJob, - insertChangefilesOnPeriodJob, - insertChangefileJob, -}; diff --git a/src/update/lib/cron.js b/src/update/lib/cron.js deleted file mode 100644 index 4bf600ed..00000000 --- a/src/update/lib/cron.js +++ /dev/null @@ -1,59 +0,0 @@ -const { format, subDays } = require('date-fns'); - -const Cron = require('./models/cron'); - -const { insertChangefilesOnPeriod } = require('./job'); - -const updateConfig = { - index: 'unpaywall', - interval: 'day', -}; - -/** - * Starts an update daily process if no update process is started. - * - * @returns {Promise} - */ -async function task() { - const week = (updateConfig.interval === 'week'); - const startDate = format(subDays(new Date(), week ? 7 : 0), 'yyyy-MM-dd'); - const endDate = format(new Date(), 'yyyy-MM-dd'); - await insertChangefilesOnPeriod({ - index: updateConfig.index, - interval: updateConfig.interval, - startDate, - endDate, - offset: 0, - limit: -1, - }); -} - -const cron = new Cron('update', '0 0 0 * * *', task); - -/** - * Update config of update process and config of cron. - * - * @param {Object} config - Global config. - */ -function update(config) { - if (config.time) updateConfig.time = config.time; - if (config.index) updateConfig.index = config.index; - if (config.interval) updateConfig.interval = config.interval; - - cron.setTask(task); -} - -/** - * Get config of update process and config of cron. - * @returns {Object} Config of update process and config of cron. - */ -function getGlobalConfig() { - const config = cron.getConfig(); - return { ...config, ...updateConfig }; -} - -module.exports = { - getGlobalConfig, - update, - cron, -}; diff --git a/src/update/lib/cron/file.js b/src/update/lib/cron/file.js deleted file mode 100644 index b802ec80..00000000 --- a/src/update/lib/cron/file.js +++ /dev/null @@ -1,29 +0,0 @@ -const path = require('path'); -const logger = require('../logger'); -const Cron = require('../models/cron'); - -const { deleteFilesInDir } = require('../file'); - -const reportsDir = path.resolve(__dirname, '..', '..', 'data', 'reports'); -const snapshotDir = path.resolve(__dirname, '..', '..', 'data', 'snapshots'); -const states = path.resolve(__dirname, '..', '..', 'data', 'states'); - -/** - * Removes files generated by an update process that are older than 30 days. - * - * @returns {Promise} - */ -async function task() { - const deletedReportFiles = await deleteFilesInDir(reportsDir, 30); - logger.info(`[cron: delete out files] ${deletedReportFiles?.join(',')} (${deletedReportFiles.length}) reports are deleted`); - - const deletedSnapshotFiles = await deleteFilesInDir(snapshotDir, 30); - logger.info(`[cron: delete out files] ${deletedSnapshotFiles?.join(',')} (${deletedSnapshotFiles.length}) snapshots are deleted`); - - const deletedStateFiles = await deleteFilesInDir(states, 30); - logger.info(`[cron: delete out files] ${deletedStateFiles?.join(',')} (${deletedStateFiles.length}) states are deleted`); -} - -const cron = new Cron('delete out files', '0 0 0 * * *', task, true); - -module.exports = cron; diff --git a/src/update/lib/cron/update.js b/src/update/lib/cron/update.js deleted file mode 100644 index 4c292f12..00000000 --- a/src/update/lib/cron/update.js +++ /dev/null @@ -1,74 +0,0 @@ -const { format, subDays } = require('date-fns'); -const { cron } = require('config'); - -const Cron = require('../models/cron'); -const { getStatus } = require('../status'); - -const { insertChangefilesOnPeriod } = require('../job'); -const logger = require('../logger'); - -let { active } = cron; - -if (active === 'true' || active) active = true; -else active = false; - -const updateConfig = { - index: cron.index, - interval: cron.interval, -}; - -/** - * Starts an update daily process if no update process is started. - * - * @returns {Promise} - */ -async function task() { - const status = getStatus(); - if (status) { - logger.info(`[cron: ${this.name}] conflit: an update is already in progress`); - return; - } - const week = (updateConfig.interval === 'week'); - const startDate = format(subDays(new Date(), week ? 7 : 0), 'yyyy-MM-dd'); - const endDate = format(new Date(), 'yyyy-MM-dd'); - await insertChangefilesOnPeriod({ - index: updateConfig.index, - interval: updateConfig.interval, - startDate, - endDate, - offset: 0, - limit: -1, - }); -} - -const updateCron = new Cron('update', cron.schedule, task, active); - -/** - * Update config of update process and config of cron. - * - * @param {Object} newConfig - Global config. - */ -function update(newConfig) { - if (newConfig.time) updateCron.setSchedule(newConfig.time); - - if (newConfig.index) updateConfig.index = newConfig.index; - if (newConfig.interval) updateConfig.interval = newConfig.interval; - - if (newConfig.index || newConfig.interval) updateCron.setTask(task); -} - -/** - * Get config of update process and config of cron. - * - * @returns {Object} Config of update process and config of cron. - */ -function getGlobalConfig() { - const cronConfig = updateCron.getConfig(); - return { ...cronConfig, ...updateConfig }; -} - -module.exports = { - getGlobalConfig, - update, - updateCron, -}; diff --git a/src/update/lib/job.js b/src/update/lib/job.js deleted file mode 100644 index 4c61acbf..00000000 --- a/src/update/lib/job.js +++ /dev/null @@ -1,135 +0,0 @@ -/* eslint-disable no-param-reassign */ - -const logger = require('./logger'); - -const { - endState, fail, -} = require('./models/state'); - -const { - setInUpdate, -} = require('./status'); - -const { - downloadBigSnapshot, - downloadChangefile, -} = require('./download'); - -const { - createState, - addStepGetChangefiles, - updateLatestStep, - getLatestStep, -} = require('./models/state'); - -const insertDataUnpaywall = require('./insert'); - -const { - getChangefiles, -} = require('./services/unpaywall'); - -const { - sendMailNoChangefile, -} = require('./services/mail'); - -/** - * Download the current snapshot of unpaywall and insert his content. - * - * @param {Object} jobConfig - Config of job. - * @param {string} jobConfig.index - Name of the index to which the data will be inserted. - * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. - * @param {number} jobConfig.limit - Line in the file where the insertion stops. - * - * @returns {Promise} - */ -async function downloadAndInsertSnapshot(jobConfig) { - setInUpdate(true); - await createState(); - const filename = await downloadBigSnapshot(jobConfig); - if (!filename) { - await fail(); - return; - } - jobConfig.filename = filename; - await insertDataUnpaywall(jobConfig); - await endState(); -} - -/** - * Download and insert on elastic the changefiles from unpaywall between a period. - * - * @param {Object} jobConfig - Config of job. - * @param {string} jobConfig.index - Name of the index to which the data will be inserted. - * @param {string} jobConfig.interval - Interval of changefile, day or week are available. - * @param {string} jobConfig.startDate - Start date for the changefile period. - * @param {string} jobConfig.endDate - End date for the changefile period. - * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. - * @param {number} jobConfig.limit - Line in the file where the insertion stops. - * - * @returns {Promise} - */ -async function insertChangefilesOnPeriod(jobConfig) { - setInUpdate(true); - const { - interval, startDate, endDate, - } = jobConfig; - await createState(); - const start = new Date(); - addStepGetChangefiles(); - const step = getLatestStep(); - const changefilesInfo = await getChangefiles(interval, startDate, endDate); - - if (!changefilesInfo) { - step.status = 'error'; - updateLatestStep(step); - await fail(); - return; - } - - step.took = (new Date() - start) / 1000; - step.status = 'success'; - updateLatestStep(step); - - if (changefilesInfo.length === 0) { - sendMailNoChangefile(startDate, endDate).catch((err) => { - logger.errorRequest(err); - }); - await endState(); - return; - } - - let success = true; - for (let i = 0; i < changefilesInfo.length; i += 1) { - success = await downloadChangefile(changefilesInfo[i], interval); - if (!success) return; - jobConfig.filename = changefilesInfo[i].filename; - success = await insertDataUnpaywall(jobConfig); - if (!success) return; - } - await endState(); -} - -/** - * Insert on elastic the content of file installed on ezunpaywall. - * - * @param {Object} jobConfig - Config of job. - * @param {string} jobConfig.index - Name of the index to which the data will be inserted. - * @param {number} jobConfig.offset - Line of the snapshot at which the data insertion starts. - * @param {number} jobConfig.limit - Line in the file where the insertion stops. - * - * @returns {Promise} - */ -async function insertChangefile(jobConfig) { - setInUpdate(true); - await createState(); - const success = await insertDataUnpaywall(jobConfig); - if (success) { - await endState(); - } -} - -module.exports = { - downloadAndInsertSnapshot, - insertChangefilesOnPeriod, - insertChangefile, -}; diff --git a/src/update/lib/middlewares/cron.js b/src/update/lib/middlewares/cron.js deleted file mode 100644 index 57f53e7a..00000000 --- a/src/update/lib/middlewares/cron.js +++ /dev/null @@ -1,24 +0,0 @@ -const joi = require('joi').extend(require('@hapi/joi-date')); - -/** - * Joi middleware to check if cron config is correct. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function validateCronConfig(req, res, next) { - const { error, value } = joi.object({ - time: joi.string().trim(), - index: joi.string().trim(), - interval: joi.string().trim().valid('day', 'week'), - }).validate(req.body); - - if (error) return res.status(400).json({ message: error.details[0].message }); - - req.data = value; - - return next(); -} - -module.exports = validateCronConfig; diff --git a/src/update/lib/middlewares/interval.js b/src/update/lib/middlewares/interval.js deleted file mode 100644 index 435a6cb3..00000000 --- a/src/update/lib/middlewares/interval.js +++ /dev/null @@ -1,21 +0,0 @@ -const joi = require('joi'); - -/** - * Joi middleware to check if interval in body is correct. - * - * @param {import('express').Request} req - HTTP request. - * @param {import('express').Response} res - HTTP response. - * @param {import('express').NextFunction} next - Do the following. - */ -async function validateIntervale(req, res, next) { - const { error, value } = joi.string().trim().valid('week', 'day').default('day') - .validate(req.body.interval); - - if (error) return res.status(400).json({ message: error.details[0].message }); - - req.data = value; - - return next(); -} - -module.exports = validateIntervale; diff --git a/src/update/lib/models/state.js b/src/update/lib/models/state.js deleted file mode 100644 index 233d0d63..00000000 --- a/src/update/lib/models/state.js +++ /dev/null @@ -1,169 +0,0 @@ -const { - createReport, -} = require('../report'); - -const { - sendMailUpdateReport, -} = require('../services/mail'); - -const { - setInUpdate, -} = require('../status'); - -const logger = require('../logger'); - -let state = {}; - -function getState() { - return state; -} - -function setState(key, value) { - state[key] = value; -} - -/** - * Create a new file on folder "data/update/state" containing the update state - * - * @return {Promise} name of the file where the state is saved. - */ -async function createState() { - state = { - done: false, - createdAt: new Date(), - endAt: null, - steps: [], - error: false, - }; -} - -/** - * Add step "getChangefiles" in steps attributes of state. - */ -function addStepGetChangefiles() { - logger.info('[job: state] add step of check unpaywall update file registry'); - const step = { - task: 'getChangefiles', - took: 0, - status: 'inProgress', - }; - state.steps.push(step); -} - -/** - * Add step "download" in steps attributes of state. - * - * @param {string} downloadFile - Unpaywall data update filename. - */ -function addStepDownload(downloadFile) { - logger.info('[job: state] add step of download update file from unpaywall'); - const step = { - task: 'download', - file: downloadFile, - percent: 0, - took: 0, - status: 'inProgress', - }; - state.steps.push(step); -} - -/** - * Add step "download" in steps attributes of state. - * - * @param {string} downloadFile - Unpaywall data update file name. - */ -function addStepInsert(downloadFile) { - logger.info('[job: state] add step of insert the content of update file from unpaywall'); - const step = { - task: 'insert', - index: 'unpaywall', - file: downloadFile, - linesRead: 0, - insertedDocs: 0, - updatedDocs: 0, - failedDocs: 0, - percent: 0, - took: 0, - status: 'inProgress', - }; - state.steps.push(step); -} - -/** - * Get the latest step in state. - */ -function getLatestStep() { - return state.steps[state.steps.length - 1]; -} - -/** - * Update latest step in state. - * - * @param {Object} step - Latest step. - */ -function updateLatestStep(step) { - state.steps[state.steps.length - 1] = step; -} - -/** - * Enrich the state by adding the end of treatment attributes. - */ -function end() { - state.done = true; - state.endAt = new Date(); - state.took = (new Date(state.endAt) - new Date(state.createdAt)) / 1000; - - const insertSteps = state.steps.filter((e) => e.task === 'insert'); - let totalInsertedDocs = 0; - let totalUpdatedDocs = 0; - insertSteps.forEach((e) => { - totalInsertedDocs += e?.insertedDocs || 0; - }); - state.totalInsertedDocs = totalInsertedDocs; - insertSteps.forEach((e) => { - totalUpdatedDocs += e?.updatedDocs || 0; - }); - state.totalUpdatedDocs = totalUpdatedDocs; -} - -/** - * Update the state when there is an error. - * - * @param {Promise>} stackTrace - Log of error. - */ -async function fail(stackTrace) { - logger.error('[update process]: fail'); - end(); - state.error = true; - state.stackTrace = stackTrace; - await createReport(state); - sendMailUpdateReport(state).catch((err) => { - logger.errorRequest(err); - }); - setInUpdate(false); -} - -/** - * Update the state when the process is finished successfully. - * - * @returns {Promise} - */ -async function endState() { - logger.info('[update process]: end process'); - end(); - await createReport(state); - setInUpdate(false); -} - -module.exports = { - getState, - setState, - createState, - addStepGetChangefiles, - addStepDownload, - addStepInsert, - getLatestStep, - updateLatestStep, - fail, - endState, -}; diff --git a/src/update/lib/report.js b/src/update/lib/report.js deleted file mode 100644 index 5acd98f9..00000000 --- a/src/update/lib/report.js +++ /dev/null @@ -1,52 +0,0 @@ -const path = require('path'); -const fs = require('fs-extra'); -const { format } = require('date-fns'); -const logger = require('./logger'); - -const reportsDir = path.resolve(__dirname, '..', 'data', 'reports'); - -/** - * Create report on the folder "data/update/report" on behalf of the date of treatment. - * - * @param {string} state - State filename. - * - * @returns {Promise} - */ -async function createReport(state) { - const pathfile = path.resolve(reportsDir, `${format(new Date(), 'yyyy-MM-dd HH:mm:ss')}.json`); - try { - await fs.writeFile(pathfile, JSON.stringify(state, null, 2)); - } catch (err) { - logger.error(`[report] Cannot write [${JSON.stringify(state, null, 2)}] in ${pathfile}`, err); - throw err; - } -} - -/** - * Get report from the folder "data/update/report". - * - * @param {string} filename - Report filename. - * - * @returns {Promise} Report in json format. - */ -async function getReport(filename) { - let report; - try { - report = await fs.readFile(path.resolve(reportsDir, filename)); - } catch (err) { - logger.error(`[report] Cannot read [${path.resolve(reportsDir, filename)}]`, err); - return undefined; - } - try { - report = JSON.parse(report); - } catch (err) { - logger.error(`[report] Cannot parse [${report}] at json format`, err); - return undefined; - } - return report; -} - -module.exports = { - createReport, - getReport, -}; diff --git a/src/update/lib/routers/cron.js b/src/update/lib/routers/cron.js deleted file mode 100644 index 98af616c..00000000 --- a/src/update/lib/routers/cron.js +++ /dev/null @@ -1,38 +0,0 @@ -const router = require('express').Router(); - -const checkAuth = require('../middlewares/auth'); -const validateCronConfig = require('../middlewares/cron'); - -const { - startUpdateCron, - stopUpdateCron, - patchUpdateCron, - getConfigOfUpdateCron, -} = require('../controllers/cron'); - -/** - * Route that start the update cron. - * Auth required. - */ -router.post('/cron/start', checkAuth, startUpdateCron); - -/** - * Route that stop the update cron. - * Auth required. - */ -router.post('/cron/stop', checkAuth, stopUpdateCron); - -/** - * Route that update the update cron. - * Auth required. - * - * This route need a body that contains a config of cron. - */ -router.patch('/cron', checkAuth, validateCronConfig, patchUpdateCron); - -/** - * Route that get the config of update cron. - */ -router.get('/cron', getConfigOfUpdateCron); - -module.exports = router; diff --git a/src/update/lib/routers/elastic.js b/src/update/lib/routers/elastic.js deleted file mode 100644 index c4219038..00000000 --- a/src/update/lib/routers/elastic.js +++ /dev/null @@ -1,13 +0,0 @@ -const router = require('express').Router(); - -const checkAuth = require('../middlewares/auth'); -const createAlias = require('../controllers/elastic'); - -/** - * Route that init unpaywall elastic alias with local mapping. - * - * Auth required. - */ -router.post('/elastic/alias', checkAuth, createAlias); - -module.exports = router; diff --git a/src/update/lib/routers/job.js b/src/update/lib/routers/job.js deleted file mode 100644 index 47f3312d..00000000 --- a/src/update/lib/routers/job.js +++ /dev/null @@ -1,47 +0,0 @@ -const router = require('express').Router(); - -const { - downloadAndInsertSnapshotJob, - insertChangefilesOnPeriodJob, - insertChangefileJob, -} = require('../controllers/job'); - -const { - validateSnapshotJob, - validateJobChangefilesConfig, - validateInsertFile, -} = require('../middlewares/job'); - -const checkStatus = require('../middlewares/status'); - -const checkAuth = require('../middlewares/auth'); - -/** - * Route that download the current snapshot of unpaywall and insert his content. - * Auth required. - * No update process should be in progress. - * - * This route need a body that contains a config of job. - */ -router.post('/job/snapshot', checkStatus, checkAuth, validateSnapshotJob, downloadAndInsertSnapshotJob); - -/** - * Route that download and insert on elastic the changefiles from unpaywall between a period. - * Auth required. - * No update process should be in progress. - * - * This route need a body that contains a config of job. - */ -router.post('/job/period', checkStatus, checkAuth, validateJobChangefilesConfig, insertChangefilesOnPeriodJob); - -/** - * Route that insert on elastic the content of file installed on ezunpaywall. - * Auth required. - * No update process should be in progress. - * - * This route need a body that contains a config of job - * and a param which corresponds to the filename. - */ -router.post('/job/changefile/:filename', checkStatus, checkAuth, validateInsertFile, insertChangefileJob); - -module.exports = router; diff --git a/src/update/lib/routers/openapi.js b/src/update/lib/routers/openapi.js deleted file mode 100644 index f68e1ca0..00000000 --- a/src/update/lib/routers/openapi.js +++ /dev/null @@ -1,10 +0,0 @@ -const router = require('express').Router(); - -const openapi = require('../../openapi.json'); - -/** - * Route that give the openapi.json file. - */ -router.get('/openapi.json', (req, res) => res.status(200).json(openapi)); - -module.exports = router; diff --git a/src/update/lib/routers/report.js b/src/update/lib/routers/report.js deleted file mode 100644 index f24c13a1..00000000 --- a/src/update/lib/routers/report.js +++ /dev/null @@ -1,25 +0,0 @@ -const router = require('express').Router(); - -const { - getReports, - getReportByFilename, -} = require('../controllers/report'); - -const validateLatest = require('../middlewares/latest'); -const validateFilename = require('../middlewares/filename'); - -/** - * Route that give the list of reports or the content of most recent report in JSON format. - * - * This route can take in query latest. - */ -router.get('/reports', validateLatest, getReports); - -/** - * Route that give the content of report in JSON format. - * - * This route takes a param which corresponds to the filename of report. - */ -router.get('/reports/:filename', validateFilename, getReportByFilename); - -module.exports = router; diff --git a/src/update/lib/services/elastic.js b/src/update/lib/services/elastic.js deleted file mode 100644 index 1d32092f..00000000 --- a/src/update/lib/services/elastic.js +++ /dev/null @@ -1,126 +0,0 @@ -const fs = require('fs-extra'); -const path = require('path'); - -const { Client } = require('@elastic/elasticsearch'); -const { URL } = require('url'); -const { elasticsearch } = require('config'); -const { nodeEnv } = require('config'); -const logger = require('../logger'); - -const isProd = (nodeEnv === 'production'); - -let ssl; - -if (isProd) { - let ca; - const caPath = path.resolve(__dirname, '..', '..', 'certs', 'ca.crt'); - try { - ca = fs.readFileSync(caPath, 'utf8'); - } catch (err) { - logger.error(`[elastic] Cannot read elastic certificate file in [${caPath}]`, err); - } - ssl = { - ca, - rejectUnauthorized: true, - }; -} - -const elasticClient = new Client({ - node: { - url: new URL(`${elasticsearch.host}:${elasticsearch.port}`), - auth: { - username: elasticsearch.user, - password: elasticsearch.password, - }, - ssl, - }, - requestTimeout: elasticsearch.timeout, -}); - -/** - * Ping elastic service. - * - * @returns {Promise} ping. - */ -async function pingElastic() { - let elasticStatus; - try { - elasticStatus = await elasticClient.ping(); - } catch (err) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port}`, err); - return err.message; - } - if (elasticStatus?.statusCode !== 200) { - logger.error(`[elastic] Cannot ping ${elasticsearch.host}:${elasticsearch.port} - ${elasticStatus?.statusCode}`); - return false; - } - return true; -} - -/** - * Check if index exit. - * - * @param {string} index - Name of index. - * - * @returns {Promise} If index exist. - */ -async function checkIfIndexExist(index) { - const { body } = await elasticClient.indices.exists({ index }); - return body; -} - -/** - * Create index if it doesn't exist. - * - * @param {string} index - Name of index. - * @param {Object} mapping mapping in JSON format. - * - * @returns {Promise} - */ -async function createIndex(index, mapping) { - const exist = await checkIfIndexExist(index); - if (!exist) { - await elasticClient.indices.create({ - index, - body: mapping, - }); - } -} - -/** - * Create alias on elastic. - * - * @param {string} indexName - Name of index. - * @param {Object} mapping - Mapping of index. - * @param {string} aliasName - Name of alias. - * - * @returns {Promise} - */ -async function initAlias(indexName, mapping, aliasName) { - try { - await createIndex(indexName, mapping); - } catch (err) { - logger.error(`[elastic] Cannot create index [${indexName}]`, err); - return; - } - - try { - const { body: aliasExists } = await elasticClient.indices.existsAlias({ name: aliasName }); - - if (aliasExists) { - logger.info(`[elastic] Alias [${aliasName}] already exists`); - } else { - logger.info(`[elastic] Creating alias [${aliasName}] pointing to index [${indexName}]`); - await elasticClient.indices.putAlias({ index: indexName, name: aliasName }); - } - } catch (err) { - logger.error(`[elastic] Cannot create alias [${aliasName}] pointing to index [${indexName}]`, err); - } -} - -module.exports = { - elasticClient, - pingElastic, - createIndex, - initAlias, -}; diff --git a/src/update/openapi.json b/src/update/openapi.json deleted file mode 100644 index 360b6741..00000000 --- a/src/update/openapi.json +++ /dev/null @@ -1,1330 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "The update service allows to update the mirror data. This service queries unpaywall to get the snapshots and inserts their content in an elasticsearch index ", - "version": "1.0.0", - "title": "Update service", - "contact": { - "email": "ezteam@couperin.org", - "name": "ezTeam" - }, - "license": { - "name": "CeCILL 2.1", - "url": "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" - } - }, - "paths": { - "/update": { - "get": { - "summary": "Name of service", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "type": "string", - "x-examples": { - "example-1": "update service" - } - }, - "examples": { - "service": { - "value": "update service" - } - } - }, - "Success": { - "examples": { - "response": { - "value": { - "message": "update service" - } - } - } - } - } - } - }, - "operationId": "get-update", - "description": "Get name of update service", - "tags": [ - "ping" - ] - } - }, - "/update/ping": { - "get": { - "summary": "Ping update service", - "operationId": "get-update-ping", - "description": "Ping update service", - "tags": [ - "ping" - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/update/health": { - "get": { - "summary": "Health", - "operationId": "get-update-health", - "description": "Health on all service connected to update service", - "tags": [ - "ping" - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "redis": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elastic": { - "type": "object", - "properties": { - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - } - }, - "elapsedTime": { - "type": "integer" - }, - "status": { - "type": "boolean" - } - }, - "x-examples": { - "Example 1": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 1, - "status": true - } - } - }, - "examples": { - "Success": { - "value": { - "redis": { - "elapsedTime": 1, - "status": true - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 1, - "status": true - } - }, - "Error redis": { - "value": { - "redis": { - "elapsedTime": 3001, - "status": false, - "error": "time out" - }, - "elastic": { - "elapsedTime": 1, - "status": true - }, - "elapsedTime": 3001, - "status": false - } - } - } - } - } - } - } - }, - "parameters": [] - }, - "/update/health/redis": { - "get": { - "summary": "Health on redis service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-update-health-redis", - "description": "Health on redis", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/update/health/elastic": { - "get": { - "summary": "Health on elastic service", - "responses": { - "200": { - "$ref": "#/components/responses/Health" - } - }, - "operationId": "get-update-health-elastic", - "description": "Health on elastic", - "tags": [ - "ping" - ] - }, - "parameters": [] - }, - "/update/job/snapshot": { - "post": { - "summary": "Start process download and insert snapshot from unpaywall", - "operationId": "post-update-job-snapshot", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "userName" - ], - "properties": { - "interval": { - "type": "string" - } - } - } - } - }, - "description": "index where the unpaywall data will be inserted" - }, - "responses": { - "202": { - "description": "Process start" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "409": { - "description": "Update in progress", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "changeme" - } - } - } - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "description": "Download and insert the latest snapshot from unpaywall.org", - "tags": [ - "job" - ] - } - }, - "/update/job/period": { - "post": { - "summary": "Start process download and insert changefiles from unpaywall", - "operationId": "post-update-job-period", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "userName" - ], - "properties": { - "index": { - "type": "string" - }, - "interval": { - "type": "string" - }, - "startDate": { - "type": "string" - }, - "endDate": { - "type": "string" - } - } - } - } - }, - "description": "config for process" - }, - "responses": { - "202": { - "description": "Process start" - }, - "400": { - "description": "startDate cannot be in the futur or endDate cannot be lower than startDate", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "changeme" - } - }, - "Test1": { - "examples": { - "response": { - "value": "changeme" - } - } - }, - "Test2": { - "examples": { - "response": { - "value": "changeme" - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "409": { - "description": "Update in progress", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "changeme" - } - } - } - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "description": "Download and insert changefiles from unpaywall.org", - "tags": [ - "job" - ] - } - }, - "/update/job/changefile/{filename}": { - "post": { - "summary": "Start process insert changesfiles downloaded on ezunpaywall", - "operationId": "post-update-job-changefile-$-filename", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "index": { - "type": "string" - }, - "offset": { - "type": "integer" - }, - "limit": { - "type": "integer" - } - } - } - } - }, - "description": "config for process" - }, - "responses": { - "202": { - "description": "Process start" - }, - "400": { - "description": "startDate cannot be in the futur or endDate cannot be lower than startDate", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "changeme" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "404": { - "description": "File not found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "File not found" - } - } - } - }, - "File not found": { - "examples": { - "response": { - "value": { - "message": "File not found" - } - } - } - } - } - }, - "409": { - "description": "Update in progress", - "content": { - "application/json": { - "schema": { - "type": "string", - "default": "changeme" - } - } - } - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "description": "Insert changefiles already downloaded on ezunpaywall", - "tags": [ - "job" - ] - } - }, - "/update/reports": { - "get": { - "summary": "Get reports", - "operationId": "get-update-reports", - "description": "Get list of reports or latest report", - "parameters": [ - { - "in": "query", - "name": "latest", - "description": "latest", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "report", - "content": { - "List of reports": { - "examples": { - "response": { - "value": [ - "2022-10-10 13:10:51.json", - "2022-10-10 13:10:50.json", - "2022-10-10 13:10:49.json", - "2022-10-10 13:10:48.json", - "2022-10-10 13:10:47.json", - "2022-10-10 13:10:46.json", - "2022-10-10 13:10:45.json", - "2022-10-10 13:10:44.json" - ] - } - } - }, - "Latest report": { - "examples": { - "response": { - "value": { - "done": true, - "createdAt": "2022-10-10T13:10:46.828Z", - "endAt": "2022-10-10T13:10:47.084Z", - "steps": [ - { - "task": "getChangefiles", - "took": 0.002, - "status": "success" - }, - { - "task": "download", - "file": "fake2.jsonl.gz", - "percent": 100, - "took": 0, - "status": "success" - }, - { - "task": "insert", - "index": "unpaywall-test", - "file": "fake2.jsonl.gz", - "linesRead": 100, - "insertedDocs": 100, - "updatedDocs": 0, - "failedDocs": 0, - "percent": 100, - "took": 0.202, - "status": "success" - } - ], - "error": false, - "took": 0.256 - } - } - } - } - } - } - }, - "tags": [ - "job" - ] - } - }, - "/update/reports/${filename}": { - "get": { - "summary": "Get report", - "operationId": "get-update-reports-$-filename", - "description": "Get report with his filename", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "report", - "content": { - "application/json": { - "schema": { - "type": "object", - "x-examples": { - "example-1": { - "done": true, - "createdAt": "2022-10-10T13:10:46.828Z", - "endAt": "2022-10-10T13:10:47.084Z", - "steps": [ - { - "task": "getChangefiles", - "took": 0.002, - "status": "success" - }, - { - "task": "download", - "file": "fake2.jsonl.gz", - "percent": 100, - "took": 0, - "status": "success" - }, - { - "task": "insert", - "index": "unpaywall-test", - "file": "fake2.jsonl.gz", - "linesRead": 100, - "insertedDocs": 100, - "updatedDocs": 0, - "failedDocs": 0, - "percent": 100, - "took": 0.202, - "status": "success" - } - ], - "error": false, - "took": 0.256 - } - } - } - }, - "Report": { - "examples": { - "response": { - "value": { - "done": true, - "createdAt": "2022-10-10T13:10:46.828Z", - "endAt": "2022-10-10T13:10:47.084Z", - "steps": [ - { - "task": "getChangefiles", - "took": 0.002, - "status": "success" - }, - { - "task": "download", - "file": "fake2.jsonl.gz", - "percent": 100, - "took": 0, - "status": "success" - }, - { - "task": "insert", - "index": "unpaywall-test", - "file": "fake2.jsonl.gz", - "linesRead": 100, - "insertedDocs": 100, - "updatedDocs": 0, - "failedDocs": 0, - "percent": 100, - "took": 0.202, - "status": "success" - } - ], - "error": false, - "took": 0.256 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "File not found" - } - } - } - }, - "File not found": { - "examples": { - "response": { - "value": { - "message": "File not found" - } - } - } - } - } - } - }, - "tags": [ - "job" - ] - } - }, - "/update/snapshots": { - "get": { - "summary": "Get snapshots", - "operationId": "get-update-snapshots", - "description": "Get list of snapshot or latest snapshot", - "parameters": [ - { - "in": "query", - "name": "latest", - "description": "latest", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "snapshot", - "content": { - "Lists of snapshots": { - "examples": { - "response": { - "value": [ - "snapshot-2022-10-10.jsonl.gz" - ] - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/update/snapshots/${filename}": { - "get": { - "summary": "Get snapshot", - "operationId": "get-update-snapshots-$-filename", - "description": "Get snapshot with his filename", - "parameters": [ - { - "in": "path", - "name": "filename", - "description": "filename", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "snapshot" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - }, - "404": { - "description": "File not found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "File not found" - } - } - }, - "examples": { - "example-1": { - "value": { - "message": "string" - } - } - } - }, - "File not found": { - "examples": { - "response": { - "value": { - "message": "File not found" - } - } - } - } - } - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/update/states": { - "get": { - "summary": "Get state", - "operationId": "get-update-states", - "description": "Get latest state", - "responses": { - "200": { - "description": "state", - "content": { - "Latest state": { - "examples": { - "response": { - "value": { - "done": true, - "createdAt": "2022-10-10T13:10:51.417Z", - "endAt": "2022-10-10T13:10:51.584Z", - "steps": [ - { - "task": "getChangefiles", - "took": 0.002, - "status": "success" - }, - { - "task": "insert", - "index": "unpaywall-test", - "file": "fake1.jsonl.gz", - "linesRead": 50, - "insertedDocs": 50, - "updatedDocs": 0, - "failedDocs": 0, - "percent": 100, - "took": 0.165, - "status": "success" - } - ], - "error": false, - "took": 0.167 - } - } - } - } - } - } - }, - "tags": [ - "job" - ] - } - }, - "/update/status": { - "get": { - "summary": "Get status", - "operationId": "get-update-status", - "description": "Get status", - "responses": { - "200": { - "description": "status", - "content": { - "No process in progress": { - "examples": { - "response": { - "value": false - } - } - }, - "Update in progress": { - "examples": { - "response": { - "value": true - } - } - } - } - } - }, - "tags": [ - "job" - ] - } - }, - "/update/unpaywall/changefiles": { - "get": { - "summary": "Get changefiles from unpaywall", - "operationId": "get-update-unpaywall-changefiles", - "description": "Get changefiles from unpaywall", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "index": { - "type": "string" - } - } - }, - "examples": { - "example-1": { - "value": { - "index": "string" - } - } - } - } - }, - "description": "interval of changefiles (\"week\" or \"day\")" - }, - "responses": { - "200": { - "description": "status", - "content": { - "List of daily changefiles of unpaywall": { - "examples": { - "response": { - "value": [ - { - "date": "2022-10-10T00:00:00.000Z", - "filename": "fake1.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2021-10-09T13:10:50.000Z", - "lines": 50, - "size": 19896, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake1.jsonl.gz" - }, - { - "date": "2022-10-09T00:00:00.000Z", - "filename": "fake2.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2022-10-09T13:10:50.000Z", - "lines": 100, - "size": 44137, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake2.jsonl.gz" - }, - { - "date": "2022-10-08T00:00:00.000Z", - "filename": "fake3.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2022-10-08T13:10:50.000Z", - "lines": 2000, - "size": 877494, - "url": "http://fakeUnpaywall:3000/daily-feed/changefiles/fake3.jsonl.gz" - } - ] - } - } - }, - "List of weekly changefiles of unpaywall": { - "examples": { - "response": { - "value": [ - { - "date": "2022-10-10T00:00:00.000Z", - "filename": "fake1.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2021-10-09T13:10:50.000Z", - "lines": 50, - "size": 19896, - "url": "http://fakeUnpaywall:3000/feed/changefiles/fake1.jsonl.gz" - }, - { - "date": "2022-10-09T00:00:00.000Z", - "filename": "fake2.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2022-10-09T13:10:50.000Z", - "lines": 100, - "size": 44137, - "url": "http://fakeUnpaywall:3000/feed/changefiles/fake2.jsonl.gz" - }, - { - "date": "2022-10-08T00:00:00.000Z", - "filename": "fake3.jsonl.gz", - "filetype": "jsonl", - "last_modified": "2022-10-08T13:10:50.000Z", - "lines": 2000, - "size": 877494, - "url": "http://fakeUnpaywall:3000/feed/changefiles/fake3.jsonl.gz" - } - ] - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "job" - ] - } - }, - "/update/cron/start": { - "post": { - "summary": "Start update cron", - "operationId": "post-update-cron-start", - "responses": { - "202": { - "description": "Accepted" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "description": "Start update cron", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "cron" - ] - } - }, - "/update/cron/stop": { - "post": { - "summary": "Stop update cron", - "operationId": "post-update-cron-stop", - "responses": { - "202": { - "description": "Accepted" - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "description": "Stop update cron", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "cron" - ] - }, - "parameters": [] - }, - "/update/cron": { - "parameters": [], - "patch": { - "summary": "update update cron", - "operationId": "patch-update-cron", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "config": { - "type": "object", - "properties": { - "time": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "index": { - "type": "string" - }, - "interval": { - "type": "string" - } - } - } - }, - "x-examples": { - "example-1": { - "config": { - "time": "* * * * * *", - "status": false, - "index": "unpaywall", - "interval": "day" - } - } - } - }, - "examples": { - "updated": { - "value": { - "config": { - "time": "* 30 12-15 * * *", - "status": true, - "index": "unpaywall", - "interval": "day" - } - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Not-authorized" - } - }, - "description": "update update cron", - "security": [ - { - "x-api-key": [] - } - ], - "tags": [ - "cron" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "time": { - "type": "string" - }, - "index": { - "type": "string" - }, - "interval": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "time": "", - "index": "", - "interval": "" - } - } - }, - "examples": { - "daily": { - "value": { - "time": "0 0 0 * * *", - "index": "unpaywall", - "interval": "day" - } - }, - "weekly": { - "value": { - "time": "0 0 0 * * 0", - "index": "unpaywall", - "interval": "weekly" - } - } - } - } - } - } - }, - "get": { - "summary": "Get config of update cron", - "operationId": "get-update-cron", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "config": { - "type": "object", - "properties": { - "time": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "index": { - "type": "string" - }, - "interval": { - "type": "string" - } - } - } - }, - "x-examples": { - "example-1": { - "config": { - "time": "* * * * * *", - "status": false, - "index": "unpaywall", - "interval": "day" - } - } - } - }, - "examples": { - "day": { - "value": { - "config": { - "time": "0 0 0 * * *", - "status": true, - "index": "unpaywall", - "interval": "day" - } - } - }, - "week": { - "value": { - "config": { - "time": "0 0 0 * * *", - "status": true, - "index": "unpaywall", - "interval": "day" - } - } - }, - "off": { - "value": { - "config": { - "time": "0 0 0 * * *", - "status": false, - "index": "unpaywall", - "interval": "day" - } - } - } - } - } - } - } - }, - "description": "Get config of update cron", - "parameters": [], - "tags": [ - "cron" - ] - } - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "tags": [ - { - "name": "cron" - }, - { - "name": "job" - }, - { - "name": "ping" - } - ], - "components": { - "responses": { - "Not-authorized": { - "description": "Not authorized", - "headers": {}, - "content": { - "*/*": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "x-examples": { - "example-1": { - "message": "Not authorized" - } - } - }, - "examples": { - "example-1": { - "value": { - "message": "string" - } - } - } - }, - "Not authorized": { - "examples": { - "response": { - "value": { - "message": "Not authorized" - } - } - } - } - } - }, - "Health": { - "description": "Example response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "boolean" - }, - "elapsedTime": { - "type": "integer" - } - }, - "x-examples": { - "Example 1": { - "name": "redis", - "status": true, - "elapsedTime": 1 - } - } - }, - "examples": { - "Success": { - "value": { - "name": "name of service", - "status": true, - "elapsedTime": 1 - } - }, - "Error redis": { - "value": { - "name": "redis", - "elapsedTime": 3002, - "error": "time out", - "status": false - } - } - } - } - } - } - }, - "securitySchemes": { - "x-api-key": { - "type": "apiKey", - "in": "header", - "name": "API Key" - } - }, - "schemas": {} - } -} \ No newline at end of file diff --git a/src/update/test/insertionError.js b/src/update/test/insertionError.js deleted file mode 100644 index 275d00cc..00000000 --- a/src/update/test/insertionError.js +++ /dev/null @@ -1,122 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const { - addSnapshot, - updateChangeFile, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -chai.use(chaiHttp); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -describe('Test: insert the content of a file already installed on ezunpaywall', () => { - before(async function () { - this.timeout(30000); - await ping(); - await updateChangeFile('week'); - }); - - describe('Do insertion of a corrupted file already installed', () => { - before(async () => { - await reset(); - await addSnapshot('fake1-error.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1-error.jsonl.gz') - .send({ - index: 'unpaywall-test', - }) - .set('Access-Control-Allow-Origin', '*') - .set('Content-Type', 'application/json') - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 0 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(0); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(true); - expect(state).have.property('took').to.not.equal(undefined); - - expect(state.steps[0]).have.property('task').equal('insert'); - expect(state.steps[0]).have.property('index').equal('unpaywall-test'); - expect(state.steps[0]).have.property('file').equal('fake1-error.jsonl.gz'); - expect(state.steps[0]).have.property('linesRead').equal(50); - expect(state.steps[0]).have.property('insertedDocs').equal(49); - expect(state.steps[0]).have.property('updatedDocs').equal(0); - expect(state.steps[0]).have.property('failedDocs').equal(1); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('error'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(true); - expect(report).have.property('took').to.not.equal(undefined); - - expect(report.steps[0]).have.property('task').equal('insert'); - expect(report.steps[0]).have.property('index').equal('unpaywall-test'); - expect(report.steps[0]).have.property('file').equal('fake1-error.jsonl.gz'); - expect(report.steps[0]).have.property('linesRead').equal(50); - expect(report.steps[0]).have.property('insertedDocs').equal(49); - expect(report.steps[0]).have.property('updatedDocs').equal(0); - expect(report.steps[0]).have.property('failedDocs').equal(1); - expect(report.steps[0]).have.property('percent').equal(0); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('error'); - }); - - after(async () => { - await reset(); - }); - }); - - after(async () => { - await reset(); - }); -}); diff --git a/src/update/test/insertionFile.js b/src/update/test/insertionFile.js deleted file mode 100644 index deb6bf0c..00000000 --- a/src/update/test/insertionFile.js +++ /dev/null @@ -1,408 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const { - addSnapshot, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -chai.use(chaiHttp); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -describe('Test: insert the content of a file already installed on ezunpaywall', () => { - before(async function () { - this.timeout(30000); - await ping(); - }); - - describe('Do insertion of a file already installed', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 50 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - - expect(count).to.equal(50); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - - expect(state.steps[0]).have.property('task').equal('insert'); - expect(state.steps[0]).have.property('index').equal('unpaywall-test'); - expect(state.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[0]).have.property('linesRead').equal(50); - expect(state.steps[0]).have.property('insertedDocs').equal(50); - expect(state.steps[0]).have.property('updatedDocs').equal(0); - expect(state.steps[0]).have.property('failedDocs').equal(0); - expect(state.steps[0]).have.property('percent').equal(100); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - - expect(report.steps[0]).have.property('task').equal('insert'); - expect(report.steps[0]).have.property('index').equal('unpaywall-test'); - expect(report.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[0]).have.property('percent').equal(100); - expect(report.steps[0]).have.property('linesRead').equal(50); - expect(report.steps[0]).have.property('insertedDocs').equal(50); - expect(report.steps[0]).have.property('updatedDocs').equal(0); - expect(report.steps[0]).have.property('failedDocs').equal(0); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Do insertion of a file already installed with parameter limit=10', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - limit: 10, - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 10 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(10); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - - expect(state.steps[0]).have.property('task').equal('insert'); - expect(state.steps[0]).have.property('index').equal('unpaywall-test'); - expect(state.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[0]).have.property('percent').equal(100); - expect(state.steps[0]).have.property('linesRead').equal(10); - expect(state.steps[0]).have.property('insertedDocs').equal(10); - expect(state.steps[0]).have.property('updatedDocs').equal(0); - expect(state.steps[0]).have.property('failedDocs').equal(0); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - - expect(report.steps[0]).have.property('task').equal('insert'); - expect(report.steps[0]).have.property('index').equal('unpaywall-test'); - expect(report.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[0]).have.property('percent').equal(100); - expect(report.steps[0]).have.property('linesRead').equal(10); - expect(report.steps[0]).have.property('insertedDocs').equal(10); - expect(report.steps[0]).have.property('updatedDocs').equal(0); - expect(report.steps[0]).have.property('failedDocs').equal(0); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Do insertion of a file already installed with parameter offset=40', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - offset: 40, - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 10 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(10); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - - expect(state.steps[0]).have.property('task').equal('insert'); - expect(state.steps[0]).have.property('index').equal('unpaywall-test'); - expect(state.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[0]).have.property('percent').equal(100); - expect(state.steps[0]).have.property('linesRead').equal(50); - expect(state.steps[0]).have.property('insertedDocs').equal(10); - expect(state.steps[0]).have.property('updatedDocs').equal(0); - expect(state.steps[0]).have.property('failedDocs').equal(0); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - - expect(report.steps[0]).have.property('task').equal('insert'); - expect(report.steps[0]).have.property('index').equal('unpaywall-test'); - expect(report.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[0]).have.property('percent').equal(100); - expect(report.steps[0]).have.property('linesRead').equal(50); - expect(report.steps[0]).have.property('insertedDocs').equal(10); - expect(report.steps[0]).have.property('updatedDocs').equal(0); - expect(report.steps[0]).have.property('failedDocs').equal(0); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Do insertion of a file already installed with parameter offset=10 and limit=20', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - offset: 10, - limit: 20, - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 10 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(10); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - - expect(state.steps[0]).have.property('task').equal('insert'); - expect(state.steps[0]).have.property('index').equal('unpaywall-test'); - expect(state.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[0]).have.property('percent').equal(100); - expect(state.steps[0]).have.property('linesRead').equal(20); - expect(state.steps[0]).have.property('insertedDocs').equal(10); - expect(state.steps[0]).have.property('updatedDocs').equal(0); - expect(state.steps[0]).have.property('failedDocs').equal(0); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - - expect(report.steps[0]).have.property('task').equal('insert'); - expect(report.steps[0]).have.property('index').equal('unpaywall-test'); - expect(report.steps[0]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[0]).have.property('percent').equal(100); - expect(report.steps[0]).have.property('linesRead').equal(20); - expect(report.steps[0]).have.property('insertedDocs').equal(10); - expect(report.steps[0]).have.property('updatedDocs').equal(0); - expect(report.steps[0]).have.property('failedDocs').equal(0); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Don\'t do a insertion of a file already installed because the file is in the wrong format', () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe('Don\'t do a insertion of a file already installed because the File not found on ezunpaywall', () => { - it('Should return a status code 404', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(404); - }); - }); - - describe('Don\'t do a insertion of a file already installed because the parameter limit can\t be lower than offset', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/changefile/fake1.jsonl.gz') - .send({ - index: 'unpaywall-test', - offset: 100, - limit: 50, - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - - after(async () => { - await reset(); - }); - }); - - after(async () => { - await reset(); - }); -}); diff --git a/src/update/test/insertionPeriodDay.js b/src/update/test/insertionPeriodDay.js deleted file mode 100644 index 397809ff..00000000 --- a/src/update/test/insertionPeriodDay.js +++ /dev/null @@ -1,472 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - deleteFile, - updateChangeFile, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const { - countDocuments, - deleteIndex, -} = require('./utils/elastic'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -chai.use(chaiHttp); - -describe('Test: download and insert file from unpaywall between a period', () => { - const now = Date.now(); - const oneDay = (1 * 24 * 60 * 60 * 1000); - - // create date in a format (YYYY-mm-dd) to be use by ezunpaywall - // yesterday - const date1 = new Date(now - (1 * oneDay)).toISOString().slice(0, 10); - // 2 days before - const date2 = new Date(now - (2 * oneDay)).toISOString().slice(0, 10); - - // these dates are for test with dates on which no update file has been published from unpaywall - const date3 = new Date(now - (6 * oneDay)).toISOString().slice(0, 10); - const date4 = new Date(now - (7 * oneDay)).toISOString().slice(0, 10); - const tomorrow = new Date(now + (1 * oneDay)).toISOString().slice(0, 10); - - before(async function () { - this.timeout(30000); - await ping(); - await updateChangeFile('day'); - }); - - describe(`Day: Do a download and insert between ${date1} and now`, async () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date1, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 150 data', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(150); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(150); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('download'); - expect(state.steps[1]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - - expect(state.steps[2]).have.property('task').equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[2]).have.property('percent').equal(100); - expect(state.steps[2]).have.property('linesRead').equal(100); - expect(state.steps[2]).have.property('insertedDocs').equal(100); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').equal('success'); - - expect(state.steps[3]).have.property('task').equal('download'); - expect(state.steps[3]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[3]).have.property('percent').equal(100); - expect(state.steps[3]).have.property('took').to.not.equal(undefined); - expect(state.steps[3]).have.property('status').equal('success'); - - expect(state.steps[4]).have.property('task').equal('insert'); - expect(state.steps[4]).have.property('index').equal('unpaywall-test'); - expect(state.steps[4]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[4]).have.property('percent').equal(100); - expect(state.steps[4]).have.property('linesRead').equal(50); - expect(state.steps[4]).have.property('insertedDocs').equal(50); - expect(state.steps[4]).have.property('updatedDocs').equal(0); - expect(state.steps[4]).have.property('failedDocs').equal(0); - expect(state.steps[4]).have.property('took').to.not.equal(undefined); - expect(state.steps[4]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the download and insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(150); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('download'); - expect(report.steps[1]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - - expect(report.steps[2]).have.property('task').equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[2]).have.property('percent').equal(100); - expect(report.steps[2]).have.property('linesRead').equal(100); - expect(report.steps[2]).have.property('insertedDocs').equal(100); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').equal('success'); - - expect(report.steps[3]).have.property('task').equal('download'); - expect(report.steps[3]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[3]).have.property('percent').equal(100); - expect(report.steps[3]).have.property('took').to.not.equal(undefined); - expect(report.steps[3]).have.property('status').equal('success'); - - expect(report.steps[4]).have.property('task').equal('insert'); - expect(report.steps[4]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[4]).have.property('percent').equal(100); - expect(report.steps[4]).have.property('linesRead').equal(50); - expect(report.steps[4]).have.property('insertedDocs').equal(50); - expect(report.steps[4]).have.property('updatedDocs').equal(0); - expect(report.steps[4]).have.property('failedDocs').equal(0); - expect(report.steps[4]).have.property('took').to.not.equal(undefined); - expect(report.steps[4]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe(`Day: Do a download and insert between ${date2} and ${date1}`, () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date2, - endDate: date1, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 2100 data', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(2100); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(2100); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('download'); - expect(state.steps[1]).have.property('file').equal('fake3.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - - expect(state.steps[2]).have.property('task').equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').equal('fake3.jsonl.gz'); - expect(state.steps[2]).have.property('percent').equal(100); - expect(state.steps[2]).have.property('linesRead').equal(2000); - expect(state.steps[2]).have.property('insertedDocs').equal(2000); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').equal('success'); - - expect(state.steps[3]).have.property('task').equal('download'); - expect(state.steps[3]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[3]).have.property('percent').equal(100); - expect(state.steps[3]).have.property('took').to.not.equal(undefined); - expect(state.steps[3]).have.property('status').equal('success'); - - expect(state.steps[4]).have.property('task').equal('insert'); - expect(state.steps[4]).have.property('index').equal('unpaywall-test'); - expect(state.steps[4]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[4]).have.property('percent').equal(100); - expect(state.steps[4]).have.property('linesRead').equal(100); - expect(state.steps[4]).have.property('insertedDocs').equal(100); - expect(state.steps[4]).have.property('updatedDocs').equal(0); - expect(state.steps[4]).have.property('failedDocs').equal(0); - expect(state.steps[4]).have.property('took').to.not.equal(undefined); - expect(state.steps[4]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the download and insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(2100); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('download'); - expect(report.steps[1]).have.property('file').equal('fake3.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - - expect(report.steps[2]).have.property('task').equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').equal('fake3.jsonl.gz'); - expect(report.steps[2]).have.property('percent').equal(100); - expect(report.steps[2]).have.property('linesRead').equal(2000); - expect(report.steps[2]).have.property('insertedDocs').equal(2000); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').equal('success'); - - expect(report.steps[3]).have.property('task').equal('download'); - expect(report.steps[3]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[3]).have.property('percent').equal(100); - expect(report.steps[3]).have.property('took').to.not.equal(undefined); - expect(report.steps[3]).have.property('status').equal('success'); - - expect(report.steps[4]).have.property('task').equal('insert'); - expect(report.steps[4]).have.property('index').equal('unpaywall-test'); - expect(report.steps[4]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[4]).have.property('percent').equal(100); - expect(report.steps[4]).have.property('linesRead').equal(100); - expect(report.steps[4]).have.property('insertedDocs').equal(100); - expect(report.steps[4]).have.property('updatedDocs').equal(0); - expect(report.steps[4]).have.property('failedDocs').equal(0); - expect(report.steps[4]).have.property('took').to.not.equal(undefined); - expect(report.steps[4]).have.property('status').equal('success'); - }); - after(async () => { - await reset(); - }); - }); - - describe(`Day: Don't download and insert between ${date4} and ${date3} because there is no file between these dates in ezunpaywall`, () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date4, - endDate: date3, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert nothing', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(0); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(0); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe(`Day: Don't do a download and insert with endDate=${date1} only`, () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - endDate: date1, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe('Day: Don\'t do a download and insert with startDate in the wrong format', () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .query({ index: 'unpaywall-test', startDate: 'doen\'t exist' }) - .send({ - index: 'unpaywall-test', - startDate: 'doesn\'t exist', - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: '01-01-2000', - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: '2000-50-50', - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe(`Day: Don't download and insert between ${date2} and ${date3} because startDate=${date2} is superior than endDate=${date3}`, () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date2, - endDate: date3, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe(`Day: Don't download and insert with startDate=${tomorrow} because there can be no futuristic file`, () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: tomorrow, - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - after(async () => { - await deleteIndex('unpaywall-test'); - await deleteFile('fake1.jsonl.gz'); - await deleteFile('fake2.jsonl.gz'); - await deleteFile('fake3.jsonl.gz'); - }); -}); diff --git a/src/update/test/insertionPeriodWeek.js b/src/update/test/insertionPeriodWeek.js deleted file mode 100644 index 4d8c54ae..00000000 --- a/src/update/test/insertionPeriodWeek.js +++ /dev/null @@ -1,470 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - updateChangeFile, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -chai.use(chaiHttp); - -describe('Week: Test: download and insert file from unpaywall between a period', () => { - const now = Date.now(); - const oneDay = (1 * 24 * 60 * 60 * 1000); - - // create date in a format (YYYY-mm-dd) to be use by ezunpaywall - // yersterday - const date1 = new Date(now - (1 * oneDay)).toISOString().slice(0, 10); - // yersterday - one week - const date2 = new Date(now - (8 * oneDay)).toISOString().slice(0, 10); - // yersterday - two weeks - const date3 = new Date(now - (15 * oneDay)).toISOString().slice(0, 10); - // these dates are for test between a short period - const date4 = new Date(now - (4 * oneDay)).toISOString().slice(0, 10); - const date5 = new Date(now - (5 * oneDay)).toISOString().slice(0, 10); - const tomorrow = new Date(now + (1 * oneDay)).toISOString().slice(0, 10); - - before(async function () { - this.timeout(30000); - await ping(); - await updateChangeFile('week'); - }); - - describe(`Week: Do a download and insert between ${date2} and now`, async () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date2, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 150 data', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(150); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(150); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('download'); - expect(state.steps[1]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - - expect(state.steps[2]).have.property('task').equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[2]).have.property('percent').equal(100); - expect(state.steps[2]).have.property('linesRead').equal(100); - expect(state.steps[2]).have.property('insertedDocs').equal(100); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').equal('success'); - - expect(state.steps[3]).have.property('task').equal('download'); - expect(state.steps[3]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[3]).have.property('percent').equal(100); - expect(state.steps[3]).have.property('took').to.not.equal(undefined); - expect(state.steps[3]).have.property('status').equal('success'); - - expect(state.steps[4]).have.property('task').equal('insert'); - expect(state.steps[4]).have.property('index').equal('unpaywall-test'); - expect(state.steps[4]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[4]).have.property('percent').equal(100); - expect(state.steps[4]).have.property('linesRead').equal(50); - expect(state.steps[4]).have.property('insertedDocs').equal(50); - expect(state.steps[4]).have.property('updatedDocs').equal(0); - expect(state.steps[4]).have.property('failedDocs').equal(0); - expect(state.steps[4]).have.property('took').to.not.equal(undefined); - expect(state.steps[4]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the download and insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(150); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('download'); - expect(report.steps[1]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - - expect(report.steps[2]).have.property('task').equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[2]).have.property('percent').equal(100); - expect(report.steps[2]).have.property('linesRead').equal(100); - expect(report.steps[2]).have.property('insertedDocs').equal(100); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').equal('success'); - - expect(report.steps[3]).have.property('task').equal('download'); - expect(report.steps[3]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[3]).have.property('percent').equal(100); - expect(report.steps[3]).have.property('took').to.not.equal(undefined); - expect(report.steps[3]).have.property('status').equal('success'); - - expect(report.steps[4]).have.property('task').equal('insert'); - expect(report.steps[4]).have.property('index').equal('unpaywall-test'); - expect(report.steps[4]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[4]).have.property('percent').equal(100); - expect(report.steps[4]).have.property('linesRead').equal(50); - expect(report.steps[4]).have.property('took').to.not.equal(undefined); - expect(report.steps[4]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe(`Week: Do a download and insert between ${date3} and ${date2}`, () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date3, - endDate: date2, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 2100 data', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(2100); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(2100); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('download'); - expect(state.steps[1]).have.property('file').equal('fake3.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - - expect(state.steps[2]).have.property('task').equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').equal('fake3.jsonl.gz'); - expect(state.steps[2]).have.property('percent').equal(100); - expect(state.steps[2]).have.property('linesRead').equal(2000); - expect(state.steps[2]).have.property('insertedDocs').equal(2000); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').equal('success'); - - expect(state.steps[3]).have.property('task').equal('download'); - expect(state.steps[3]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[3]).have.property('percent').equal(100); - expect(state.steps[3]).have.property('took').to.not.equal(undefined); - expect(state.steps[3]).have.property('status').equal('success'); - - expect(state.steps[4]).have.property('task').equal('insert'); - expect(state.steps[4]).have.property('index').equal('unpaywall-test'); - expect(state.steps[4]).have.property('file').equal('fake2.jsonl.gz'); - expect(state.steps[4]).have.property('percent').equal(100); - expect(state.steps[4]).have.property('linesRead').equal(100); - expect(state.steps[4]).have.property('insertedDocs').equal(100); - expect(state.steps[4]).have.property('updatedDocs').equal(0); - expect(state.steps[4]).have.property('failedDocs').equal(0); - expect(state.steps[4]).have.property('took').to.not.equal(undefined); - expect(state.steps[4]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the download and insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(2100); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('download'); - expect(report.steps[1]).have.property('file').equal('fake3.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - - expect(report.steps[2]).have.property('task').equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').equal('fake3.jsonl.gz'); - expect(report.steps[2]).have.property('percent').equal(100); - expect(report.steps[2]).have.property('linesRead').equal(2000); - expect(report.steps[2]).have.property('insertedDocs').equal(2000); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').equal('success'); - - expect(report.steps[3]).have.property('task').equal('download'); - expect(report.steps[3]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[3]).have.property('percent').equal(100); - expect(report.steps[3]).have.property('took').to.not.equal(undefined); - expect(report.steps[3]).have.property('status').equal('success'); - - expect(report.steps[4]).have.property('task').equal('insert'); - expect(report.steps[4]).have.property('index').equal('unpaywall-test'); - expect(report.steps[4]).have.property('file').equal('fake2.jsonl.gz'); - expect(report.steps[4]).have.property('percent').equal(100); - expect(report.steps[4]).have.property('linesRead').equal(100); - expect(report.steps[4]).have.property('insertedDocs').equal(100); - expect(report.steps[4]).have.property('updatedDocs').equal(0); - expect(report.steps[4]).have.property('failedDocs').equal(0); - expect(report.steps[4]).have.property('took').to.not.equal(undefined); - expect(report.steps[4]).have.property('status').equal('success'); - }); - after(async () => { - await reset(); - }); - }); - - describe(`Week: Don't download and insert between ${date5} and ${date4} because there is no file between these dates in ezunpaywall`, () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date5, - endDate: date4, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert nothing', async () => { - // wait for the update to finish - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(0); - }); - - it('Should get state with all information from the download and insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(0); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe(`Week: Don't do a download and insert with endDate=${date1} only`, () => { - it('Should return status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: - 'unpaywall-test', - endDate: date1, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe('Week: Don\'t do a download and insert with startDate in the wrong format', () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .query({ - index: 'unpaywall-test', - startDate: 'doen\'t exist', - interval: 'week', - }) - .send({ - index: 'unpaywall-test', - startDate: 'doen\'t exist', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: '01-01-2000', - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: '2000-50-50', - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe(`Week: Don't download and insert between ${date2} and ${date3} because startDate=${date2} is superior than endDate=${date3}`, () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: date2, - endDate: date3, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - describe(`Week: Don't download and insert with startDate=${tomorrow} because there can be no futuristic file`, () => { - it('Should return a status code 400', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - startDate: tomorrow, - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(400); - }); - }); - - after(async () => { - await reset(); - }); -}); diff --git a/src/update/test/insertionSnapshot.js b/src/update/test/insertionSnapshot.js deleted file mode 100644 index 5118903a..00000000 --- a/src/update/test/insertionSnapshot.js +++ /dev/null @@ -1,127 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); -const { format } = require('date-fns'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -chai.use(chaiHttp); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -describe('Test: download and insert snapshot from unpaywall', () => { - before(async function () { - this.timeout(30000); - await ping(); - }); - - describe('Do a download and a insertion of snapshot', () => { - before(async () => { - await reset(); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/snapshot') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 2150 data', async () => { - // wait for the update to finish - let isUpdate = true; - do { - isUpdate = await checkIfInUpdate(); - await new Promise((resolve) => { setTimeout(resolve, 100); }); - } while (isUpdate); - - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(2150); - }); - - it('Should get state with all information from the insertion', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(2150); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('download'); - expect(state.steps[0]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - expect(state.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); - - expect(state.steps[1]).have.property('task').equal('insert'); - expect(state.steps[1]).have.property('index').equal('unpaywall-test'); - expect(state.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('linesRead').equal(2150); - expect(state.steps[1]).have.property('insertedDocs').equal(2150); - expect(state.steps[1]).have.property('updatedDocs').equal(0); - expect(state.steps[1]).have.property('failedDocs').equal(0); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the insertion', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(2150); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('download'); - expect(report.steps[0]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - expect(report.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); - - expect(report.steps[1]).have.property('task').equal('insert'); - expect(report.steps[1]).have.property('index').equal('unpaywall-test'); - expect(report.steps[1]).have.property('file').equal(`snapshot-${format(new Date(), 'yyyy-MM-dd')}.jsonl.gz`); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('linesRead').equal(2150); - expect(report.steps[1]).have.property('insertedDocs').equal(2150); - expect(report.steps[1]).have.property('updatedDocs').equal(0); - expect(report.steps[1]).have.property('failedDocs').equal(0); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); -}); diff --git a/src/update/test/updateDay.js b/src/update/test/updateDay.js deleted file mode 100644 index 14b000b0..00000000 --- a/src/update/test/updateDay.js +++ /dev/null @@ -1,417 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const { - addSnapshot, - updateChangeFile, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -chai.use(chaiHttp); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -describe('Test: daily update route test', () => { - before(async function () { - this.timeout(30000); - await ping(); - await updateChangeFile('day'); - }); - - describe('Day: Do daily update', () => { - before(async () => { - await reset(); - }); - - // test response - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the daily update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(50); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').be.equal('success'); - - expect(state.steps[1]).have.property('task').be.equal('download'); - expect(state.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').be.equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').be.equal('success'); - - expect(state.steps[2]).have.property('task').be.equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[2]).have.property('percent').be.equal(100); - expect(state.steps[2]).have.property('linesRead').be.equal(50); - expect(state.steps[2]).have.property('insertedDocs').equal(50); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').be.equal('success'); - - expect(state.done).be.equal(true); - }); - - it('Should get report with all information from the daily update', async () => { - const report = await getReport(); - - expect(report).have.property('done'); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(50); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').be.equal('success'); - - expect(report.steps[1]).have.property('task').be.equal('download'); - expect(report.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').be.equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').be.equal('success'); - - expect(report.steps[2]).have.property('task').be.equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[2]).have.property('percent').be.equal(100); - expect(report.steps[2]).have.property('linesRead').be.equal(50); - expect(report.steps[2]).have.property('insertedDocs').equal(50); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').be.equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Day: daily update 2 times', () => { - before(async () => { - await reset(); - }); - - // test response - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the weekly update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(50); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').be.equal('success'); - - expect(state.steps[1]).have.property('task').be.equal('download'); - expect(state.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').be.equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').be.equal('success'); - - expect(state.steps[2]).have.property('task').be.equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[2]).have.property('percent').be.equal(100); - expect(state.steps[2]).have.property('linesRead').be.equal(50); - expect(state.steps[2]).have.property('insertedDocs').equal(50); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').be.equal('success'); - - expect(state.done).be.equal(true); - }); - - it('Should get report with all information from the weekly update', async () => { - const report = await getReport(); - - expect(report).have.property('done'); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(50); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').be.equal('success'); - - expect(report.steps[1]).have.property('task').be.equal('download'); - expect(report.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').be.equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').be.equal('success'); - - expect(report.steps[2]).have.property('task').be.equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[2]).have.property('percent').be.equal(100); - expect(report.steps[2]).have.property('linesRead').be.equal(50); - expect(report.steps[2]).have.property('insertedDocs').equal(50); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').be.equal('success'); - }); - - // test response - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the weekly update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(0); - expect(state).have.property('totalUpdatedDocs').equal(50); - - expect(state.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').be.equal('success'); - - expect(state.steps[1]).have.property('task').be.equal('insert'); - expect(state.steps[1]).have.property('index').equal('unpaywall-test'); - expect(state.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').be.equal(100); - expect(state.steps[1]).have.property('linesRead').be.equal(50); - expect(state.steps[1]).have.property('insertedDocs').equal(0); - expect(state.steps[1]).have.property('updatedDocs').equal(50); - expect(state.steps[1]).have.property('failedDocs').equal(0); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').be.equal('success'); - - expect(state.done).be.equal(true); - }); - - it('Should get report with all information from the weekly update', async () => { - const report = await getReport(); - - expect(report).have.property('done'); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(0); - expect(report).have.property('totalUpdatedDocs').equal(50); - - expect(report.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').be.equal('success'); - - expect(report.steps[1]).have.property('task').be.equal('insert'); - expect(report.steps[1]).have.property('index').equal('unpaywall-test'); - expect(report.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').be.equal(100); - expect(report.steps[1]).have.property('linesRead').be.equal(50); - expect(report.steps[1]).have.property('insertedDocs').equal(0); - expect(report.steps[1]).have.property('updatedDocs').equal(50); - expect(report.steps[1]).have.property('failedDocs').equal(0); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').be.equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Day: Do a daily update but the file is already installed', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - interval: 'day', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the daily update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(50); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('insert'); - expect(state.steps[1]).have.property('index').equal('unpaywall-test'); - expect(state.steps[1]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('linesRead').equal(50); - expect(state.steps[1]).have.property('insertedDocs').equal(50); - expect(state.steps[1]).have.property('updatedDocs').equal(0); - expect(state.steps[1]).have.property('failedDocs').equal(0); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the daily update', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(50); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('insert'); - expect(report.steps[1]).have.property('index').equal('unpaywall-test'); - expect(report.steps[1]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('linesRead').equal(50); - expect(report.steps[1]).have.property('insertedDocs').equal(50); - expect(report.steps[1]).have.property('updatedDocs').equal(0); - expect(report.steps[1]).have.property('failedDocs').equal(0); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - after(async () => { - await reset(); - }); -}); diff --git a/src/update/test/updateWeek.js b/src/update/test/updateWeek.js deleted file mode 100644 index d99795a4..00000000 --- a/src/update/test/updateWeek.js +++ /dev/null @@ -1,234 +0,0 @@ -/* eslint-disable no-await-in-loop */ -const { expect } = require('chai'); -const chai = require('chai'); -const chaiHttp = require('chai-http'); - -const { - countDocuments, -} = require('./utils/elastic'); - -const { - addSnapshot, - updateChangeFile, -} = require('./utils/snapshot'); - -const { - getState, -} = require('./utils/state'); - -const { - getReport, -} = require('./utils/report'); - -const checkIfInUpdate = require('./utils/status'); - -const ping = require('./utils/ping'); - -const reset = require('./utils/reset'); - -chai.use(chaiHttp); - -const updateURL = process.env.UPDATE_HOST || 'http://localhost:59702'; - -describe('Week: Test: weekly update route test', () => { - before(async function () { - this.timeout(30000); - await ping(); - await updateChangeFile('week'); - }); - - describe('Do weekly update', () => { - before(async () => { - await reset(); - }); - - // test response - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('Should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the weekly update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(50); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').be.equal('success'); - - expect(state.steps[1]).have.property('task').be.equal('download'); - expect(state.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').be.equal(100); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').be.equal('success'); - - expect(state.steps[2]).have.property('task').be.equal('insert'); - expect(state.steps[2]).have.property('index').equal('unpaywall-test'); - expect(state.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(state.steps[2]).have.property('percent').be.equal(100); - expect(state.steps[2]).have.property('linesRead').be.equal(50); - expect(state.steps[2]).have.property('insertedDocs').equal(50); - expect(state.steps[2]).have.property('updatedDocs').equal(0); - expect(state.steps[2]).have.property('failedDocs').equal(0); - expect(state.steps[2]).have.property('took').to.not.equal(undefined); - expect(state.steps[2]).have.property('status').be.equal('success'); - - expect(state.done).be.equal(true); - }); - - it('Should get report with all information from the weekly update', async () => { - const report = await getReport(); - - expect(report).have.property('done'); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(50); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').be.equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').be.equal('success'); - - expect(report.steps[1]).have.property('task').be.equal('download'); - expect(report.steps[1]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').be.equal(100); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').be.equal('success'); - - expect(report.steps[2]).have.property('task').be.equal('insert'); - expect(report.steps[2]).have.property('index').equal('unpaywall-test'); - expect(report.steps[2]).have.property('file').be.equal('fake1.jsonl.gz'); - expect(report.steps[2]).have.property('percent').be.equal(100); - expect(report.steps[2]).have.property('linesRead').be.equal(50); - expect(report.steps[2]).have.property('insertedDocs').equal(50); - expect(report.steps[2]).have.property('updatedDocs').equal(0); - expect(report.steps[2]).have.property('failedDocs').equal(0); - expect(report.steps[2]).have.property('took').to.not.equal(undefined); - expect(report.steps[2]).have.property('status').be.equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - describe('Week: Do a weekly update but the file is already installed', () => { - before(async () => { - await reset(); - await addSnapshot('fake1.jsonl.gz'); - }); - - it('Should return a status code 202', async () => { - const res = await chai.request(updateURL) - .post('/job/period') - .send({ - index: 'unpaywall-test', - interval: 'week', - }) - .set('x-api-key', 'changeme'); - - expect(res).have.status(202); - }); - - it('should insert 50 data', async () => { - let isUpdate = true; - while (isUpdate) { - await new Promise((resolve) => { setTimeout(resolve, 100); }); - isUpdate = await checkIfInUpdate(); - } - const count = await countDocuments('unpaywall-test'); - expect(count).to.equal(50); - }); - - it('Should get state with all information from the weekly update', async () => { - const state = await getState(); - - expect(state).have.property('done').equal(true); - expect(state).have.property('steps').to.be.an('array'); - expect(state).have.property('createdAt').to.not.equal(undefined); - expect(state).have.property('endAt').to.not.equal(undefined); - expect(state).have.property('error').equal(false); - expect(state).have.property('took').to.not.equal(undefined); - expect(state).have.property('totalInsertedDocs').equal(50); - expect(state).have.property('totalUpdatedDocs').equal(0); - - expect(state.steps[0]).have.property('task').equal('getChangefiles'); - expect(state.steps[0]).have.property('took').to.not.equal(undefined); - expect(state.steps[0]).have.property('status').equal('success'); - - expect(state.steps[1]).have.property('task').equal('insert'); - expect(state.steps[1]).have.property('file').equal('fake1.jsonl.gz'); - expect(state.steps[1]).have.property('percent').equal(100); - expect(state.steps[1]).have.property('linesRead').equal(50); - expect(state.steps[1]).have.property('insertedDocs').equal(50); - expect(state.steps[1]).have.property('updatedDocs').equal(0); - expect(state.steps[1]).have.property('failedDocs').equal(0); - expect(state.steps[1]).have.property('took').to.not.equal(undefined); - expect(state.steps[1]).have.property('status').equal('success'); - }); - - it('Should get report with all information from the weekly update', async () => { - const report = await getReport(); - - expect(report).have.property('done').equal(true); - expect(report).have.property('steps').to.be.an('array'); - expect(report).have.property('createdAt').to.not.equal(undefined); - expect(report).have.property('endAt').to.not.equal(undefined); - expect(report).have.property('error').equal(false); - expect(report).have.property('took').to.not.equal(undefined); - expect(report).have.property('totalInsertedDocs').equal(50); - expect(report).have.property('totalUpdatedDocs').equal(0); - - expect(report.steps[0]).have.property('task').equal('getChangefiles'); - expect(report.steps[0]).have.property('took').to.not.equal(undefined); - expect(report.steps[0]).have.property('status').equal('success'); - - expect(report.steps[1]).have.property('task').equal('insert'); - expect(report.steps[1]).have.property('index').equal('unpaywall-test'); - expect(report.steps[1]).have.property('file').equal('fake1.jsonl.gz'); - expect(report.steps[1]).have.property('percent').equal(100); - expect(report.steps[1]).have.property('linesRead').equal(50); - expect(report.steps[1]).have.property('insertedDocs').equal(50); - expect(report.steps[1]).have.property('updatedDocs').equal(0); - expect(report.steps[1]).have.property('failedDocs').equal(0); - expect(report.steps[1]).have.property('took').to.not.equal(undefined); - expect(report.steps[1]).have.property('status').equal('success'); - }); - - after(async () => { - await reset(); - }); - }); - - after(async () => { - await reset(); - }); -}); diff --git a/src/update/test/utils/reset.js b/src/update/test/utils/reset.js deleted file mode 100644 index a9ac2da7..00000000 --- a/src/update/test/utils/reset.js +++ /dev/null @@ -1,26 +0,0 @@ -const { - deleteFile, -} = require('./snapshot'); - -const { - deleteIndex, -} = require('./elastic'); - -const resetCronConfig = require('./cron'); - -/** - * Reset ezunpaywall - * - * @returns {Promise} - */ -async function reset() { - await deleteFile('fake1.jsonl.gz'); - await deleteFile('fake2.jsonl.gz'); - await deleteFile('fake3.jsonl.gz'); - await deleteFile('fake1-error.jsonl.gz'); - await deleteFile('snapshot.jsonl.gz'); - await deleteIndex('unpaywall-test'); - await resetCronConfig(); -} - -module.exports = reset;